Monitor Arduino Sensor using Smartphone and ESB: IoT Tutorial

This post describes how to monitor Arduino sensor using the application of the IoT reference architecture. This architecture is shown in the previous post describing Internet of things project based on Arduino Android and ESB.
What if we want to read a remote sensor connected to Arduino board using our smartphone? As explained previously, we can connect directly our Android smartphone to arduino and read the sensor data or we can use a different approach where there is an Enterprise Service Bus (ESB) that stands in the middle between the arduino board and the smartphone.
Even if the system is a little bit more complex as stated in the previous post using ESB we have a lot of advantages.


It is time to show things work:

  •  an ESB proxy using WSO2 ESB that sends HTTP request to Arduino board and transforms response from Arduino board to our smartphone
  • Arduino Webserver that handles HTTP connection and read the temperature sensor
  • Android app that shows the temperature value in our smartphone
Connect Arduino to ESB and send data to Android: Monitor arduino sensor

How to implement an WSO2 ESB Proxy

The first thing we do is implementing a proxy that lives in our ESB that handles the incoming connection from the Android smartphone on one side and on the other side handles HTTP connection toward Arduino board.
The ESB proxy is very simple, the picture below shows how it works:esb proxy
As said, the proxy accept incoming connection and forward it to the Arduino web server that reads the environment temperature and returns a simple XML response. This response is transformed by the proxy and becomes a JSON response.This is the proxy code:
<proxy name="AndroidService"
    transports="https http"
    startOnLoad="true"
    trace="disable"
    statistics="enable">
   <description>
    <target>
     <inSequence>
      <log>
        <property name="Message Flow" value="Arduino API"/>
      </log>
      <send>
       <endpoint>
         <address uri="http://192.168.1.130"/>
       </endpoint>
     </send>
   </inSequence>
   <outSequence>
    <payloadFactory media-type="json">
     <format> {"temp":$1} </format>
      <args>
       <arg evaluator="xml" expression="//temp"/>
      </args>
    </payloadFactory>
    <property name="messageType" 
              value="application/json" 
              scope="axis2"/>
    <send/>
   </outSequence>
 </target>
</proxy >

At line 14, the proxy forwards the request to arduino web server, while in the line 19-24 the proxy transforms the response to JSON.The WSO2 ESB Proxy is now available in the service list:

esb service

The WSO2 Proxy details are shown below:

wso2 esb proxy service

The proxy is ready now to accept an incoming connection and we will monitor Arduino sensor.

Arduino Web server and Temperature sensor

It is time to implement the Arduino sketch that reads the temperature sensor and makes the data available using a web server. Of course, to make the project working it is necessary to have an ethernet shield.
The code is similar to the Arduino starter book. The sketch is very simple:

arduino webserver

The Arduino code is very simple:

void loop() {
  // Is there a client (Our Android smartphone)
  EthernetClient client = server.available(); 

  // Read temp
  int sensorVal = analogRead(3);
  float vSens = (sensorVal /1024.0) * 5.0;
  //Serial.println(vSens);
  float temp = (vSens - 0.5) * 100;
  //Serial.println(temp);

  if (client) {
    // Let's start reading
    boolean isLastLine = true;
    boolean isBody = false;
    header = "";
    reqData = "";
    int contentLen = 0;

    Serial.print("Client connected!");
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
       char c = client.read();
       if (c == 'n' && currentLineIsBlank) {
         // send a standard http response header
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/xml");
        // the connection will be closed after completion of the response
        client.println("Connection: close"); 
        client.println();
        // output the value of each analog input pin
       client.println("");
       client.print("");
       client.print(temp);
       client.print("");
       break;
     }
   }
  }
  // give the web browser time to receive the data
  delay(1);
  // close the connection:
  client.stop();
  Serial.println("client disconnected");
  client.stop();
}

The code is very simple, arduino board reads the temperature sensor using the analog PIN and when the arduino web server receives an HTTP request, it responds with the temperature sensor value in an XML format.

Implement an #IoT Architecture using #ESB #Android and #Arduino Click To Tweet

Monitor Arduino sensor using Android app

Finally, it is time to implement the android app that makes an HTTP request toward ESB and read the temperature sensor data using arduino board.
The android app is very simple, it is implemented using material design so it as a Toolbar and the temperature value.
The layout is shown below:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
 android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin"
 android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

 <android.support.v7.widget.Toolbar
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/toolbar"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
     android:background="@color/primaryColor"
     android:elevation="4dp"
     app:theme="@style/ThemeOverlay.AppCompat.Dark"
 />

 <TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerInParent="true"
   android:id="@+id/temp"
   android:text="--"
   style="@style/tempText"/>

</RelativeLayout>
The interesting part in the app, is the java code that makes the HTTP request:
public void doRequest() {
 initClient();
 Request req = new Request.Builder()
 .url(URL)
 .get()
 .build();

 client.newCall(req).enqueue(new Callback() {
   @Override
   public void onFailure(Request request, IOException e) {
   }

   @Override
   public void onResponse(Response response) throws IOException {
     try {
       String body = response.body().string();
       Log.d("AA", "resp [" + body + "]");

      JSONObject obj = new JSONObject(body);
      float data = (float) obj.getDouble("temp");
      ((DataListener) ctx).notifyData(data);
    }
    catch(Throwable t) {
      t.printStackTrace();
    }
  }
});

Running the android app the result is shown below:

android esb temp

At the end of this post, you know how to monitor Arduino sensor from your smartphone using an ESB proxy.