Monday, July 13, 2015

Monitor Arduino Sensor using Smartphone and ESB: IoT Tutorial

Use WSO2 ESB to monitor arduino sensor and send data to android smartphone

Topics covered

Arduino board

WSO2 ESB Proxy

Read sensor using arduino board

This post is the application of the IoT reference architecture shown in the previous post about Internet of things 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 send HTTP request to arduino board and transforms response from arduino board to our smartphone
  • Arduino Webserver that handle 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


How to implement an WSO2 ESB Proxy

The first thing we do is implementing a proxy that lives in our ESB that handle 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:

WSO2 ESB Custom 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 an 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:

WSO2 ESB Proxy list

The WSO2 Proxy details are shown below:

ESB Proxy detail

The proxy is ready now to accept incoming connection.

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 web server and temperature sensor

The arduino code is very simple:
void loop() {
EthernetClient client = server.available(); // Is there a client (Our Android smartphone)

// 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");
client.println("Connection: close"); // the connection will be closed after completion of the response
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.

Android app that controls arduino board

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:

how to code android app that makes HTTP request

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





Monitor Arduino Sensor using Smartphone and ESB: IoT Tutorial Rating: 4.5 Diposkan Oleh: Unknown

0 comments:

Post a Comment