This program simply connects to a HTS221 I2C device to read Temperature & Humidity, and a WNC Cellular Module both of which are on the Avnet WNC Shield.

Dependencies:   mbed FXOS8700CQ

/media/uploads/JMF/avnet_logo.gif

AT&T Shape Hackathon QuickStart Instructions

  • One area that has been problematic is setting the the MY_SERVER_URL. When you copy the URL from the flow, you must make sure that the MY_SERVER_URL is also set to the appropirate server. It can be either "run-east.att.io" or "run-west.att.io", so be sure to check this.

Useful Links

Adding Additional Sensors

The FLOW_DEVICE_NAME field must contain the name of the instance of the Virtual Starter kit in FLOW that you will be communicating with. Usually this will be "vstarterkit001", but if you have problems communicating you can verify that this is indeed correct. Note that this device will not be created until you click the “Initialize” input on the Virtual Device tab of the Starter Kit project in FLOW. At that point it becomes available in M2X and you can see it there, as the DEVICE SERIAL field under Devices as in the image below.

Sensors: When executing, the FRDM-K64F board will upload sensor measurements to AT&T’s Flow environment every 5 seconds, using the Cellular shield board. You can adjust how often you want to do this by editing the SENSOR_UPDATE_INTERVAL_MS value in the header file. Temperature and humidity: By default the board will report readings from the HTS221 temperature and humidity sensor. These two values are sent to the HTTP IN /climate port in FLOW with field names “temp” and “humidity”. Temperature is in degrees Fahrenheit and humidity is a %. This default assignment is: iSensorsToReport = TEMP_HUMIDITY_ONLY;

Accelerometer: If you want to expand and use the on-board motion sensor, you can also send 3-axis accelerometer information from the board as “accelX”, “accelY” and “accelZ”. This is useful if you want to know the stationary position of the board with regards to gravity, or whether it is in motion. These readings are in g’s. To send these values, change the assignment to: iSensorsToReport = TEMP_HUMIDITY_ACCELEROMETER;

PMOD Sensors: If you have a Silicon Labs sensor module that can plug into the PMOD connector on the Cellular shield, you will also be able to measure proximity, UV light, ambient visible and infrared light from the Si1145 sensor. This PMOD also has a temperature and humidity sensor, but in this case it is redundant. When enabled, the fields “proximity”, “light_uv”, “light_vis” and “light_ir” will also be sent. To enable all these sensors, change the assignment to: iSensorsToReport = TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS;

Connecting up the PMOD sensors: Because the pinouts do not align, the SiLabs PMOD sensor board cannot be plugged into the J10 PMOD receptacle on the shield directly. The following wiring instructions must be used:

Signal=J10=(Shield) PMOD=Color in the image below
VCCPin 6Pin 6Red
GNDPin 5Pin 5Black
SDAPin4Pin 3Green
SCLPin3Pin 2Yellow

Link to AT&T M2X

M2X

Link to AT&T Flow

FLOW

Avnet WNC-Shield Information

Getting Started with the Avnet WNC-Shield & Hackathon software

  • This project uses Revision 119 of the MBED library because of I2C implementation differences with the tip (Revision 121)
  • This project uses Revision 4 of the FXOS8700CQ library for sensors

Easily modifiable parameters in source code

Inside the mbed “AvnetATT_shape_hackathon” project, the parameters that are needed to customize your board are in the config_me.h file.

  • FLOW parameters: This project assumes that you are using a fork of the “Starter Kit Base” project, which is a reference design that was created using AT&T’s FLOW (https://flow.att.com) that allows the creation of on-line virtualization and other IoT functionality. The default parameters in the config_me.h file are done for a specific instance of this project. When you fork the original project, you get your own instance and it will have its own base address. At the bottom of the FLOW environment, when you click on the “Endpoints” tab, you will see the URL information that is specific to your instance. Of note is the Base URL. In the example below (as in the default mbed project), the Base URL is: https://run-west.att.io/1e464b19cdcde/774c88d68202/86694923d5bf28a/in/flow You have to take note of two parts of this address. The run-west.att.io part is the server URL, and you have to make sure the
  • MY_SERVER_URL field in config_me.h matches this. Then there is the rest of the base URL, in green above, that needs to be pasted into the FLOW_BASE_URL field.

There is also a FLOW_INPUT_NAME field. This should match the name of the HTTP IN port in the FLOW project that you want to send sensor data to. The default is "/climate", as in the FLOW image below.

/media/uploads/JMF/sf.png

Where is the binary I compiled

When the COMPILE button is pressed, it will compile your project and link it. The result is placed in the DOWNLOAD folder you use when downloading files from the internet. It will be called AvnetATT_shape_hackathon_K64F.bin.

Additional information on compiling/configuring

Comprehensive instructions can be found at: Quick Start Instructions

Committer:
stefanrousseau
Date:
Wed Jul 13 05:55:06 2016 +0000
Revision:
15:61df4a452d38
Parent:
12:7c94ec5069dc
Added JSON parsing and displaying the LED color

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:9d5134074d84 1 #include "mbed.h"
JMF 0:9d5134074d84 2 #include <cctype>
JMF 0:9d5134074d84 3 #include <string>
JMF 0:9d5134074d84 4 #include "SerialBuffered.h"
JMF 0:9d5134074d84 5 #include "HTS221.h"
JMF 2:0e2ef866af95 6 #include "config_me.h"
JMF 2:0e2ef866af95 7 #include "wnc_control.h"
stefanrousseau 4:f83bedd9cab4 8 #include "sensors.h"
JMF 0:9d5134074d84 9
stefanrousseau 11:e6602513730f 10 #include "hardware.h"
stefanrousseau 11:e6602513730f 11 I2C i2c(PTC11, PTC10); //SDA, SCL -- define the I2C pins being used
stefanrousseau 11:e6602513730f 12
JMF 0:9d5134074d84 13 // comment out the following line if color is not supported on the terminal
JMF 0:9d5134074d84 14 #define USE_COLOR
JMF 0:9d5134074d84 15 #ifdef USE_COLOR
JMF 0:9d5134074d84 16 #define BLK "\033[30m"
JMF 0:9d5134074d84 17 #define RED "\033[31m"
JMF 0:9d5134074d84 18 #define GRN "\033[32m"
JMF 0:9d5134074d84 19 #define YEL "\033[33m"
JMF 0:9d5134074d84 20 #define BLU "\033[34m"
JMF 0:9d5134074d84 21 #define MAG "\033[35m"
JMF 0:9d5134074d84 22 #define CYN "\033[36m"
JMF 0:9d5134074d84 23 #define WHT "\033[37m"
JMF 0:9d5134074d84 24 #define DEF "\033[39m"
JMF 0:9d5134074d84 25 #else
JMF 0:9d5134074d84 26 #define BLK
JMF 0:9d5134074d84 27 #define RED
JMF 0:9d5134074d84 28 #define GRN
JMF 0:9d5134074d84 29 #define YEL
JMF 0:9d5134074d84 30 #define BLU
JMF 0:9d5134074d84 31 #define MAG
JMF 0:9d5134074d84 32 #define CYN
JMF 0:9d5134074d84 33 #define WHT
JMF 0:9d5134074d84 34 #define DEF
JMF 0:9d5134074d84 35 #endif
JMF 0:9d5134074d84 36
JMF 0:9d5134074d84 37 #define MDM_DBG_OFF 0
JMF 0:9d5134074d84 38 #define MDM_DBG_AT_CMDS (1 << 0)
JMF 0:9d5134074d84 39 int mdm_dbgmask = MDM_DBG_OFF;
JMF 0:9d5134074d84 40
JMF 0:9d5134074d84 41 Serial pc(USBTX, USBRX);
JMF 0:9d5134074d84 42 SerialBuffered mdm(PTD3, PTD2, 128);
stefanrousseau 15:61df4a452d38 43 DigitalOut led_green(LED_GREEN);
stefanrousseau 15:61df4a452d38 44 DigitalOut led_red(LED_RED);
stefanrousseau 15:61df4a452d38 45 DigitalOut led_blue(LED_BLUE);
JMF 0:9d5134074d84 46
JMF 0:9d5134074d84 47 DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot
JMF 0:9d5134074d84 48 DigitalOut mdm_power_on(PTB9); // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem)
JMF 0:9d5134074d84 49 DigitalOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield
JMF 0:9d5134074d84 50
JMF 0:9d5134074d84 51 DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active
JMF 0:9d5134074d84 52 DigitalOut mdm_uart1_cts(PTD0);
JMF 0:9d5134074d84 53
JMF 0:9d5134074d84 54 #define TOUPPER(a) (a) //toupper(a)
JMF 0:9d5134074d84 55
JMF 0:9d5134074d84 56 const char ok_str[] = "OK";
JMF 0:9d5134074d84 57 const char error_str[] = "ERROR";
JMF 0:9d5134074d84 58
JMF 0:9d5134074d84 59 #define MDM_OK 0
JMF 0:9d5134074d84 60 #define MDM_ERR_TIMEOUT -1
JMF 0:9d5134074d84 61
JMF 0:9d5134074d84 62 #define MAX_AT_RSP_LEN 255
JMF 0:9d5134074d84 63
JMF 0:9d5134074d84 64 ssize_t mdm_getline(char *buff, size_t size, int timeout_ms) {
JMF 0:9d5134074d84 65 int cin = -1;
JMF 0:9d5134074d84 66 int cin_last;
JMF 0:9d5134074d84 67
JMF 0:9d5134074d84 68 if (NULL == buff || size == 0) {
JMF 0:9d5134074d84 69 return -1;
JMF 0:9d5134074d84 70 }
JMF 0:9d5134074d84 71
JMF 0:9d5134074d84 72 size_t len = 0;
JMF 0:9d5134074d84 73 Timer timer;
JMF 0:9d5134074d84 74 timer.start();
JMF 0:9d5134074d84 75 while ((len < (size-1)) && (timer.read_ms() < timeout_ms)) {
JMF 0:9d5134074d84 76 if (mdm.readable()) {
JMF 0:9d5134074d84 77 cin_last = cin;
JMF 0:9d5134074d84 78 cin = mdm.getc();
JMF 0:9d5134074d84 79 if (isprint(cin)) {
JMF 0:9d5134074d84 80 buff[len++] = (char)cin;
JMF 0:9d5134074d84 81 continue;
JMF 0:9d5134074d84 82 } else if (('\r' == cin_last) && ('\n' == cin)) {
JMF 0:9d5134074d84 83 break;
JMF 0:9d5134074d84 84 }
JMF 0:9d5134074d84 85 }
JMF 0:9d5134074d84 86 wait_ms(1);
JMF 0:9d5134074d84 87 }
JMF 2:0e2ef866af95 88 buff[len] = (char)NULL;
JMF 0:9d5134074d84 89
JMF 0:9d5134074d84 90 return len;
JMF 0:9d5134074d84 91 }
JMF 0:9d5134074d84 92
JMF 0:9d5134074d84 93 int mdm_sendAtCmd(const char *cmd, const char **rsp_list, int timeout_ms) {
JMF 0:9d5134074d84 94 if (cmd && strlen(cmd) > 0) {
JMF 0:9d5134074d84 95 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 0:9d5134074d84 96 printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
JMF 0:9d5134074d84 97 }
JMF 0:9d5134074d84 98 mdm.printf("%s\r\n", cmd);
JMF 0:9d5134074d84 99 }
JMF 0:9d5134074d84 100
JMF 0:9d5134074d84 101 if (rsp_list) {
JMF 0:9d5134074d84 102 Timer timer;
JMF 0:9d5134074d84 103 char rsp[MAX_AT_RSP_LEN+1];
JMF 0:9d5134074d84 104 int len;
JMF 0:9d5134074d84 105
JMF 0:9d5134074d84 106 timer.start();
JMF 0:9d5134074d84 107 while (timer.read_ms() < timeout_ms) {
JMF 0:9d5134074d84 108 len = mdm_getline(rsp, sizeof(rsp), timeout_ms - timer.read_ms());
JMF 0:9d5134074d84 109
JMF 0:9d5134074d84 110 if (len < 0)
JMF 0:9d5134074d84 111 return MDM_ERR_TIMEOUT;
JMF 0:9d5134074d84 112
JMF 0:9d5134074d84 113 if (len == 0)
JMF 0:9d5134074d84 114 continue;
JMF 0:9d5134074d84 115
JMF 0:9d5134074d84 116 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 0:9d5134074d84 117 printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", rsp);
JMF 0:9d5134074d84 118 }
JMF 0:9d5134074d84 119
JMF 0:9d5134074d84 120 if (rsp_list) {
JMF 0:9d5134074d84 121 int rsp_idx = 0;
JMF 0:9d5134074d84 122 while (rsp_list[rsp_idx]) {
JMF 0:9d5134074d84 123 if (strcasecmp(rsp, rsp_list[rsp_idx]) == 0) {
JMF 0:9d5134074d84 124 return rsp_idx;
JMF 0:9d5134074d84 125 }
JMF 0:9d5134074d84 126 rsp_idx++;
JMF 0:9d5134074d84 127 }
JMF 0:9d5134074d84 128 }
JMF 0:9d5134074d84 129 }
JMF 0:9d5134074d84 130 return MDM_ERR_TIMEOUT;
JMF 0:9d5134074d84 131 }
JMF 0:9d5134074d84 132 return MDM_OK;
JMF 0:9d5134074d84 133 }
JMF 0:9d5134074d84 134
JMF 0:9d5134074d84 135 int mdm_init(void) {
JMF 0:9d5134074d84 136 // disable signal level translator
JMF 0:9d5134074d84 137 shield_3v3_1v8_sig_trans_ena = 0;
JMF 0:9d5134074d84 138
JMF 0:9d5134074d84 139 // power modem on //off
JMF 0:9d5134074d84 140 mdm_power_on = 0; //1;
JMF 0:9d5134074d84 141
JMF 0:9d5134074d84 142 // insure modem boots into normal operating mode
JMF 0:9d5134074d84 143 // and does not go to sleep when powered on
JMF 0:9d5134074d84 144 mdm_uart2_rx_boot_mode_sel = 1;
JMF 0:9d5134074d84 145 mdm_wakeup_in = 1;
JMF 0:9d5134074d84 146
JMF 0:9d5134074d84 147 // initialze comm with the modem
JMF 0:9d5134074d84 148 mdm.baud(115200);
JMF 2:0e2ef866af95 149 // clear out potential garbage
JMF 2:0e2ef866af95 150 while (mdm.readable())
JMF 2:0e2ef866af95 151 mdm.getc();
JMF 2:0e2ef866af95 152
JMF 0:9d5134074d84 153 mdm_uart1_cts = 0;
JMF 0:9d5134074d84 154
JMF 0:9d5134074d84 155 // enable the signal level translator to start
JMF 0:9d5134074d84 156 // modem reset process (modem will be powered down)
JMF 0:9d5134074d84 157 shield_3v3_1v8_sig_trans_ena = 1;
JMF 0:9d5134074d84 158
JMF 0:9d5134074d84 159 // Give the modem 60 secons to start responding by
JMF 0:9d5134074d84 160 // sending simple 'AT' commands to modem once per second.
JMF 0:9d5134074d84 161 Timer timer;
JMF 0:9d5134074d84 162 timer.start();
JMF 0:9d5134074d84 163 while (timer.read() < 60) {
JMF 0:9d5134074d84 164 const char * rsp_lst[] = { ok_str, error_str, NULL };
JMF 0:9d5134074d84 165 int rc = mdm_sendAtCmd("AT", rsp_lst, 500);
JMF 0:9d5134074d84 166 if (rc == 0)
JMF 0:9d5134074d84 167 return timer.read();
JMF 0:9d5134074d84 168 wait_ms(1000 - (timer.read_ms() % 1000));
JMF 0:9d5134074d84 169 pc.printf("\r%d",timer.read_ms()/1000);
JMF 0:9d5134074d84 170 }
JMF 0:9d5134074d84 171 return false;
JMF 0:9d5134074d84 172 }
JMF 0:9d5134074d84 173
JMF 2:0e2ef866af95 174 int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len) {
JMF 2:0e2ef866af95 175 static char cmd_buf[3200]; // Need enough room for the WNC sockreads (over 3000 chars)
fkellermavnet 6:713b4cbf1a7d 176 size_t n = strlen(cmd);
fkellermavnet 6:713b4cbf1a7d 177 if (cmd && n > 0) {
JMF 2:0e2ef866af95 178 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 2:0e2ef866af95 179 printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
JMF 2:0e2ef866af95 180 }
fkellermavnet 6:713b4cbf1a7d 181 while (n--) {
fkellermavnet 6:713b4cbf1a7d 182 mdm.putc(*cmd++);
fkellermavnet 6:713b4cbf1a7d 183 wait_ms(1);
fkellermavnet 6:713b4cbf1a7d 184 };
fkellermavnet 6:713b4cbf1a7d 185 mdm.putc('\r');
fkellermavnet 6:713b4cbf1a7d 186 wait_ms(1);
fkellermavnet 6:713b4cbf1a7d 187 mdm.putc('\n');
fkellermavnet 6:713b4cbf1a7d 188 wait_ms(1);
JMF 2:0e2ef866af95 189 }
JMF 2:0e2ef866af95 190
JMF 2:0e2ef866af95 191 if (rsp_list) {
JMF 2:0e2ef866af95 192 rsp->erase(); // Clean up from prior cmd response
JMF 2:0e2ef866af95 193 *len = 0;
JMF 2:0e2ef866af95 194 Timer timer;
JMF 2:0e2ef866af95 195 timer.start();
JMF 2:0e2ef866af95 196 while (timer.read_ms() < timeout_ms) {
JMF 2:0e2ef866af95 197 int lenCmd = mdm_getline(cmd_buf, sizeof(cmd_buf), timeout_ms - timer.read_ms());
JMF 2:0e2ef866af95 198
JMF 2:0e2ef866af95 199 if (lenCmd == 0)
JMF 2:0e2ef866af95 200 continue;
JMF 2:0e2ef866af95 201
JMF 2:0e2ef866af95 202 if (lenCmd < 0)
JMF 2:0e2ef866af95 203 return MDM_ERR_TIMEOUT;
JMF 2:0e2ef866af95 204 else {
JMF 2:0e2ef866af95 205 *len += lenCmd;
JMF 2:0e2ef866af95 206 *rsp += cmd_buf;
JMF 2:0e2ef866af95 207 }
JMF 2:0e2ef866af95 208
JMF 2:0e2ef866af95 209 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 2:0e2ef866af95 210 printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", cmd_buf);
JMF 2:0e2ef866af95 211 }
JMF 2:0e2ef866af95 212
JMF 2:0e2ef866af95 213 int rsp_idx = 0;
JMF 2:0e2ef866af95 214 while (rsp_list[rsp_idx]) {
JMF 2:0e2ef866af95 215 if (strcasecmp(cmd_buf, rsp_list[rsp_idx]) == 0) {
JMF 2:0e2ef866af95 216 return rsp_idx;
JMF 2:0e2ef866af95 217 }
JMF 2:0e2ef866af95 218 rsp_idx++;
JMF 2:0e2ef866af95 219 }
JMF 2:0e2ef866af95 220 }
JMF 2:0e2ef866af95 221 return MDM_ERR_TIMEOUT;
JMF 2:0e2ef866af95 222 }
JMF 2:0e2ef866af95 223 pc.printf("D %s",rsp);
JMF 2:0e2ef866af95 224 return MDM_OK;
JMF 2:0e2ef866af95 225 }
JMF 2:0e2ef866af95 226
JMF 2:0e2ef866af95 227 void reinitialize_mdm(void)
JMF 2:0e2ef866af95 228 {
JMF 2:0e2ef866af95 229 // Initialize the modem
JMF 2:0e2ef866af95 230 printf(GRN "Modem RE-initializing..." DEF "\r\n");
JMF 2:0e2ef866af95 231 if (!mdm_init()) {
JMF 2:0e2ef866af95 232 printf(RED "\n\rModem RE-initialization failed!" DEF "\n");
JMF 2:0e2ef866af95 233 }
JMF 2:0e2ef866af95 234 printf("\r\n");
JMF 2:0e2ef866af95 235 }
JMF 2:0e2ef866af95 236 // These are built on the fly
JMF 2:0e2ef866af95 237 string MyServerIpAddress;
JMF 2:0e2ef866af95 238 string MySocketData;
JMF 2:0e2ef866af95 239
JMF 2:0e2ef866af95 240 // These are to be built on the fly
JMF 2:0e2ef866af95 241 string my_temp;
JMF 2:0e2ef866af95 242 string my_humidity;
JMF 2:0e2ef866af95 243
JMF 0:9d5134074d84 244 #define CTOF(x) ((x)*1.8+32)
JMF 0:9d5134074d84 245
stefanrousseau 3:26b3cc155f39 246 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 247 //* Create string with sensor readings that can be sent to flow as an HTTP get
stefanrousseau 3:26b3cc155f39 248 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 249 K64F_Sensors_t SENSOR_DATA =
stefanrousseau 3:26b3cc155f39 250 {
stefanrousseau 12:7c94ec5069dc 251 .Temperature = "0",
stefanrousseau 12:7c94ec5069dc 252 .Humidity = "0",
stefanrousseau 12:7c94ec5069dc 253 .AccelX = "0",
stefanrousseau 12:7c94ec5069dc 254 .AccelY = "0",
stefanrousseau 12:7c94ec5069dc 255 .AccelZ = "0",
stefanrousseau 12:7c94ec5069dc 256 .MagnetometerX = "0",
stefanrousseau 12:7c94ec5069dc 257 .MagnetometerY = "0",
stefanrousseau 12:7c94ec5069dc 258 .MagnetometerZ = "0",
stefanrousseau 12:7c94ec5069dc 259 .AmbientLightVis = "0",
stefanrousseau 12:7c94ec5069dc 260 .AmbientLightIr = "0",
stefanrousseau 12:7c94ec5069dc 261 .UVindex = "0",
stefanrousseau 12:7c94ec5069dc 262 .Proximity = "0",
stefanrousseau 12:7c94ec5069dc 263 .Temperature_Si7020 = "0",
stefanrousseau 12:7c94ec5069dc 264 .Humidity_Si7020 = "0"
stefanrousseau 3:26b3cc155f39 265 };
stefanrousseau 12:7c94ec5069dc 266
stefanrousseau 3:26b3cc155f39 267 void GenerateModemString(char * modem_string)
stefanrousseau 3:26b3cc155f39 268 {
stefanrousseau 12:7c94ec5069dc 269 switch(iSensorsToReport)
stefanrousseau 12:7c94ec5069dc 270 {
stefanrousseau 12:7c94ec5069dc 271 case TEMP_HUMIDITY_ONLY:
stefanrousseau 12:7c94ec5069dc 272 {
stefanrousseau 12:7c94ec5069dc 273 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 274 break;
stefanrousseau 12:7c94ec5069dc 275 }
stefanrousseau 12:7c94ec5069dc 276 case TEMP_HUMIDITY_ACCELEROMETER:
stefanrousseau 12:7c94ec5069dc 277 {
stefanrousseau 12:7c94ec5069dc 278 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 279 break;
stefanrousseau 12:7c94ec5069dc 280 }
stefanrousseau 12:7c94ec5069dc 281 case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS:
stefanrousseau 12:7c94ec5069dc 282 {
stefanrousseau 12:7c94ec5069dc 283 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 284 break;
stefanrousseau 12:7c94ec5069dc 285 }
stefanrousseau 12:7c94ec5069dc 286 default:
stefanrousseau 12:7c94ec5069dc 287 {
stefanrousseau 12:7c94ec5069dc 288 sprintf(modem_string, "Invalid sensor selected\r\n\r\n");
stefanrousseau 12:7c94ec5069dc 289 break;
stefanrousseau 12:7c94ec5069dc 290 }
stefanrousseau 15:61df4a452d38 291 } //switch(iSensorsToReport)
stefanrousseau 3:26b3cc155f39 292 } //GenerateModemString
stefanrousseau 3:26b3cc155f39 293
stefanrousseau 3:26b3cc155f39 294
stefanrousseau 3:26b3cc155f39 295 //Periodic timer
stefanrousseau 3:26b3cc155f39 296 Ticker OneMsTicker;
stefanrousseau 3:26b3cc155f39 297 volatile bool bTimerExpiredFlag = false;
stefanrousseau 3:26b3cc155f39 298 int OneMsTicks = 0;
stefanrousseau 3:26b3cc155f39 299 int iTimer1Interval_ms = 1000;
stefanrousseau 3:26b3cc155f39 300 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 301 //* Periodic 1ms timer tick
stefanrousseau 3:26b3cc155f39 302 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 303 void OneMsFunction()
stefanrousseau 3:26b3cc155f39 304 {
stefanrousseau 3:26b3cc155f39 305 OneMsTicks++;
stefanrousseau 3:26b3cc155f39 306 if ((OneMsTicks % iTimer1Interval_ms) == 0)
stefanrousseau 3:26b3cc155f39 307 {
stefanrousseau 3:26b3cc155f39 308 bTimerExpiredFlag = true;
stefanrousseau 3:26b3cc155f39 309 }
stefanrousseau 3:26b3cc155f39 310 } //OneMsFunction()
stefanrousseau 3:26b3cc155f39 311
stefanrousseau 15:61df4a452d38 312 //********************************************************************************************************************************************
stefanrousseau 15:61df4a452d38 313 //* Set the RGB LED's Color
stefanrousseau 15:61df4a452d38 314 //* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue)
stefanrousseau 15:61df4a452d38 315 //********************************************************************************************************************************************
stefanrousseau 15:61df4a452d38 316 void SetLedColor(unsigned char ucColor)
stefanrousseau 15:61df4a452d38 317 {
stefanrousseau 15:61df4a452d38 318 //Note that when an LED is on, you write a 0 to it:
stefanrousseau 15:61df4a452d38 319 led_red = !(ucColor & 0x1); //bit 0
stefanrousseau 15:61df4a452d38 320 led_green = !(ucColor & 0x2); //bit 1
stefanrousseau 15:61df4a452d38 321 led_blue = !(ucColor & 0x4); //bit 2
stefanrousseau 15:61df4a452d38 322 } //SetLedColor()
stefanrousseau 15:61df4a452d38 323
stefanrousseau 15:61df4a452d38 324 //********************************************************************************************************************************************
stefanrousseau 15:61df4a452d38 325 //* Process JSON response messages
stefanrousseau 15:61df4a452d38 326 //********************************************************************************************************************************************
stefanrousseau 15:61df4a452d38 327 bool extract_JSON(char* search_field, char* found_string)
stefanrousseau 15:61df4a452d38 328 {
stefanrousseau 15:61df4a452d38 329 char* beginquote;
stefanrousseau 15:61df4a452d38 330 char* endquote;
stefanrousseau 15:61df4a452d38 331 beginquote = strchr(search_field, '{'); //start of JSON
stefanrousseau 15:61df4a452d38 332 endquote = strchr(search_field, '}'); //end of JSON
stefanrousseau 15:61df4a452d38 333 if (beginquote != 0)
stefanrousseau 15:61df4a452d38 334 {
stefanrousseau 15:61df4a452d38 335 uint16_t ifoundlen;
stefanrousseau 15:61df4a452d38 336 if (endquote != 0)
stefanrousseau 15:61df4a452d38 337 {
stefanrousseau 15:61df4a452d38 338 ifoundlen = (uint16_t) (endquote - beginquote) + 1;
stefanrousseau 15:61df4a452d38 339 strncpy(found_string, beginquote, ifoundlen );
stefanrousseau 15:61df4a452d38 340 found_string[ifoundlen] = 0; //null terminate
stefanrousseau 15:61df4a452d38 341 return true;
stefanrousseau 15:61df4a452d38 342 }
stefanrousseau 15:61df4a452d38 343 else
stefanrousseau 15:61df4a452d38 344 {
stefanrousseau 15:61df4a452d38 345 endquote = strchr(search_field, '\0'); //end of string... sometimes the end bracket is missing
stefanrousseau 15:61df4a452d38 346 ifoundlen = (uint16_t) (endquote - beginquote) + 1;
stefanrousseau 15:61df4a452d38 347 strncpy(found_string, beginquote, ifoundlen );
stefanrousseau 15:61df4a452d38 348 found_string[ifoundlen] = 0; //null terminate
stefanrousseau 15:61df4a452d38 349 return false;
stefanrousseau 15:61df4a452d38 350 }
stefanrousseau 15:61df4a452d38 351 }
stefanrousseau 15:61df4a452d38 352 else
stefanrousseau 15:61df4a452d38 353 {
stefanrousseau 15:61df4a452d38 354 return false;
stefanrousseau 15:61df4a452d38 355 }
stefanrousseau 15:61df4a452d38 356 } //extract_JSON
stefanrousseau 15:61df4a452d38 357
stefanrousseau 15:61df4a452d38 358 bool parse_JSON(char* json_string)
stefanrousseau 15:61df4a452d38 359 {
stefanrousseau 15:61df4a452d38 360 char* beginquote;
stefanrousseau 15:61df4a452d38 361 char token[] = "\"LED\":\"";
stefanrousseau 15:61df4a452d38 362 beginquote = strstr(json_string, token );
stefanrousseau 15:61df4a452d38 363 if ((beginquote != 0))
stefanrousseau 15:61df4a452d38 364 {
stefanrousseau 15:61df4a452d38 365 char cLedColor = beginquote[strlen(token)];
stefanrousseau 15:61df4a452d38 366 printf(GRN "LED Found : %c" DEF "\r\n", cLedColor);
stefanrousseau 15:61df4a452d38 367 switch(cLedColor)
stefanrousseau 15:61df4a452d38 368 {
stefanrousseau 15:61df4a452d38 369 case 'O':
stefanrousseau 15:61df4a452d38 370 { //Off
stefanrousseau 15:61df4a452d38 371 SetLedColor(0);
stefanrousseau 15:61df4a452d38 372 break;
stefanrousseau 15:61df4a452d38 373 }
stefanrousseau 15:61df4a452d38 374 case 'R':
stefanrousseau 15:61df4a452d38 375 { //Red
stefanrousseau 15:61df4a452d38 376 SetLedColor(1);
stefanrousseau 15:61df4a452d38 377 break;
stefanrousseau 15:61df4a452d38 378 }
stefanrousseau 15:61df4a452d38 379 case 'G':
stefanrousseau 15:61df4a452d38 380 { //Green
stefanrousseau 15:61df4a452d38 381 SetLedColor(2);
stefanrousseau 15:61df4a452d38 382 break;
stefanrousseau 15:61df4a452d38 383 }
stefanrousseau 15:61df4a452d38 384 case 'Y':
stefanrousseau 15:61df4a452d38 385 { //Yellow
stefanrousseau 15:61df4a452d38 386 SetLedColor(3);
stefanrousseau 15:61df4a452d38 387 break;
stefanrousseau 15:61df4a452d38 388 }
stefanrousseau 15:61df4a452d38 389 case 'B':
stefanrousseau 15:61df4a452d38 390 { //Blue
stefanrousseau 15:61df4a452d38 391 SetLedColor(4);
stefanrousseau 15:61df4a452d38 392 break;
stefanrousseau 15:61df4a452d38 393 }
stefanrousseau 15:61df4a452d38 394 case 'M':
stefanrousseau 15:61df4a452d38 395 { //Magenta
stefanrousseau 15:61df4a452d38 396 SetLedColor(5);
stefanrousseau 15:61df4a452d38 397 break;
stefanrousseau 15:61df4a452d38 398 }
stefanrousseau 15:61df4a452d38 399 case 'T':
stefanrousseau 15:61df4a452d38 400 { //Turquoise
stefanrousseau 15:61df4a452d38 401 SetLedColor(6);
stefanrousseau 15:61df4a452d38 402 break;
stefanrousseau 15:61df4a452d38 403 }
stefanrousseau 15:61df4a452d38 404 case 'W':
stefanrousseau 15:61df4a452d38 405 { //White
stefanrousseau 15:61df4a452d38 406 SetLedColor(7);
stefanrousseau 15:61df4a452d38 407 break;
stefanrousseau 15:61df4a452d38 408 }
stefanrousseau 15:61df4a452d38 409 default:
stefanrousseau 15:61df4a452d38 410 {
stefanrousseau 15:61df4a452d38 411 break;
stefanrousseau 15:61df4a452d38 412 }
stefanrousseau 15:61df4a452d38 413 } //switch(cLedColor)
stefanrousseau 15:61df4a452d38 414 return true;
stefanrousseau 15:61df4a452d38 415 }
stefanrousseau 15:61df4a452d38 416 else
stefanrousseau 15:61df4a452d38 417 {
stefanrousseau 15:61df4a452d38 418 return false;
stefanrousseau 15:61df4a452d38 419 }
stefanrousseau 15:61df4a452d38 420 } //parse_JSON
stefanrousseau 15:61df4a452d38 421
JMF 0:9d5134074d84 422 int main() {
JMF 2:0e2ef866af95 423 int i;
JMF 0:9d5134074d84 424 HTS221 hts221;
JMF 0:9d5134074d84 425 pc.baud(115200);
JMF 0:9d5134074d84 426
JMF 0:9d5134074d84 427 void hts221_init(void);
JMF 0:9d5134074d84 428
JMF 1:af7a42f7d465 429 pc.printf(BLU "Hello World from AT&T Shape!\r\n\n\r");
JMF 0:9d5134074d84 430 pc.printf(GRN "Initialize the HTS221\n\r");
JMF 0:9d5134074d84 431
JMF 0:9d5134074d84 432 i = hts221.begin();
JMF 0:9d5134074d84 433 if( i )
JMF 0:9d5134074d84 434 pc.printf(BLU "HTS221 Detected! (0x%02X)\n\r",i);
JMF 0:9d5134074d84 435 else
JMF 0:9d5134074d84 436 pc.printf(RED "HTS221 NOT DETECTED!!\n\r");
JMF 0:9d5134074d84 437
JMF 0:9d5134074d84 438 printf("Temp is: %0.2f F \n\r",CTOF(hts221.readTemperature()));
JMF 0:9d5134074d84 439 printf("Humid is: %02d %%\n\r",hts221.readHumidity());
JMF 0:9d5134074d84 440
stefanrousseau 11:e6602513730f 441 sensors_init();
stefanrousseau 12:7c94ec5069dc 442 read_sensors();
stefanrousseau 11:e6602513730f 443
JMF 0:9d5134074d84 444 // Initialize the modem
JMF 0:9d5134074d84 445 printf(GRN "Modem initializing... will take up to 60 seconds" DEF "\r\n");
JMF 0:9d5134074d84 446 i=mdm_init();
JMF 0:9d5134074d84 447 if (!i) {
JMF 0:9d5134074d84 448 pc.printf(RED "Modem initialization failed!" DEF "\n");
JMF 0:9d5134074d84 449 while (1);
JMF 0:9d5134074d84 450 }
JMF 0:9d5134074d84 451
JMF 2:0e2ef866af95 452 //Software init
JMF 2:0e2ef866af95 453 software_init_mdm();
JMF 2:0e2ef866af95 454
JMF 2:0e2ef866af95 455 // Resolve URL to IP address to connect to
JMF 2:0e2ef866af95 456 resolve_mdm();
JMF 0:9d5134074d84 457
stefanrousseau 3:26b3cc155f39 458 //Create a 1ms timer tick function:
stefanrousseau 3:26b3cc155f39 459 OneMsTicker.attach(OneMsFunction, 0.001f) ;
stefanrousseau 3:26b3cc155f39 460 iTimer1Interval_ms = 5000; //5 seconds
stefanrousseau 3:26b3cc155f39 461
JMF 2:0e2ef866af95 462 // Send and receive data perpetually
JMF 2:0e2ef866af95 463 while(1) {
stefanrousseau 3:26b3cc155f39 464 if (bTimerExpiredFlag)
stefanrousseau 3:26b3cc155f39 465 {
stefanrousseau 3:26b3cc155f39 466 bTimerExpiredFlag = false;
stefanrousseau 3:26b3cc155f39 467 sprintf(SENSOR_DATA.Temperature, "%0.2f", CTOF(hts221.readTemperature()));
stefanrousseau 3:26b3cc155f39 468 sprintf(SENSOR_DATA.Humidity, "%02d", hts221.readHumidity());
stefanrousseau 4:f83bedd9cab4 469 read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor
stefanrousseau 3:26b3cc155f39 470 sockopen_mdm();
stefanrousseau 3:26b3cc155f39 471 char modem_string[512];
stefanrousseau 3:26b3cc155f39 472 GenerateModemString(&modem_string[0]);
stefanrousseau 15:61df4a452d38 473 printf(BLU "Sending to modem : %s" DEF "\n", modem_string);
stefanrousseau 3:26b3cc155f39 474 sockwrite_mdm(modem_string);
stefanrousseau 3:26b3cc155f39 475 sockread_mdm(&MySocketData, 1024, 20);
stefanrousseau 15:61df4a452d38 476 printf(BLU "Read back : %s" DEF "\n", &MySocketData[0]);
stefanrousseau 15:61df4a452d38 477 char * myJsonResponse;
stefanrousseau 15:61df4a452d38 478 if (extract_JSON(&MySocketData[0], &myJsonResponse[0]))
stefanrousseau 15:61df4a452d38 479 {
stefanrousseau 15:61df4a452d38 480 printf(GRN "JSON : %s" DEF "\n", &myJsonResponse[0]);
stefanrousseau 15:61df4a452d38 481 parse_JSON(&myJsonResponse[0]);
stefanrousseau 15:61df4a452d38 482 }
stefanrousseau 15:61df4a452d38 483 else
stefanrousseau 15:61df4a452d38 484 {
stefanrousseau 15:61df4a452d38 485 printf(RED "JSON : %s" DEF "\n", &myJsonResponse[0]); //most likely an incomplete JSON string
stefanrousseau 15:61df4a452d38 486 parse_JSON(&myJsonResponse[0]); //This is risky, as the string may be corrupted
stefanrousseau 15:61df4a452d38 487 }
stefanrousseau 3:26b3cc155f39 488 sockclose_mdm();
stefanrousseau 3:26b3cc155f39 489 } //bTimerExpiredFlag
stefanrousseau 3:26b3cc155f39 490 } //forever loop
JMF 2:0e2ef866af95 491
stefanrousseau 12:7c94ec5069dc 492 #if (0)
JMF 2:0e2ef866af95 493 string * pStr;
JMF 2:0e2ef866af95 494 while (1)
JMF 2:0e2ef866af95 495 {
JMF 2:0e2ef866af95 496 send_wnc_cmd("AT", &pStr, WNC_TIMEOUT_MS);
JMF 0:9d5134074d84 497 }
stefanrousseau 12:7c94ec5069dc 498 #endif
JMF 0:9d5134074d84 499 }