Get access to the new Intel® IoT Developer Kit, a complete hardware and software solution that allows developers to create exciting new solutions with the Intel® Galileo and Intel® Edison boards. Visit the Intel® Developer Zone for IoT.
INTRODUCTION
This article will guide you through the process of hooking up your Edison with Windows azure and do some cool stuffs like controlling it. This example will just switch on and off an LED connected to any of the digital pins on the Edison board paired up with the Arduino breakout board. Let's see how it really works. An azure mobile service will act as a bridge between the Edison and the controller (An Windows phone app is used here). The Edison will read the value of an attribute from the table of the mobile service. An Windows phone app will update the value in the table and thus we will make changes in the Edison code depending on the value.
PRE-REQUISITES
It is assumed that the reader has basic knowledge on Windows phone app development and can hook up the app with an azure mobile service. If you are unknown about creating a backend for your app, then go through this link.
THINGS REQUIRED (HARDWARE)
- Intel Edison with the Arduino breakout board
- A LED
REQUIRED SOFTWARE
- Visual studio
- Arduino IDE
SERVICES REQUIRED
1: Azure mobile service
Firstly let's create an azure mobile service first. There are lots of article on creating an azure mobile service. Follow this link and create a mobile service that will contain a single table let's name it as controltable. The table will contain a column named "status" and another named "name". The value of the status column will either be 1 or 0. While the value for name will be set to Edison/Arduino.
Now we will develop an windows phone app that will add/modify the value of the attribute. The picture below shows us the screenshot of the azure sql table. Please note that the value of the attribute for "device" doesn’t matters. You can even exclude this attribute if you want to.
The next section will deal with the development of the Windows phone app.
WINDOWS PHONE APP
Our app will consist of only two buttons An on button and an off button. The screenshot of the app is shown below.
You can ignore the logout button, Actually, I was trying to add some features. Now what these buttons will do? This will update the value of the "status" attribute. When we press on button, the value of "status" will be 1 else it will be 0.
There is a bit of a problem though. What to update if nothing is created? For that we will deploy the app two times. The first time, we will create the table and assign some default values. The next time we will just update the previously updated values.
Now, our app is ready. Test the app and check whether the value of "status" is getting updated or not. Once it works, then there you go. The app is ready. Next part will concentrate on the Edison code.
EDISON CODE
Let’s get into Edison. Before kick starting your code for your Edison, follow the initial steps mentioned here for configuring your Edison. After connecting your Edison, note your comport number. Then open up your Arduino IDE and select Intel Edison from board. If you don’t find the Intel Edison option, then you need to download the necessary files from the boards manager option.
Once you open up the Arduino IDE, two functions will be mentioned from before. Void setup()
and void loop()
. The Edison has an in-built Wi-Fi. We will use the Wi-Fi to connect it to internet. So our first action is to include a library for Wi-Fi. Go to Sketch->include library->Wi-Fi. After that, let’s add up this code to connect it to Wi-Fi.
#include <SPI.h>
#include <WiFi.h>
WiFiClient client;
char ssid[] = "networkssid"; char pass[] = "password"; int keyIndex = 0; int status = WL_IDLE_STATUS;
void setup()
{
pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
Serial.begin(115200);
while (!Serial) {
; }
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
while(true);
}
String fv = WiFi.firmwareVersion();
if( fv != "1.1.0" )
Serial.println("Please upgrade the firmware");
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
}
}
The above code is responsible for connecting the Edison to internet by Wi-Fi. Also, we have set PIN 13 to output mode and the current status is off. We will use the serial monitor of the IDE to monitor the process. Now, let's go to void loop()
. Retriving data from azure is done by http get method.
void loop()
{
send_request();
wait_response();
read_response();
end_request();
delay(100);
}
These functions will retrive the data from the azure table. But before deep diving into the methods, we need to add some global variables to link our Edison to Azure service. Add these global variables.
const char* server= "YourAzureService.azure-mobile.net";
const char* table_name= "TableName";
const char* ams_key="YourApplicationKey";
char buffer[64];
The application key can be found in the manage keys button at your azure portal. Now, we will write the code for the methods in void loop()
.
void send_request()
{
Serial.println("\nconnecting...");
if (client.connect(server, 80))
{
sprintf(buffer, "GET /tables/%s HTTP/1.1", table_name);
client.println(buffer);
sprintf(buffer, "Host: %s", server);
client.println(buffer);
sprintf(buffer, "X-ZUMO-APPLICATION: %s", ams_key);
client.println(buffer);
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(strlen(buffer));
client.println();
client.println(buffer);
}
else
{
Serial.println("connection failed");
}
}
We performed an HTTP request and called GET where we have indicated the name of the table previously, the name of the Server and code key, this to allow the correct retrieving of the data. Then we specify in what format the data needs to be retrieved and specified it as JSON. Let's write the code for wait_response()
void wait_response()
{
while (!client.available())
{
if (!client.connected())
{
return;
}
}
}
Then we need to read the data retrieved. Since it's in JSON format, we need to parse the JSON string to get our desired value. Below is the example of a sample string.
{"id":"2492D996-C471-48F0-B3C9-F33E3B37477F","status":"0","name":"arduino"}
A very efficient library known as the ArduinoJson exist. This will do most of the parsing. But the retrieved JSON string is enclosed within '[' and ']'. These must be removed for the library to work. So firstly you need to include the library in your code and add the following global variables and add
#include <ArduinoJson.h>
#define RESPONSE_JSON_DATA_LINENNO 10
int charIndex=0;
StaticJsonBuffer<200> jsonbuffer;
Then write the following code in your read_response
method().
void read_response()
{
boolean bodyStarted;
int jsonStringLength;
int jsonBufferCntr=0;
int numline=RESPONSE_JSON_DATA_LINENNO;
while (client.available())
{
char c = client.read();
if (c == '\n')
{
numline -=1;
}
else
{
if (numline == 0 && (c!='[')&& (c!=']') )
{
buffer[jsonBufferCntr++] = c;
buffer[jsonBufferCntr] = '\0';
}
}
}
Serial.println("Received:");
Serial.println(buffer);
Serial.println("");
parse();
}
The above code will read the response and the parse method is responsible for decoding the string. The parse()
method is shown below. In the Parse()
method itself, we will change the status of the PIN13.
void parse()
{
StaticJsonBuffer<150> jsonbuffer;
JsonObject& root = jsonbuffer.parseObject(buffer);
if(!root.success())
{
Serial.println("PARSING FAILED!!!");
return;
}
int f= root["status"];
Serial.println("Decoded: ");
Serial.println(f);
if(f==0)
digitalWrite(13,LOW);
else
digitalWrite(13,HIGH);
}
Here, in the above code, f stores the value of the attribute of status. Then, we check the value of f and ultimately set the PIN either to HIGH or LOW.
For a detailed documentation on ArduinoJson library visit this link. However, there is a bit of problem with this library. It will be discussed later on. Now, we will write the remaining method's code.
void end_request()
{
client.stop();
}
Now, you will see that when you compile the code, you will most likely encounter some errors. These errors, needs to be removed. Before moving futher have a look over this issue. The file WString.h misses some lines of code. The difference can be seen here. You need to update the file located here.
C:\Users\Username\AppData\Roaming\Arduino15\packages\Intel\hardware\i686\1.6.2+1.0\cores\arduino\WString.h
After updating your errors will be resolved. After you compile the code, burn it into your Edison and then you are done. When the code is burnt in your Edison, take a LED, and attach the longer leg of the LED to PIN13 and the shorter leg to Gnd. An optional 233 ohm resistor can be added with the longer leg. Thus, our Windows Phone controlled Edison via Windows Azure is ready. The screenshot of the serial window while the Edison is in action is shown below.
The first stage is when the Edison is attempting to connect to the Wi-Fi network.
The next stage is when the Edison is trying to connect to the Azure mobile service. After connecting, it obtains the JSON data which is then decoded by the JSON library and then we obtain the decoded result. The decoded result is responsible for the status of the PIN13 on the Edison.
CONCLUSION
Thus we have learnt in this article how to control your Edison using Azure mobile services. The Mobile service acts as a bridge. The Windows phone app alters data in azure tables and ultimately the Edison is controlled. The article didn't cover the Windows phone development but a look at the links, will provide you the info required. The entire Edison code is uploaded as a text file. The YouTube link for the video is here.