Introduction: Linkit One Serving JSONP Sensor Data (battery Example)

This is partial port of something I started doing with the Intel Edison (see here: https://www.instructables.com/id/Intel-Edison-Sensor-Dashboard-Using-FreeboardPytho/ ). The idea is relatively simple: present sensor data as json(p) so that a IoT enabler (like freeboard.io) can readily consume the data. I will minimally go over freeboard.io here. More details about freeboard are available at their site: http://freeboard.io and in my other instructuable linked above. I will in another instructable try to port freeboard/adapt freeboard to be served by the linkitone. Look for that in the future (and hopefully I'll remember to link to it here).

I must give credit where credit is due. I used these tutorials a lot to make this work: https://evothings.com/create-your-own-mobile-application-for-the-mediatek-linkit-one/ (They do exactly what I am doing but with GPS data and present it in a nice IoT-friendly JSON format)

I have made a separate tutorial on improving the GPS sketch by evothings and will link to it here later. (The reasoning is that I wanted to keep the code for this example very simple. I didn’t want to confuse anyone with the GPS parsing and such.)

All of the code for this can be found here: https://github.com/stirobot/evothings-examples/tree/master/examples/mediatek-linkit

Step 1: Materials

Materials:

  • A Linkit One
  • A sensor of some type - in the evothings example they use the stock GPS sensor, I have opted to reuse a lot of their code (available at their github here: https://github.com/evothings/evothings-examples and my fork with added goodies: https://github.com/evothings/evothings-examples hint: go down into the linkit one examples for what I have added). However, for my example I am going to use the battery as a sensor because it is something that everyone has in their linkit kit and it is easier to understand without all of the GPS helper code.
  • A network connection of some type - I suggest using wifi for simplicity in this demo. You can use cellular or bluetooth, but that will not be covered here.
  • A way to power your linkit one - I prefer the battery.
  • Something running freeboard.io. For simplicity and testing you can download freeboard and just double click the index.html once you unzip the package onto your computer. That should open up a working freeboard instance in your browser. I will make an attempt in another instructable to get freeboard working on the linkit one, but for now this is a good debugging solution.

Step 2: Setup

Follow what is here: https://www.instructables.com/id/Dummys-Linkit-One-Getting-Started-Guide/

Especially check out the GPS code test and the wifi code test. If you can get those to work then you are good to go.

Issues I ran into:

-Serial port monitoring didn’t work at first - update the firmware - reflash the sketch to your board and make sure you have the data-rate set correctly (115200 usually).

-I spent a few hours trying to get the board to power by the battery. After flashing the sketch to the board I plugged in the battery and switched the usb/batt switch to the batt side and the thing kept rebooting. Later I found out that if you have this issue you just have to do this.

  1. Set the switches to USB and UART
  2. Plug in the battery
  3. Switch from UART to MS
  4. Switch to BATT
  5. Switch to UART

Step 3: Code Walkthrough

When you are done you should be able to go to the ip address of your linkit one and see something like what is pictured for this step.

#include <LTask.h>
#include <LWifi.h> #include <LWifiServer.h> #include <LWifiClient.h> #include <LBattery.h>

These are the mediatek libraries. I can’t remember what task does. The wifi help with wifi and the battery one provides two simple functions. One to check the battery level and one to tell you if it is being charged or discharged.

// Configuration of the WiFi AP settings.
#define WIFI_AP "foo" #define WIFI_PASSWORD "bar"

// LWIFI_OPEN, LWIFI_WPA, or LWIFI_WEP. #define WIFI_AUTH LWIFI_WPA

Put your specific AP information here (this is the kind of thing that in a fancier sketch you’d put in a properties file on the storage part of the board and read in here).

// Configure the timeout of a http request (ms).
const uint32_t requestTimeout = 1000;

// Global variables LWiFiServer server(80); char buff[256];

Self explanatory global variables. The server port it what that 80 is.

void setup()
{ LTask.begin(); LWiFi.begin(); Serial.begin(115200); //delay(2000); }

I took out the delay that was in the original sketch. If you want to know why delays are evil check this out: https://www.sparkfun.com/news/1940

yadda yadda...there is some code that checks the wifi status and spams it to the serial console. I’m not going to go over it here. It’s great for quickly figuring out what ip address your linkit one has received from the AP. The other way you can do that it by going to the admin page of your AP and looking at the DHCP table for the entry with the matching MAC address (look at the sticker on the bottom of your board).

while (client.connected())
{ if (client.available()) { // we basically ignores client request, but wait for HTTP request end int c = client.read(); lastReceptionTime = millis();

Serial.print((char)c);

if (c == '\n' && currentLineIsBlank) { Serial.println("send response"); // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: application/json"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println("Access-Control-Allow-Origin: *"); client.println(); client.print("{\"batteryLevel\":\""); client.print(LBattery.level()); client.print("\", \"chargingStatus\":\""); client.print(LBattery.isCharging()); client.print("\"}"); client.println(); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } else { if (millis() - lastReceptionTime > requestTimeout) { Serial.println("Error - client timeout, dropping connection..."); break; } } } // give the web browser time to receive the data delay(500);

// close the connection: Serial.println("close connection"); client.stop(); Serial.println("client disconnected"); }

This bit is the web server proper. It takes care of everything from when a client hits it with an HTTP GET to the point that that connection is done.


The important stuff happens in these lines:

client.println("Content-Type: application/json");

This line sets the mime type of the return to json, which is understood by many “IoT enablers” like ubidots, freeboard, etc.

client.print("{\"batteryLevel\":\"");
client.print(LBattery.level()); client.print("\", \"chargingStatus\":\""); client.print(LBattery.isCharging());

The LBattery.level() is that very simple method I alluded to earlier on which simply returns the battery level. Unfortunately it isn’t very fine grained and will only give 0, 33, 66, and 100.
It is fairly simple to replace this code with your own and have any sensor values served up as json data for easy consumption. Replace batteryLevel with your descriptor and the function call with a function call that gets data from your sensor of choice. You can also expand these printing lines in the same pattern to build more structure into it. For more info on json and what json looks like check out: http://www.w3schools.com/json/

Step 4: Freeboard

You can run freeboard locally or just open it in your browser. The configuration of a new datasource is very straightforward and I chose freeboard as the example dashboard because it requires 0 programming. All you have to do is point and click. Look at the settings I used in the pictures above to get you started.

Epilog Contest VII

Participated in the
Epilog Contest VII