Contents

1. Warp7 Yocto Part1

2. Warp7 Yocto Part2

3. Warp7 Sensors demo - mpl3115a2

4. Warp7 Sensors demo - fxos8700cq

5. Warp7 IoT demo <-- You are here

 

Back in May i created a simple IoT for Warp7Warp7 while the BSP was still under development..

Incidentally FTF2016  was round the corner and we thought to demonstrate warp7 progress.

 

In this blog I will pen down the details simple enough for a begineer to understand.

The setup uses Wifi, Sensors and a Cloud Platform. ThingSpeak Cloud platform is used for this as i found it simple, you can use any other platform available.

 

A simple bare-metal sensor application and python script is all that's required to get the warp7 data to the cloud.

 

The  applications perform a push-pull operations between warp7 hardware and the Cloud Platform at regular intervals.

1. Sensor Application : The data from MEMS sensors is retrieved using a bare-metal C program directly reading I2C bus. The data coming at 200Hz is pushed into the bi-directional pipe used by this application. Linux pipes is used so that both the Sensor and Thingspeak application can read/write the file at same time without crashing either application.

2. Thingspeak Application: This application will read data from pipe and update thingspeak IoT interface using a python application and standard API interfaces. The application starts automatically (refer /etc/rc.local) once board is powered on.

 

The Sensor Application :

 

#include <stdio.h>
#include <stdint.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>




static int write_register(int file,unsigned char address,unsigned char reg,unsigned char data) 
{


   unsigned char output_buffer[2];
   struct i2c_rdwr_ioctl_data packets;
   struct i2c_msg messages[1];


    messages[0].addr  = address;
    messages[0].flags = 0;
    messages[0].len   = sizeof(output_buffer);
    messages[0].buf   = output_buffer;


    output_buffer[0] = reg;
    output_buffer[1] = data;


    packets.msgs  = messages;
    packets.nmsgs = 1;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Error sending data");
        return 1;
    }


    return 0;
}




static int read_register(int file, unsigned char address, unsigned char reg, unsigned char *data) 
{
    unsigned char input_buffer, output_buffer;
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[2];




    output_buffer = reg;
    messages[0].addr  = address;
    messages[0].flags = 0;
    messages[0].len   = sizeof(output_buffer);
    messages[0].buf   = &output_buffer;


    messages[1].addr  = address;
    messages[1].flags = I2C_M_RD;
    messages[1].len   = sizeof(input_buffer);
    messages[1].buf   = &input_buffer;



    packets.msgs      = messages;
    packets.nmsgs     = 2;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Error sending data");
        return 1;
    }
    *data = input_buffer;


    return 0;
}


int main() {
    int file, i;
    unsigned char data;
  char data256[256];
    unsigned char data1;
    unsigned char data2;
    int val1;
    int val2;
    int t_m;
    int x_value;
    int y_value;
    int z_value;


  if ((file = open("/dev/i2c-3", O_RDWR)) < 0) 
  {
    perror("Error openning file!");
    exit(1);
    }


//0x00 whoami verify
   if(read_register(file, 0x1E, 0x0D, &data))
    exit(1);
   else
    {
/* printf("GET:WHOAMI[0x%02X]: 0x%02X\n" , 13 , data);*/
  }


// set to active mode
if(write_register(file, 0x1E, 0x2A, 0x01))
    exit(1);
else
{
/* printf("FXOS8700CQ is active");*/
}




//enable accelerometer & magnetometer
if(write_register(file, 0x1E, 0x5B, 0x03))
     exit(1);
else
{
/* printf("enabling accelerometer and magnetometer");*/
}


// setup mpl3115 temperature
//0x0C whoami verify
   if(read_register(file, 0x60, 0x0C, &data))
    exit(1);
   else
   {
   }
//0x26 set ctrlreg1 ACTIVE
   if(write_register(file, 0x60, 0x26, 0x03))
     exit(1);




int counter=0;
while(1)
{
///////////////////////////////////////////////////////Accelerometer
// X value
   if(read_register(file, 0x1E, 0x01, &data1))
    exit(1);
   else
   {
   }


   if(read_register(file, 0x1E, 0x02, &data2))
    exit(1);
   else
   {
   }


 val1 = (int)data1;
 val1 <<=8;
 val2 = (int)data2;
 x_value = val1 | val2;


// Y value
   if(read_register(file, 0x1E, 0x03, &data1))
    exit(1);
   else
   {
   }

   if(read_register(file, 0x1E, 0x04, &data2))
    exit(1);
   else
   {
   }


 val1 = (int)data1;
 val1 <<=8;
 val2 = (int)data2;
 y_value = val1 | val2;




// Z value
   if(read_register(file, 0x1E, 0x05, &data1))
    exit(1);
   else
   {
   }

   if(read_register(file, 0x1E, 0x06, &data2))
    exit(1);
   else
   {
   }


 val1 = (int)data1;
 val1 <<=8;
 val2 = (int)data2;
 z_value = val1 | val2;


//write terminal
/*printf("\n\nx-value :%d:\n",x_value);*/
/*printf("y-value :%d:\n",y_value);*/
/*printf("z-value :%d:\n",z_value);*/


//write file
snprintf(data256, 256, "echo -n %d %d %d > /opt/file1.txt", x_value, y_value, z_value);
system(data256);




///////////////////////////////////////////////////////Magnetometer
// X value
   if(read_register(file, 0x1E, 0x33, &data1))
    exit(1);
   else
   {
   }


   if(read_register(file, 0x1E, 0x34, &data2))
    exit(1);
   else
   {
   }


 val1 = (int)data1;
 val1 <<=8;
 val2 = (int)data2;
 x_value = val1 | val2;


// Y value
   if(read_register(file, 0x1E, 0x35, &data1))
    exit(1);
   else
   {
   }

   if(read_register(file, 0x1E, 0x36, &data2))
    exit(1);
   else
   {
   }


 val1 = (int)data1;
 val1 <<=8;
 val2 = (int)data2;
 y_value = val1 | val2;




// Z value
   if(read_register(file, 0x1E, 0x37, &data1))
    exit(1);
   else
   {
   }

   if(read_register(file, 0x1E, 0x38, &data2))
    exit(1);
   else
   {
   }


 val1 = (int)data1;
 val1 <<=8;
 val2 = (int)data2;
 z_value = val1 | val2;


//write terminal
/*printf("\n\nx-value :%d:\n",x_value);*/
/*printf("y-value :%d:\n",y_value);*/
/*printf("z-value :%d:\n",z_value);*/


//write file
snprintf(data256, 256, "echo -n %d %d %d > /opt/file2.txt", x_value, y_value, z_value);
system(data256);


/////////////////////////////////////////////////////////////////TEMPERATURE
//read temperature MSB/LSB
   if(read_register(file, 0x60, 0x04, &data))
     exit(1);


        val2 = (int)data;
/*        if(DBG_ENABLE == 1) printf("val2: initial :%d:\n",val2);*/
        val2 <<=8;
/*        if(DBG_ENABLE == 1) printf("val2: shift :%d:\n",val2);*/




   if(read_register(file, 0x60, 0x05, &data))
    exit(1);
   else
   {
/*     if(DBG_ENABLE == 1)*/
/*     printf("Register[0x%02X]: 0x%02X\n" , 5 , data);*/
   }


    val2 = val2+ (int)data;


/*    if(DBG_ENABLE == 1)*/
/*    { printf("val2 :%d:\n",val2);*/
/*    }*/


    t_m = (val2 >> 8) & 0xff;


/*   printf("temperature :%d: \n",t_m);*/


snprintf(data256, 256, "echo -n %d > /opt/file3.txt", t_m);
system(data256);




  usleep(100000);
  counter++;
}


    close(file);
    return 0;
}

 

 

 

The Thingspeak Cloud Application.

import sys

from time import sleep 

import urllib2

import os

import time

 

 

def getSensorData():

  with open('/opt/file1.txt') as f:

  line1 = f.readline()

  str1  = str(line1)

  list1  = str1.split()

  x,y,z = list1

  return (str(x), str(y), str(z))

 

def getSensorData2():

  with open('/opt/file2.txt') as f:

  line1 = f.readline()

  str1  = str(line1)

  list1  = str1.split()

  x,y,z = list1

  return (str(x), str(y), str(z))

 

 

def getSensorData3():

  with open('/opt/file3.txt') as f:

  line1 = f.readline()

  str1  = str(line1)

  x = str1

  return (str(x))

 

 

def main():

  print "Starting Warp7 Iot Platform"

  print "activating sensor application"

  os.system("killall a.out")

  os.system("sync")

  time.sleep(1)

  os.system("/opt/a.out &")

  baseURL = 'https://api.thingspeak.com/update?api_key=<YOUR_API_KEY_HERE>'

  x=0

  y=0

  z=0

  x2=0

  y2=0

  z2=0

  x3=0

  while True:

  try:

  x,y,z = getSensorData()

  x2,y2,z2 = getSensorData2()

  x3 = getSensorData3()

  except ValueError:

  print "get: Sensor Data Failed"

  try:

  print "x,y,z:",x,y,z

  print "x2,y2,z2:",x2,y2,z2

  print "x3",x3

  os.system("echo -n 100 > /opt/status1")

  f = urllib2.urlopen(baseURL+"&field1=%s&field2=%s&field3=%s&field4=%s&field5=%s&field6=%s&field7=%s" %(x,y,z,x2,y2,z2,x3))

  print "THINGSPEAK: Updated"

  os.system("echo -n 100 > /opt/status2")

  print f.read()

  f.close()

  except urllib2.HTTPError, e:

  print "urllib2.HTTPError"

  except urllib2.URLError, e:

  print "urllib2.URLError" #print e.args

  time.sleep(1)

 

 

# call main

if __name__ == '__main__':

  main()

 

 

 

First things first:

Before trying the demo , please use a terminal program like gnu screen/minicom to verify the wireless connectivity and sensor application running status. I believe both will work fine.

Download all FTF demo bundle.

 

The default wifi ssid and password as set in the bundle is:

ssid: “warp7ssid

password: “warp7pwd

 

If you don't want to edit wireless setting in the above bundle,  change your router ssid and password (as above) for demo purposes.

Alternatively, edit “/etc/network/interfaces” & “/etc/wpa_supplicant.conf” files and replace the text “warp7ssid” with your SSID and “warp7pwd” with your password.

 

Note:

1. The wireless interfaces might breaks sometimes, hence you might find the  application updating the “last recorded sensor values” to thingspeak.

2. add “#” symbol to line14 in /etc/rc.local to disable python application logs during testing. Mount the rootfs on PC to perform this step. “ums 0 mmc 0” does the thing - Check user manual section 5.2 for more.

 

 

 

The sensor application pushes continuous values to terminal. If you want to perform debugging follow below steps to stop the app.

 

Step1. Power on warp board & wait till you similar values as below in screen:

 

5jspbs.jpg

Step2.

Its difficult to see the prompt, as the sensor application starts dumping values to screen every second. so just do as below.

then type “root”, hit Enter.

Again type “root”, hit enter.

We are logged in now.

 

Step3.

Now type “./stop”, hit enter.

The sensor app will stop, don't worry, the apps will start once board reboots.

 

 

 

 

The First connection to router might take several mins depending on wifi-router connectivity. Updates to “thingspeak” page happens every 3-10 seconds.

If updates are not visible, restart warp7 .

 

Next create a channel in your  thingspeak.com account and get the api key required to push data.

To view sensor data check this channel - https://thingspeak.com/channels/113986.

You will find 4 Graphs that show the calibrated values from MEMS sensors.

 

 

What are the Graphs for ???

Graph1 :  Warp7 accelerometer(FXOS8700CQR1) Roll values.

2e4doiq.jpg

Tilting warp7 to left and right (as shown) will show recorded data (in spikes) in graph based on the direction of tilt.

 

Roll Left.

rutkkx.jpg

Roll Right.

bfozyb.jpg

 

 

 

 

Graph2 : Warp7 accelerometer(FXOS8700CQR1) Pitch values.

2cyp9x2.jpg

Tilting warp7 up and down will record data in thingspeak as above.

Pitch Up.

2vmf3ly.jpg

Pitch Down.

344fs76.jpg

 

Graph3 : Warp7 Magnetometer (FXOS8700CQR1) values

11lkinc.jpg

Warp7 magnetometer and Android Phone both facing north.

if magnetometer pointed NORTH, y-axis value in graph3 will be 0.

 

24myrdu.jpg

 

Graph4  MPL3115A2MPL3115A2 temperature values

Self Explanatory

316ryu9.jpg

 

 

Snapshot of thingspeak page (10-may-2016):

https://thingspeak.com/channels/113986

 

wcc0g5.jpg

 

Let me know challenges if any.