Pubnub demo for AT&T IoT Starter Kit. Functionally similar to the Flow demo.

Dependencies:   FXOS8700CQ MODSERIAL mbed

http://pubnub.github.io/slides/workshop/pictures/broadcast.png

Pubnub demo for AT&T IoT Starter Kit

This demo is functionally similar to the Flow demo, so you can find general information here: https://developer.mbed.org/users/JMF/code/Avnet_ATT_Cellular_IOT/.

The only difference is that we use Pubnub to publish the measurements and subscribe to receiving the instructions to set the LED.

Settings

Pubnub related settings are:

Pubnub settings in `config_me.h`

PUBNUB_SUBSCRIBE_KEY
PUBNUB_PUBLISH_KEY
PUBNUB_CHANNEL

All are documented in their respective comments.

Pubnub context class

Similar to Pubnub SDKs, we provide a Pubnub context class. It is defined in pubnub.h header file and implemented in pubnub.cpp.

It provides only the fundamental "publish" and "subscribe" methods. They are documented in the header file.

This class is reusable in other code (it is not specific to this demo), it has a very narrow interface to the AT&T IoT cellular modem code. For example of use, you can look at the main() (in main.c).

Sample of published data

Published message w/measurement data

{"serial":"vstarterkit001","temp":89.61,"humidity":35,"accelX":0.97,"accelY":0.013,"accelZ":-0.038}

Don't worry, nobody got burnt, the temperature is in degrees Fahrenheit. :)

Publish a message (from, say, the Pubnub console http://pubnub.com/console) of the form {"LED":<name-of-the-color>} on the channel that this demo listens to (default is hello_world) to turn the LED to that color on the Starter Kit:

Turn LED to red

{"LED":"Red"}

Turn LED to green

{"LED":"Green"}

Turn LED to blue

{"LED":"Blue"}
Committer:
stefanrousseau
Date:
Mon Aug 01 20:19:58 2016 +0000
Revision:
63:90d7c69993cd
Parent:
61:f6b93129f954
Child:
64:09004cd610df
Changed the mdm UART from SerialBuffered to MODSERIAL so there will only be one type.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stefanrousseau 55:3abf9e3f42e6 1 #include "mbed.h"
JMF 0:9d5134074d84 2 #include <cctype>
JMF 0:9d5134074d84 3 #include <string>
JMF 2:0e2ef866af95 4 #include "config_me.h"
stefanrousseau 4:f83bedd9cab4 5 #include "sensors.h"
stefanrousseau 61:f6b93129f954 6 #include "cell_modem.h"
stefanrousseau 11:e6602513730f 7 #include "hardware.h"
stefanrousseau 11:e6602513730f 8
stefanrousseau 61:f6b93129f954 9 I2C i2c(PTC11, PTC10); //SDA, SCL -- define the I2C pins being used
stefanrousseau 56:cb42ff383dab 10 MODSERIAL pc(USBTX, USBRX, 256, 256); // tx, rx with default tx, rx buffer sizes
stefanrousseau 63:90d7c69993cd 11 MODSERIAL mdm(PTD3, PTD2, 4096, 4096);
stefanrousseau 16:17c5916f2d12 12 DigitalOut led_green(LED_GREEN);
stefanrousseau 16:17c5916f2d12 13 DigitalOut led_red(LED_RED);
stefanrousseau 16:17c5916f2d12 14 DigitalOut led_blue(LED_BLUE);
JMF 0:9d5134074d84 15
JMF 0:9d5134074d84 16
stefanrousseau 3:26b3cc155f39 17 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 18 //* Create string with sensor readings that can be sent to flow as an HTTP get
stefanrousseau 3:26b3cc155f39 19 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 20 K64F_Sensors_t SENSOR_DATA =
stefanrousseau 3:26b3cc155f39 21 {
stefanrousseau 12:7c94ec5069dc 22 .Temperature = "0",
stefanrousseau 12:7c94ec5069dc 23 .Humidity = "0",
stefanrousseau 12:7c94ec5069dc 24 .AccelX = "0",
stefanrousseau 12:7c94ec5069dc 25 .AccelY = "0",
stefanrousseau 12:7c94ec5069dc 26 .AccelZ = "0",
stefanrousseau 12:7c94ec5069dc 27 .MagnetometerX = "0",
stefanrousseau 12:7c94ec5069dc 28 .MagnetometerY = "0",
stefanrousseau 12:7c94ec5069dc 29 .MagnetometerZ = "0",
stefanrousseau 12:7c94ec5069dc 30 .AmbientLightVis = "0",
stefanrousseau 12:7c94ec5069dc 31 .AmbientLightIr = "0",
stefanrousseau 12:7c94ec5069dc 32 .UVindex = "0",
stefanrousseau 12:7c94ec5069dc 33 .Proximity = "0",
stefanrousseau 12:7c94ec5069dc 34 .Temperature_Si7020 = "0",
stefanrousseau 55:3abf9e3f42e6 35 .Humidity_Si7020 = "0",
stefanrousseau 55:3abf9e3f42e6 36 .Virtual_Sensor1 = "0",
stefanrousseau 55:3abf9e3f42e6 37 .Virtual_Sensor2 = "0",
stefanrousseau 55:3abf9e3f42e6 38 .Virtual_Sensor3 = "0",
stefanrousseau 55:3abf9e3f42e6 39 .Virtual_Sensor4 = "0",
stefanrousseau 55:3abf9e3f42e6 40 .Virtual_Sensor5 = "0",
stefanrousseau 55:3abf9e3f42e6 41 .Virtual_Sensor6 = "0",
stefanrousseau 55:3abf9e3f42e6 42 .Virtual_Sensor7 = "0",
stefanrousseau 55:3abf9e3f42e6 43 .Virtual_Sensor8 = "0"
stefanrousseau 3:26b3cc155f39 44 };
stefanrousseau 12:7c94ec5069dc 45
stefanrousseau 3:26b3cc155f39 46 void GenerateModemString(char * modem_string)
stefanrousseau 3:26b3cc155f39 47 {
stefanrousseau 12:7c94ec5069dc 48 switch(iSensorsToReport)
stefanrousseau 12:7c94ec5069dc 49 {
stefanrousseau 12:7c94ec5069dc 50 case TEMP_HUMIDITY_ONLY:
stefanrousseau 12:7c94ec5069dc 51 {
stefanrousseau 12:7c94ec5069dc 52 sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, FLOW_URL_TYPE, MY_SERVER_URL);
stefanrousseau 12:7c94ec5069dc 53 break;
stefanrousseau 12:7c94ec5069dc 54 }
stefanrousseau 12:7c94ec5069dc 55 case TEMP_HUMIDITY_ACCELEROMETER:
stefanrousseau 12:7c94ec5069dc 56 {
stefanrousseau 12:7c94ec5069dc 57 sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&accelX=%s&accelY=%s&accelZ=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,SENSOR_DATA.AccelZ, FLOW_URL_TYPE, MY_SERVER_URL);
stefanrousseau 12:7c94ec5069dc 58 break;
stefanrousseau 12:7c94ec5069dc 59 }
stefanrousseau 12:7c94ec5069dc 60 case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS:
stefanrousseau 12:7c94ec5069dc 61 {
stefanrousseau 12:7c94ec5069dc 62 sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&accelX=%s&accelY=%s&accelZ=%s&proximity=%s&light_uv=%s&light_vis=%s&light_ir=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,SENSOR_DATA.AccelZ, SENSOR_DATA.Proximity, SENSOR_DATA.UVindex, SENSOR_DATA.AmbientLightVis, SENSOR_DATA.AmbientLightIr, FLOW_URL_TYPE, MY_SERVER_URL);
stefanrousseau 12:7c94ec5069dc 63 break;
stefanrousseau 12:7c94ec5069dc 64 }
stefanrousseau 55:3abf9e3f42e6 65 case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS_VIRTUALSENSORS:
stefanrousseau 55:3abf9e3f42e6 66 {
stefanrousseau 55:3abf9e3f42e6 67 sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&accelX=%s&accelY=%s&accelZ=%s&proximity=%s&light_uv=%s&light_vis=%s&light_ir=%s&virt_sens1=%s&virt_sens2=%s&virt_sens3=%s&virt_sens4=%s&virt_sens5=%s&virt_sens6=%s&virt_sens7=%s&virt_sens8=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,SENSOR_DATA.AccelZ, SENSOR_DATA.Proximity, SENSOR_DATA.UVindex, SENSOR_DATA.AmbientLightVis, SENSOR_DATA.AmbientLightIr, SENSOR_DATA.Virtual_Sensor1, SENSOR_DATA.Virtual_Sensor2, SENSOR_DATA.Virtual_Sensor3, SENSOR_DATA.Virtual_Sensor4, SENSOR_DATA.Virtual_Sensor5, SENSOR_DATA.Virtual_Sensor6, SENSOR_DATA.Virtual_Sensor7, SENSOR_DATA.Virtual_Sensor8, FLOW_URL_TYPE, MY_SERVER_URL);
stefanrousseau 55:3abf9e3f42e6 68 break;
stefanrousseau 55:3abf9e3f42e6 69 }
stefanrousseau 12:7c94ec5069dc 70 default:
stefanrousseau 12:7c94ec5069dc 71 {
stefanrousseau 12:7c94ec5069dc 72 sprintf(modem_string, "Invalid sensor selected\r\n\r\n");
stefanrousseau 12:7c94ec5069dc 73 break;
stefanrousseau 12:7c94ec5069dc 74 }
stefanrousseau 16:17c5916f2d12 75 } //switch(iSensorsToReport)
stefanrousseau 3:26b3cc155f39 76 } //GenerateModemString
stefanrousseau 3:26b3cc155f39 77
stefanrousseau 3:26b3cc155f39 78
stefanrousseau 3:26b3cc155f39 79 //Periodic timer
stefanrousseau 3:26b3cc155f39 80 Ticker OneMsTicker;
stefanrousseau 3:26b3cc155f39 81 volatile bool bTimerExpiredFlag = false;
stefanrousseau 3:26b3cc155f39 82 int OneMsTicks = 0;
stefanrousseau 3:26b3cc155f39 83 int iTimer1Interval_ms = 1000;
stefanrousseau 3:26b3cc155f39 84 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 85 //* Periodic 1ms timer tick
stefanrousseau 3:26b3cc155f39 86 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 87 void OneMsFunction()
stefanrousseau 3:26b3cc155f39 88 {
stefanrousseau 3:26b3cc155f39 89 OneMsTicks++;
stefanrousseau 3:26b3cc155f39 90 if ((OneMsTicks % iTimer1Interval_ms) == 0)
stefanrousseau 3:26b3cc155f39 91 {
stefanrousseau 3:26b3cc155f39 92 bTimerExpiredFlag = true;
stefanrousseau 3:26b3cc155f39 93 }
stefanrousseau 3:26b3cc155f39 94 } //OneMsFunction()
stefanrousseau 3:26b3cc155f39 95
stefanrousseau 16:17c5916f2d12 96 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 97 //* Set the RGB LED's Color
stefanrousseau 16:17c5916f2d12 98 //* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue)
stefanrousseau 16:17c5916f2d12 99 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 100 void SetLedColor(unsigned char ucColor)
stefanrousseau 16:17c5916f2d12 101 {
stefanrousseau 16:17c5916f2d12 102 //Note that when an LED is on, you write a 0 to it:
stefanrousseau 16:17c5916f2d12 103 led_red = !(ucColor & 0x1); //bit 0
stefanrousseau 16:17c5916f2d12 104 led_green = !(ucColor & 0x2); //bit 1
stefanrousseau 16:17c5916f2d12 105 led_blue = !(ucColor & 0x4); //bit 2
stefanrousseau 16:17c5916f2d12 106 } //SetLedColor()
stefanrousseau 16:17c5916f2d12 107
stefanrousseau 16:17c5916f2d12 108 //********************************************************************************************************************************************
stefanrousseau 61:f6b93129f954 109 //* Process the JSON response. In this example we are only extracting a LED color.
stefanrousseau 16:17c5916f2d12 110 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 111 bool parse_JSON(char* json_string)
stefanrousseau 16:17c5916f2d12 112 {
stefanrousseau 16:17c5916f2d12 113 char* beginquote;
stefanrousseau 16:17c5916f2d12 114 char token[] = "\"LED\":\"";
stefanrousseau 16:17c5916f2d12 115 beginquote = strstr(json_string, token );
stefanrousseau 16:17c5916f2d12 116 if ((beginquote != 0))
stefanrousseau 16:17c5916f2d12 117 {
stefanrousseau 16:17c5916f2d12 118 char cLedColor = beginquote[strlen(token)];
stefanrousseau 16:17c5916f2d12 119 printf(GRN "LED Found : %c" DEF "\r\n", cLedColor);
stefanrousseau 16:17c5916f2d12 120 switch(cLedColor)
stefanrousseau 16:17c5916f2d12 121 {
stefanrousseau 16:17c5916f2d12 122 case 'O':
stefanrousseau 16:17c5916f2d12 123 { //Off
stefanrousseau 16:17c5916f2d12 124 SetLedColor(0);
stefanrousseau 16:17c5916f2d12 125 break;
stefanrousseau 16:17c5916f2d12 126 }
stefanrousseau 16:17c5916f2d12 127 case 'R':
stefanrousseau 16:17c5916f2d12 128 { //Red
stefanrousseau 16:17c5916f2d12 129 SetLedColor(1);
stefanrousseau 16:17c5916f2d12 130 break;
stefanrousseau 16:17c5916f2d12 131 }
stefanrousseau 16:17c5916f2d12 132 case 'G':
stefanrousseau 16:17c5916f2d12 133 { //Green
stefanrousseau 16:17c5916f2d12 134 SetLedColor(2);
stefanrousseau 16:17c5916f2d12 135 break;
stefanrousseau 16:17c5916f2d12 136 }
stefanrousseau 16:17c5916f2d12 137 case 'Y':
stefanrousseau 16:17c5916f2d12 138 { //Yellow
stefanrousseau 16:17c5916f2d12 139 SetLedColor(3);
stefanrousseau 16:17c5916f2d12 140 break;
stefanrousseau 16:17c5916f2d12 141 }
stefanrousseau 16:17c5916f2d12 142 case 'B':
stefanrousseau 16:17c5916f2d12 143 { //Blue
stefanrousseau 16:17c5916f2d12 144 SetLedColor(4);
stefanrousseau 16:17c5916f2d12 145 break;
stefanrousseau 16:17c5916f2d12 146 }
stefanrousseau 16:17c5916f2d12 147 case 'M':
stefanrousseau 16:17c5916f2d12 148 { //Magenta
stefanrousseau 16:17c5916f2d12 149 SetLedColor(5);
stefanrousseau 16:17c5916f2d12 150 break;
stefanrousseau 16:17c5916f2d12 151 }
stefanrousseau 16:17c5916f2d12 152 case 'T':
stefanrousseau 16:17c5916f2d12 153 { //Turquoise
stefanrousseau 16:17c5916f2d12 154 SetLedColor(6);
stefanrousseau 16:17c5916f2d12 155 break;
stefanrousseau 16:17c5916f2d12 156 }
stefanrousseau 16:17c5916f2d12 157 case 'W':
stefanrousseau 16:17c5916f2d12 158 { //White
stefanrousseau 16:17c5916f2d12 159 SetLedColor(7);
stefanrousseau 16:17c5916f2d12 160 break;
stefanrousseau 16:17c5916f2d12 161 }
stefanrousseau 16:17c5916f2d12 162 default:
stefanrousseau 16:17c5916f2d12 163 {
stefanrousseau 16:17c5916f2d12 164 break;
stefanrousseau 16:17c5916f2d12 165 }
stefanrousseau 16:17c5916f2d12 166 } //switch(cLedColor)
stefanrousseau 16:17c5916f2d12 167 return true;
stefanrousseau 16:17c5916f2d12 168 }
stefanrousseau 16:17c5916f2d12 169 else
stefanrousseau 16:17c5916f2d12 170 {
stefanrousseau 16:17c5916f2d12 171 return false;
stefanrousseau 16:17c5916f2d12 172 }
stefanrousseau 16:17c5916f2d12 173 } //parse_JSON
stefanrousseau 16:17c5916f2d12 174
JMF 0:9d5134074d84 175 int main() {
stefanrousseau 61:f6b93129f954 176 static unsigned ledOnce = 0;
fkellermavnet 20:27a4f27254d0 177
stefanrousseau 61:f6b93129f954 178 pc.baud(115200);
stefanrousseau 61:f6b93129f954 179 pc.printf(GRN "Hello World from the Cellular IoT Kit!\r\n\r\n");
JMF 0:9d5134074d84 180
stefanrousseau 61:f6b93129f954 181 //Initialize the I2C sensors that are present
stefanrousseau 11:e6602513730f 182 sensors_init();
stefanrousseau 12:7c94ec5069dc 183 read_sensors();
stefanrousseau 11:e6602513730f 184
stefanrousseau 61:f6b93129f954 185 // Set LED to RED until init finishes
stefanrousseau 61:f6b93129f954 186 SetLedColor(0x1); //Red
JMF 0:9d5134074d84 187 // Initialize the modem
stefanrousseau 61:f6b93129f954 188 pc.printf("\r\n");
stefanrousseau 61:f6b93129f954 189 cell_modem_init();
stefanrousseau 61:f6b93129f954 190 // Set LED BLUE for partial init
stefanrousseau 61:f6b93129f954 191 SetLedColor(0x4); //Blue
JMF 0:9d5134074d84 192
stefanrousseau 3:26b3cc155f39 193 //Create a 1ms timer tick function:
stefanrousseau 61:f6b93129f954 194 iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS;
stefanrousseau 3:26b3cc155f39 195 OneMsTicker.attach(OneMsFunction, 0.001f) ;
fkellermavnet 26:8d6e7e7cdcae 196
JMF 2:0e2ef866af95 197 // Send and receive data perpetually
JMF 2:0e2ef866af95 198 while(1) {
stefanrousseau 55:3abf9e3f42e6 199 #ifdef USE_VIRTUAL_SENSORS
stefanrousseau 55:3abf9e3f42e6 200 ProcessUsbInterface();
stefanrousseau 55:3abf9e3f42e6 201 #endif
stefanrousseau 3:26b3cc155f39 202 if (bTimerExpiredFlag)
stefanrousseau 3:26b3cc155f39 203 {
stefanrousseau 3:26b3cc155f39 204 bTimerExpiredFlag = false;
stefanrousseau 4:f83bedd9cab4 205 read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor
stefanrousseau 3:26b3cc155f39 206 char modem_string[512];
stefanrousseau 3:26b3cc155f39 207 GenerateModemString(&modem_string[0]);
stefanrousseau 61:f6b93129f954 208 char myJsonResponse[512];
stefanrousseau 61:f6b93129f954 209 if (cell_modem_Sendreceive(&modem_string[0], &myJsonResponse[0]))
fkellermavnet 20:27a4f27254d0 210 {
stefanrousseau 41:9b14c40eebf6 211 if (!ledOnce)
stefanrousseau 41:9b14c40eebf6 212 {
stefanrousseau 41:9b14c40eebf6 213 ledOnce = 1;
stefanrousseau 61:f6b93129f954 214 SetLedColor(0x2); //Green
stefanrousseau 41:9b14c40eebf6 215 }
stefanrousseau 61:f6b93129f954 216 parse_JSON(&myJsonResponse[0]);
stefanrousseau 16:17c5916f2d12 217 }
stefanrousseau 3:26b3cc155f39 218 } //bTimerExpiredFlag
stefanrousseau 3:26b3cc155f39 219 } //forever loop
JMF 0:9d5134074d84 220 }