The Hiking Pal tracking device firmware. See full description on the detail page: https://www.hackster.io/bowenfeng/hiking-pal-v1-07c02d

Dependencies:   FXOS8700CQ MODSERIAL mbed

Fork of Avnet_ATT_Cellular_IOT by Avnet

Committer:
stefanrousseau
Date:
Thu Jul 28 17:21:31 2016 +0000
Revision:
56:cb42ff383dab
Parent:
55:3abf9e3f42e6
Child:
59:7ebb9436b2bd
Changes USB UART to use MODSERIAL library

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 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
fkellermavnet 33:fa964b8b3b19 41 #define WNC_WAIT_FOR_AT_CMD_MS 40
fkellermavnet 33:fa964b8b3b19 42
stefanrousseau 56:cb42ff383dab 43 //Serial pc(USBTX, USBRX);
stefanrousseau 56:cb42ff383dab 44 MODSERIAL pc(USBTX, USBRX, 256, 256); // tx, rx with default tx, rx buffer sizes
stefanrousseau 56:cb42ff383dab 45
fkellermavnet 38:564b312a719f 46 SerialBuffered mdm(PTD3, PTD2, 4096);
stefanrousseau 16:17c5916f2d12 47 DigitalOut led_green(LED_GREEN);
stefanrousseau 16:17c5916f2d12 48 DigitalOut led_red(LED_RED);
stefanrousseau 16:17c5916f2d12 49 DigitalOut led_blue(LED_BLUE);
JMF 0:9d5134074d84 50
JMF 0:9d5134074d84 51 DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot
JMF 0:9d5134074d84 52 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 53 DigitalOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield
JMF 0:9d5134074d84 54
fkellermavnet 14:0c353e212296 55 DigitalOut mdm_reset(PTC12); // active high
fkellermavnet 14:0c353e212296 56
JMF 0:9d5134074d84 57 DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active
JMF 0:9d5134074d84 58 DigitalOut mdm_uart1_cts(PTD0);
JMF 0:9d5134074d84 59
JMF 0:9d5134074d84 60 #define TOUPPER(a) (a) //toupper(a)
JMF 0:9d5134074d84 61
JMF 0:9d5134074d84 62 const char ok_str[] = "OK";
JMF 0:9d5134074d84 63 const char error_str[] = "ERROR";
JMF 0:9d5134074d84 64
JMF 0:9d5134074d84 65 #define MDM_OK 0
JMF 0:9d5134074d84 66 #define MDM_ERR_TIMEOUT -1
JMF 0:9d5134074d84 67
JMF 0:9d5134074d84 68 #define MAX_AT_RSP_LEN 255
JMF 0:9d5134074d84 69
JMF 0:9d5134074d84 70 ssize_t mdm_getline(char *buff, size_t size, int timeout_ms) {
JMF 0:9d5134074d84 71 int cin = -1;
JMF 0:9d5134074d84 72 int cin_last;
JMF 0:9d5134074d84 73
JMF 0:9d5134074d84 74 if (NULL == buff || size == 0) {
JMF 0:9d5134074d84 75 return -1;
JMF 0:9d5134074d84 76 }
JMF 0:9d5134074d84 77
JMF 0:9d5134074d84 78 size_t len = 0;
JMF 0:9d5134074d84 79 Timer timer;
JMF 0:9d5134074d84 80 timer.start();
JMF 0:9d5134074d84 81 while ((len < (size-1)) && (timer.read_ms() < timeout_ms)) {
JMF 0:9d5134074d84 82 if (mdm.readable()) {
JMF 0:9d5134074d84 83 cin_last = cin;
JMF 0:9d5134074d84 84 cin = mdm.getc();
JMF 0:9d5134074d84 85 if (isprint(cin)) {
JMF 0:9d5134074d84 86 buff[len++] = (char)cin;
JMF 0:9d5134074d84 87 continue;
JMF 0:9d5134074d84 88 } else if (('\r' == cin_last) && ('\n' == cin)) {
JMF 0:9d5134074d84 89 break;
JMF 0:9d5134074d84 90 }
JMF 0:9d5134074d84 91 }
fkellermavnet 32:1e052a3e73fe 92 // wait_ms(1);
JMF 0:9d5134074d84 93 }
JMF 2:0e2ef866af95 94 buff[len] = (char)NULL;
JMF 0:9d5134074d84 95
JMF 0:9d5134074d84 96 return len;
JMF 0:9d5134074d84 97 }
JMF 0:9d5134074d84 98
JMF 0:9d5134074d84 99 int mdm_sendAtCmd(const char *cmd, const char **rsp_list, int timeout_ms) {
fkellermavnet 32:1e052a3e73fe 100 // Per WNC wait:
fkellermavnet 33:fa964b8b3b19 101 wait_ms(WNC_WAIT_FOR_AT_CMD_MS);
fkellermavnet 32:1e052a3e73fe 102
JMF 0:9d5134074d84 103 if (cmd && strlen(cmd) > 0) {
JMF 0:9d5134074d84 104 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 0:9d5134074d84 105 printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
JMF 0:9d5134074d84 106 }
fkellermavnet 32:1e052a3e73fe 107 mdm.puts(cmd);
fkellermavnet 32:1e052a3e73fe 108 mdm.puts("\r\n");
JMF 0:9d5134074d84 109 }
fkellermavnet 32:1e052a3e73fe 110
JMF 0:9d5134074d84 111 if (rsp_list) {
JMF 0:9d5134074d84 112 Timer timer;
JMF 0:9d5134074d84 113 char rsp[MAX_AT_RSP_LEN+1];
JMF 0:9d5134074d84 114 int len;
JMF 0:9d5134074d84 115
JMF 0:9d5134074d84 116 timer.start();
JMF 0:9d5134074d84 117 while (timer.read_ms() < timeout_ms) {
JMF 0:9d5134074d84 118 len = mdm_getline(rsp, sizeof(rsp), timeout_ms - timer.read_ms());
JMF 0:9d5134074d84 119
JMF 0:9d5134074d84 120 if (len < 0)
JMF 0:9d5134074d84 121 return MDM_ERR_TIMEOUT;
JMF 0:9d5134074d84 122
JMF 0:9d5134074d84 123 if (len == 0)
JMF 0:9d5134074d84 124 continue;
JMF 0:9d5134074d84 125
JMF 0:9d5134074d84 126 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 0:9d5134074d84 127 printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", rsp);
JMF 0:9d5134074d84 128 }
JMF 0:9d5134074d84 129
JMF 0:9d5134074d84 130 if (rsp_list) {
JMF 0:9d5134074d84 131 int rsp_idx = 0;
JMF 0:9d5134074d84 132 while (rsp_list[rsp_idx]) {
JMF 0:9d5134074d84 133 if (strcasecmp(rsp, rsp_list[rsp_idx]) == 0) {
JMF 0:9d5134074d84 134 return rsp_idx;
JMF 0:9d5134074d84 135 }
JMF 0:9d5134074d84 136 rsp_idx++;
JMF 0:9d5134074d84 137 }
JMF 0:9d5134074d84 138 }
JMF 0:9d5134074d84 139 }
JMF 0:9d5134074d84 140 return MDM_ERR_TIMEOUT;
JMF 0:9d5134074d84 141 }
JMF 0:9d5134074d84 142 return MDM_OK;
JMF 0:9d5134074d84 143 }
JMF 0:9d5134074d84 144
JMF 0:9d5134074d84 145 int mdm_init(void) {
fkellermavnet 14:0c353e212296 146 // Hard reset the modem (doesn't go through
fkellermavnet 14:0c353e212296 147 // the signal level translator)
fkellermavnet 14:0c353e212296 148 mdm_reset = 0;
JMF 17:38a8cc0c6ba5 149
JMF 17:38a8cc0c6ba5 150 // disable signal level translator (necessary
JMF 17:38a8cc0c6ba5 151 // for the modem to boot properly). All signals
JMF 17:38a8cc0c6ba5 152 // except mdm_reset go through the level translator
JMF 17:38a8cc0c6ba5 153 // and have internal pull-up/down in the module. While
JMF 17:38a8cc0c6ba5 154 // the level translator is disabled, these pins will
JMF 17:38a8cc0c6ba5 155 // be in the correct state.
JMF 17:38a8cc0c6ba5 156 shield_3v3_1v8_sig_trans_ena = 0;
JMF 17:38a8cc0c6ba5 157
JMF 17:38a8cc0c6ba5 158 // While the level translator is disabled and ouptut pins
JMF 17:38a8cc0c6ba5 159 // are tristated, make sure the inputs are in the same state
JMF 17:38a8cc0c6ba5 160 // as the WNC Module pins so that when the level translator is
JMF 17:38a8cc0c6ba5 161 // enabled, there are no differences.
JMF 17:38a8cc0c6ba5 162 mdm_uart2_rx_boot_mode_sel = 1; // UART2_RX should be high
JMF 17:38a8cc0c6ba5 163 mdm_power_on = 0; // powr_on should be low
JMF 17:38a8cc0c6ba5 164 mdm_wakeup_in = 1; // wake-up should be high
JMF 17:38a8cc0c6ba5 165 mdm_uart1_cts = 0; // indicate that it is ok to send
JMF 17:38a8cc0c6ba5 166
JMF 17:38a8cc0c6ba5 167 // Now, wait for the WNC Module to perform its initial boot correctly
fkellermavnet 14:0c353e212296 168 wait(1.0);
JMF 17:38a8cc0c6ba5 169
JMF 17:38a8cc0c6ba5 170 // The WNC module initializes comms at 115200 8N1 so set it up
JMF 17:38a8cc0c6ba5 171 mdm.baud(115200);
JMF 0:9d5134074d84 172
JMF 17:38a8cc0c6ba5 173 //Now, enable the level translator, the input pins should now be the
JMF 17:38a8cc0c6ba5 174 //same as how the M14A module is driving them with internal pull ups/downs.
JMF 17:38a8cc0c6ba5 175 //When enabled, there will be no changes in these 4 pins...
JMF 17:38a8cc0c6ba5 176 shield_3v3_1v8_sig_trans_ena = 1;
JMF 2:0e2ef866af95 177
fkellermavnet 53:dcccf2881fa0 178 // Now, give the modem 60 seconds to start responding by
JMF 0:9d5134074d84 179 // sending simple 'AT' commands to modem once per second.
JMF 0:9d5134074d84 180 Timer timer;
JMF 0:9d5134074d84 181 timer.start();
JMF 0:9d5134074d84 182 while (timer.read() < 60) {
JMF 0:9d5134074d84 183 const char * rsp_lst[] = { ok_str, error_str, NULL };
JMF 0:9d5134074d84 184 int rc = mdm_sendAtCmd("AT", rsp_lst, 500);
JMF 0:9d5134074d84 185 if (rc == 0)
fkellermavnet 14:0c353e212296 186 return true; //timer.read();
JMF 0:9d5134074d84 187 wait_ms(1000 - (timer.read_ms() % 1000));
JMF 0:9d5134074d84 188 pc.printf("\r%d",timer.read_ms()/1000);
JMF 0:9d5134074d84 189 }
JMF 0:9d5134074d84 190 return false;
JMF 0:9d5134074d84 191 }
JMF 0:9d5134074d84 192
JMF 2:0e2ef866af95 193 int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len) {
JMF 2:0e2ef866af95 194 static char cmd_buf[3200]; // Need enough room for the WNC sockreads (over 3000 chars)
fkellermavnet 6:713b4cbf1a7d 195 size_t n = strlen(cmd);
fkellermavnet 32:1e052a3e73fe 196
fkellermavnet 32:1e052a3e73fe 197 // Per WNC wait:
fkellermavnet 33:fa964b8b3b19 198 wait_ms(WNC_WAIT_FOR_AT_CMD_MS);
fkellermavnet 32:1e052a3e73fe 199
fkellermavnet 6:713b4cbf1a7d 200 if (cmd && n > 0) {
JMF 2:0e2ef866af95 201 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 2:0e2ef866af95 202 printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
JMF 2:0e2ef866af95 203 }
fkellermavnet 43:6821a9c78c4b 204 // mdm.puts(cmd);
fkellermavnet 43:6821a9c78c4b 205 // mdm.puts("\r\n");
fkellermavnet 43:6821a9c78c4b 206 while (n--) {
fkellermavnet 43:6821a9c78c4b 207 mdm.putc(*cmd++);
fkellermavnet 43:6821a9c78c4b 208 wait_us(1000);
fkellermavnet 43:6821a9c78c4b 209 };
fkellermavnet 43:6821a9c78c4b 210 mdm.putc('\r');
fkellermavnet 43:6821a9c78c4b 211 wait_us(1000);
fkellermavnet 43:6821a9c78c4b 212 mdm.putc('\n');
fkellermavnet 43:6821a9c78c4b 213 wait_us(1000);
JMF 2:0e2ef866af95 214 }
JMF 2:0e2ef866af95 215
JMF 2:0e2ef866af95 216 if (rsp_list) {
JMF 2:0e2ef866af95 217 rsp->erase(); // Clean up from prior cmd response
JMF 2:0e2ef866af95 218 *len = 0;
JMF 2:0e2ef866af95 219 Timer timer;
JMF 2:0e2ef866af95 220 timer.start();
JMF 2:0e2ef866af95 221 while (timer.read_ms() < timeout_ms) {
JMF 2:0e2ef866af95 222 int lenCmd = mdm_getline(cmd_buf, sizeof(cmd_buf), timeout_ms - timer.read_ms());
JMF 2:0e2ef866af95 223
JMF 2:0e2ef866af95 224 if (lenCmd == 0)
JMF 2:0e2ef866af95 225 continue;
JMF 2:0e2ef866af95 226
JMF 2:0e2ef866af95 227 if (lenCmd < 0)
JMF 2:0e2ef866af95 228 return MDM_ERR_TIMEOUT;
JMF 2:0e2ef866af95 229 else {
JMF 2:0e2ef866af95 230 *len += lenCmd;
JMF 2:0e2ef866af95 231 *rsp += cmd_buf;
JMF 2:0e2ef866af95 232 }
JMF 2:0e2ef866af95 233
JMF 2:0e2ef866af95 234 if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
JMF 2:0e2ef866af95 235 printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", cmd_buf);
JMF 2:0e2ef866af95 236 }
JMF 2:0e2ef866af95 237
JMF 2:0e2ef866af95 238 int rsp_idx = 0;
JMF 2:0e2ef866af95 239 while (rsp_list[rsp_idx]) {
JMF 2:0e2ef866af95 240 if (strcasecmp(cmd_buf, rsp_list[rsp_idx]) == 0) {
JMF 2:0e2ef866af95 241 return rsp_idx;
JMF 2:0e2ef866af95 242 }
JMF 2:0e2ef866af95 243 rsp_idx++;
JMF 2:0e2ef866af95 244 }
JMF 2:0e2ef866af95 245 }
JMF 2:0e2ef866af95 246 return MDM_ERR_TIMEOUT;
JMF 2:0e2ef866af95 247 }
fkellermavnet 53:dcccf2881fa0 248
JMF 2:0e2ef866af95 249 return MDM_OK;
JMF 2:0e2ef866af95 250 }
JMF 2:0e2ef866af95 251
JMF 2:0e2ef866af95 252 void reinitialize_mdm(void)
JMF 2:0e2ef866af95 253 {
JMF 2:0e2ef866af95 254 // Initialize the modem
JMF 2:0e2ef866af95 255 printf(GRN "Modem RE-initializing..." DEF "\r\n");
JMF 2:0e2ef866af95 256 if (!mdm_init()) {
JMF 2:0e2ef866af95 257 printf(RED "\n\rModem RE-initialization failed!" DEF "\n");
JMF 2:0e2ef866af95 258 }
JMF 2:0e2ef866af95 259 printf("\r\n");
JMF 2:0e2ef866af95 260 }
JMF 2:0e2ef866af95 261 // These are built on the fly
JMF 2:0e2ef866af95 262 string MyServerIpAddress;
JMF 2:0e2ef866af95 263 string MySocketData;
JMF 2:0e2ef866af95 264
JMF 2:0e2ef866af95 265 // These are to be built on the fly
JMF 2:0e2ef866af95 266 string my_temp;
JMF 2:0e2ef866af95 267 string my_humidity;
JMF 2:0e2ef866af95 268
JMF 0:9d5134074d84 269 #define CTOF(x) ((x)*1.8+32)
JMF 0:9d5134074d84 270
stefanrousseau 3:26b3cc155f39 271 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 272 //* Create string with sensor readings that can be sent to flow as an HTTP get
stefanrousseau 3:26b3cc155f39 273 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 274 K64F_Sensors_t SENSOR_DATA =
stefanrousseau 3:26b3cc155f39 275 {
stefanrousseau 12:7c94ec5069dc 276 .Temperature = "0",
stefanrousseau 12:7c94ec5069dc 277 .Humidity = "0",
stefanrousseau 12:7c94ec5069dc 278 .AccelX = "0",
stefanrousseau 12:7c94ec5069dc 279 .AccelY = "0",
stefanrousseau 12:7c94ec5069dc 280 .AccelZ = "0",
stefanrousseau 12:7c94ec5069dc 281 .MagnetometerX = "0",
stefanrousseau 12:7c94ec5069dc 282 .MagnetometerY = "0",
stefanrousseau 12:7c94ec5069dc 283 .MagnetometerZ = "0",
stefanrousseau 12:7c94ec5069dc 284 .AmbientLightVis = "0",
stefanrousseau 12:7c94ec5069dc 285 .AmbientLightIr = "0",
stefanrousseau 12:7c94ec5069dc 286 .UVindex = "0",
stefanrousseau 12:7c94ec5069dc 287 .Proximity = "0",
stefanrousseau 12:7c94ec5069dc 288 .Temperature_Si7020 = "0",
stefanrousseau 55:3abf9e3f42e6 289 .Humidity_Si7020 = "0",
stefanrousseau 55:3abf9e3f42e6 290 .Virtual_Sensor1 = "0",
stefanrousseau 55:3abf9e3f42e6 291 .Virtual_Sensor2 = "0",
stefanrousseau 55:3abf9e3f42e6 292 .Virtual_Sensor3 = "0",
stefanrousseau 55:3abf9e3f42e6 293 .Virtual_Sensor4 = "0",
stefanrousseau 55:3abf9e3f42e6 294 .Virtual_Sensor5 = "0",
stefanrousseau 55:3abf9e3f42e6 295 .Virtual_Sensor6 = "0",
stefanrousseau 55:3abf9e3f42e6 296 .Virtual_Sensor7 = "0",
stefanrousseau 55:3abf9e3f42e6 297 .Virtual_Sensor8 = "0"
stefanrousseau 3:26b3cc155f39 298 };
stefanrousseau 12:7c94ec5069dc 299
stefanrousseau 3:26b3cc155f39 300 void GenerateModemString(char * modem_string)
stefanrousseau 3:26b3cc155f39 301 {
stefanrousseau 12:7c94ec5069dc 302 switch(iSensorsToReport)
stefanrousseau 12:7c94ec5069dc 303 {
stefanrousseau 12:7c94ec5069dc 304 case TEMP_HUMIDITY_ONLY:
stefanrousseau 12:7c94ec5069dc 305 {
stefanrousseau 12:7c94ec5069dc 306 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 307 break;
stefanrousseau 12:7c94ec5069dc 308 }
stefanrousseau 12:7c94ec5069dc 309 case TEMP_HUMIDITY_ACCELEROMETER:
stefanrousseau 12:7c94ec5069dc 310 {
stefanrousseau 12:7c94ec5069dc 311 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 312 break;
stefanrousseau 12:7c94ec5069dc 313 }
stefanrousseau 12:7c94ec5069dc 314 case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS:
stefanrousseau 12:7c94ec5069dc 315 {
stefanrousseau 12:7c94ec5069dc 316 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 317 break;
stefanrousseau 12:7c94ec5069dc 318 }
stefanrousseau 55:3abf9e3f42e6 319 case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS_VIRTUALSENSORS:
stefanrousseau 55:3abf9e3f42e6 320 {
stefanrousseau 55:3abf9e3f42e6 321 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 322 break;
stefanrousseau 55:3abf9e3f42e6 323 }
stefanrousseau 12:7c94ec5069dc 324 default:
stefanrousseau 12:7c94ec5069dc 325 {
stefanrousseau 12:7c94ec5069dc 326 sprintf(modem_string, "Invalid sensor selected\r\n\r\n");
stefanrousseau 12:7c94ec5069dc 327 break;
stefanrousseau 12:7c94ec5069dc 328 }
stefanrousseau 16:17c5916f2d12 329 } //switch(iSensorsToReport)
stefanrousseau 3:26b3cc155f39 330 } //GenerateModemString
stefanrousseau 3:26b3cc155f39 331
stefanrousseau 3:26b3cc155f39 332
stefanrousseau 3:26b3cc155f39 333 //Periodic timer
stefanrousseau 3:26b3cc155f39 334 Ticker OneMsTicker;
stefanrousseau 3:26b3cc155f39 335 volatile bool bTimerExpiredFlag = false;
stefanrousseau 3:26b3cc155f39 336 int OneMsTicks = 0;
stefanrousseau 3:26b3cc155f39 337 int iTimer1Interval_ms = 1000;
stefanrousseau 3:26b3cc155f39 338 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 339 //* Periodic 1ms timer tick
stefanrousseau 3:26b3cc155f39 340 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 341 void OneMsFunction()
stefanrousseau 3:26b3cc155f39 342 {
stefanrousseau 3:26b3cc155f39 343 OneMsTicks++;
stefanrousseau 3:26b3cc155f39 344 if ((OneMsTicks % iTimer1Interval_ms) == 0)
stefanrousseau 3:26b3cc155f39 345 {
stefanrousseau 3:26b3cc155f39 346 bTimerExpiredFlag = true;
stefanrousseau 3:26b3cc155f39 347 }
stefanrousseau 3:26b3cc155f39 348 } //OneMsFunction()
stefanrousseau 3:26b3cc155f39 349
stefanrousseau 16:17c5916f2d12 350 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 351 //* Set the RGB LED's Color
stefanrousseau 16:17c5916f2d12 352 //* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue)
stefanrousseau 16:17c5916f2d12 353 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 354 void SetLedColor(unsigned char ucColor)
stefanrousseau 16:17c5916f2d12 355 {
stefanrousseau 16:17c5916f2d12 356 //Note that when an LED is on, you write a 0 to it:
stefanrousseau 16:17c5916f2d12 357 led_red = !(ucColor & 0x1); //bit 0
stefanrousseau 16:17c5916f2d12 358 led_green = !(ucColor & 0x2); //bit 1
stefanrousseau 16:17c5916f2d12 359 led_blue = !(ucColor & 0x4); //bit 2
stefanrousseau 16:17c5916f2d12 360 } //SetLedColor()
stefanrousseau 16:17c5916f2d12 361
stefanrousseau 16:17c5916f2d12 362 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 363 //* Process JSON response messages
stefanrousseau 16:17c5916f2d12 364 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 365 bool extract_JSON(char* search_field, char* found_string)
stefanrousseau 16:17c5916f2d12 366 {
stefanrousseau 16:17c5916f2d12 367 char* beginquote;
stefanrousseau 16:17c5916f2d12 368 char* endquote;
stefanrousseau 16:17c5916f2d12 369 beginquote = strchr(search_field, '{'); //start of JSON
stefanrousseau 16:17c5916f2d12 370 endquote = strchr(search_field, '}'); //end of JSON
stefanrousseau 41:9b14c40eebf6 371 if (beginquote)
stefanrousseau 16:17c5916f2d12 372 {
stefanrousseau 16:17c5916f2d12 373 uint16_t ifoundlen;
stefanrousseau 41:9b14c40eebf6 374 if (endquote)
stefanrousseau 16:17c5916f2d12 375 {
stefanrousseau 16:17c5916f2d12 376 ifoundlen = (uint16_t) (endquote - beginquote) + 1;
stefanrousseau 16:17c5916f2d12 377 strncpy(found_string, beginquote, ifoundlen );
stefanrousseau 16:17c5916f2d12 378 found_string[ifoundlen] = 0; //null terminate
stefanrousseau 16:17c5916f2d12 379 return true;
stefanrousseau 16:17c5916f2d12 380 }
stefanrousseau 16:17c5916f2d12 381 else
stefanrousseau 16:17c5916f2d12 382 {
stefanrousseau 16:17c5916f2d12 383 endquote = strchr(search_field, '\0'); //end of string... sometimes the end bracket is missing
stefanrousseau 16:17c5916f2d12 384 ifoundlen = (uint16_t) (endquote - beginquote) + 1;
stefanrousseau 16:17c5916f2d12 385 strncpy(found_string, beginquote, ifoundlen );
stefanrousseau 16:17c5916f2d12 386 found_string[ifoundlen] = 0; //null terminate
stefanrousseau 16:17c5916f2d12 387 return false;
stefanrousseau 16:17c5916f2d12 388 }
stefanrousseau 16:17c5916f2d12 389 }
stefanrousseau 16:17c5916f2d12 390 else
stefanrousseau 16:17c5916f2d12 391 {
stefanrousseau 16:17c5916f2d12 392 return false;
stefanrousseau 16:17c5916f2d12 393 }
stefanrousseau 16:17c5916f2d12 394 } //extract_JSON
stefanrousseau 16:17c5916f2d12 395
stefanrousseau 16:17c5916f2d12 396 bool parse_JSON(char* json_string)
stefanrousseau 16:17c5916f2d12 397 {
stefanrousseau 16:17c5916f2d12 398 char* beginquote;
stefanrousseau 16:17c5916f2d12 399 char token[] = "\"LED\":\"";
stefanrousseau 16:17c5916f2d12 400 beginquote = strstr(json_string, token );
stefanrousseau 16:17c5916f2d12 401 if ((beginquote != 0))
stefanrousseau 16:17c5916f2d12 402 {
stefanrousseau 16:17c5916f2d12 403 char cLedColor = beginquote[strlen(token)];
stefanrousseau 16:17c5916f2d12 404 printf(GRN "LED Found : %c" DEF "\r\n", cLedColor);
stefanrousseau 16:17c5916f2d12 405 switch(cLedColor)
stefanrousseau 16:17c5916f2d12 406 {
stefanrousseau 16:17c5916f2d12 407 case 'O':
stefanrousseau 16:17c5916f2d12 408 { //Off
stefanrousseau 16:17c5916f2d12 409 SetLedColor(0);
stefanrousseau 16:17c5916f2d12 410 break;
stefanrousseau 16:17c5916f2d12 411 }
stefanrousseau 16:17c5916f2d12 412 case 'R':
stefanrousseau 16:17c5916f2d12 413 { //Red
stefanrousseau 16:17c5916f2d12 414 SetLedColor(1);
stefanrousseau 16:17c5916f2d12 415 break;
stefanrousseau 16:17c5916f2d12 416 }
stefanrousseau 16:17c5916f2d12 417 case 'G':
stefanrousseau 16:17c5916f2d12 418 { //Green
stefanrousseau 16:17c5916f2d12 419 SetLedColor(2);
stefanrousseau 16:17c5916f2d12 420 break;
stefanrousseau 16:17c5916f2d12 421 }
stefanrousseau 16:17c5916f2d12 422 case 'Y':
stefanrousseau 16:17c5916f2d12 423 { //Yellow
stefanrousseau 16:17c5916f2d12 424 SetLedColor(3);
stefanrousseau 16:17c5916f2d12 425 break;
stefanrousseau 16:17c5916f2d12 426 }
stefanrousseau 16:17c5916f2d12 427 case 'B':
stefanrousseau 16:17c5916f2d12 428 { //Blue
stefanrousseau 16:17c5916f2d12 429 SetLedColor(4);
stefanrousseau 16:17c5916f2d12 430 break;
stefanrousseau 16:17c5916f2d12 431 }
stefanrousseau 16:17c5916f2d12 432 case 'M':
stefanrousseau 16:17c5916f2d12 433 { //Magenta
stefanrousseau 16:17c5916f2d12 434 SetLedColor(5);
stefanrousseau 16:17c5916f2d12 435 break;
stefanrousseau 16:17c5916f2d12 436 }
stefanrousseau 16:17c5916f2d12 437 case 'T':
stefanrousseau 16:17c5916f2d12 438 { //Turquoise
stefanrousseau 16:17c5916f2d12 439 SetLedColor(6);
stefanrousseau 16:17c5916f2d12 440 break;
stefanrousseau 16:17c5916f2d12 441 }
stefanrousseau 16:17c5916f2d12 442 case 'W':
stefanrousseau 16:17c5916f2d12 443 { //White
stefanrousseau 16:17c5916f2d12 444 SetLedColor(7);
stefanrousseau 16:17c5916f2d12 445 break;
stefanrousseau 16:17c5916f2d12 446 }
stefanrousseau 16:17c5916f2d12 447 default:
stefanrousseau 16:17c5916f2d12 448 {
stefanrousseau 16:17c5916f2d12 449 break;
stefanrousseau 16:17c5916f2d12 450 }
stefanrousseau 16:17c5916f2d12 451 } //switch(cLedColor)
stefanrousseau 16:17c5916f2d12 452 return true;
stefanrousseau 16:17c5916f2d12 453 }
stefanrousseau 16:17c5916f2d12 454 else
stefanrousseau 16:17c5916f2d12 455 {
stefanrousseau 16:17c5916f2d12 456 return false;
stefanrousseau 16:17c5916f2d12 457 }
stefanrousseau 16:17c5916f2d12 458 } //parse_JSON
stefanrousseau 16:17c5916f2d12 459
JMF 0:9d5134074d84 460 int main() {
JMF 2:0e2ef866af95 461 int i;
JMF 0:9d5134074d84 462 HTS221 hts221;
JMF 0:9d5134074d84 463 pc.baud(115200);
JMF 0:9d5134074d84 464
JMF 0:9d5134074d84 465 void hts221_init(void);
JMF 0:9d5134074d84 466
fkellermavnet 20:27a4f27254d0 467 // Set LED to RED until init finishes
fkellermavnet 20:27a4f27254d0 468 SetLedColor(0x1);
fkellermavnet 20:27a4f27254d0 469
JMF 1:af7a42f7d465 470 pc.printf(BLU "Hello World from AT&T Shape!\r\n\n\r");
JMF 0:9d5134074d84 471 pc.printf(GRN "Initialize the HTS221\n\r");
JMF 0:9d5134074d84 472
JMF 0:9d5134074d84 473 i = hts221.begin();
JMF 0:9d5134074d84 474 if( i )
JMF 0:9d5134074d84 475 pc.printf(BLU "HTS221 Detected! (0x%02X)\n\r",i);
JMF 0:9d5134074d84 476 else
JMF 0:9d5134074d84 477 pc.printf(RED "HTS221 NOT DETECTED!!\n\r");
JMF 0:9d5134074d84 478
JMF 0:9d5134074d84 479 printf("Temp is: %0.2f F \n\r",CTOF(hts221.readTemperature()));
JMF 0:9d5134074d84 480 printf("Humid is: %02d %%\n\r",hts221.readHumidity());
JMF 0:9d5134074d84 481
stefanrousseau 11:e6602513730f 482 sensors_init();
stefanrousseau 12:7c94ec5069dc 483 read_sensors();
stefanrousseau 11:e6602513730f 484
JMF 0:9d5134074d84 485 // Initialize the modem
JMF 0:9d5134074d84 486 printf(GRN "Modem initializing... will take up to 60 seconds" DEF "\r\n");
fkellermavnet 14:0c353e212296 487 do {
fkellermavnet 14:0c353e212296 488 i=mdm_init();
fkellermavnet 14:0c353e212296 489 if (!i) {
fkellermavnet 14:0c353e212296 490 pc.printf(RED "Modem initialization failed!" DEF "\n");
fkellermavnet 14:0c353e212296 491 }
fkellermavnet 14:0c353e212296 492 } while (!i);
JMF 0:9d5134074d84 493
JMF 2:0e2ef866af95 494 //Software init
JMF 2:0e2ef866af95 495 software_init_mdm();
fkellermavnet 19:f89baed3bd6f 496
JMF 2:0e2ef866af95 497 // Resolve URL to IP address to connect to
JMF 2:0e2ef866af95 498 resolve_mdm();
JMF 0:9d5134074d84 499
stefanrousseau 3:26b3cc155f39 500 //Create a 1ms timer tick function:
stefanrousseau 3:26b3cc155f39 501 OneMsTicker.attach(OneMsFunction, 0.001f) ;
fkellermavnet 26:8d6e7e7cdcae 502
stefanrousseau 24:bd480d2aade4 503 iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS;
stefanrousseau 3:26b3cc155f39 504
fkellermavnet 26:8d6e7e7cdcae 505 // Open the socket (connect to the server)
fkellermavnet 25:e7996d22a7e6 506 sockopen_mdm();
stefanrousseau 3:26b3cc155f39 507
fkellermavnet 20:27a4f27254d0 508 // Set LED BLUE for partial init
fkellermavnet 20:27a4f27254d0 509 SetLedColor(0x4);
fkellermavnet 20:27a4f27254d0 510
JMF 2:0e2ef866af95 511 // Send and receive data perpetually
JMF 2:0e2ef866af95 512 while(1) {
fkellermavnet 20:27a4f27254d0 513 static unsigned ledOnce = 0;
stefanrousseau 55:3abf9e3f42e6 514 #ifdef USE_VIRTUAL_SENSORS
stefanrousseau 55:3abf9e3f42e6 515 ProcessUsbInterface();
stefanrousseau 55:3abf9e3f42e6 516 #endif
stefanrousseau 3:26b3cc155f39 517 if (bTimerExpiredFlag)
stefanrousseau 3:26b3cc155f39 518 {
stefanrousseau 3:26b3cc155f39 519 bTimerExpiredFlag = false;
fkellermavnet 53:dcccf2881fa0 520 puts("HTS221 START\r\n");
stefanrousseau 3:26b3cc155f39 521 sprintf(SENSOR_DATA.Temperature, "%0.2f", CTOF(hts221.readTemperature()));
stefanrousseau 3:26b3cc155f39 522 sprintf(SENSOR_DATA.Humidity, "%02d", hts221.readHumidity());
fkellermavnet 53:dcccf2881fa0 523 puts("READ OTHER SENSORS START\r\n");
stefanrousseau 4:f83bedd9cab4 524 read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor
stefanrousseau 3:26b3cc155f39 525 char modem_string[512];
fkellermavnet 53:dcccf2881fa0 526 puts("GENERATE MODEM STRING\r\n");
stefanrousseau 3:26b3cc155f39 527 GenerateModemString(&modem_string[0]);
stefanrousseau 41:9b14c40eebf6 528 printf(BLU "\r\nSending to modem : %s" DEF "\r\n", modem_string);
stefanrousseau 3:26b3cc155f39 529 sockwrite_mdm(modem_string);
fkellermavnet 53:dcccf2881fa0 530 printf("READ START\r\n");
stefanrousseau 41:9b14c40eebf6 531 if (sockread_mdm(&MySocketData, 1024, 20))
fkellermavnet 20:27a4f27254d0 532 {
stefanrousseau 41:9b14c40eebf6 533 // If any non-zero response from server, make it GREEN one-time
stefanrousseau 41:9b14c40eebf6 534 // then the actual FLOW responses will set the color.
stefanrousseau 41:9b14c40eebf6 535 if (!ledOnce)
stefanrousseau 41:9b14c40eebf6 536 {
stefanrousseau 41:9b14c40eebf6 537 ledOnce = 1;
stefanrousseau 41:9b14c40eebf6 538 SetLedColor(0x2);
stefanrousseau 41:9b14c40eebf6 539 }
stefanrousseau 41:9b14c40eebf6 540 printf(YEL "Read back : %s" DEF "\r\n", &MySocketData[0]);
stefanrousseau 41:9b14c40eebf6 541 char myJsonResponse[512];
fkellermavnet 50:8ac42961458c 542 char stringToCharBuf[BUF_SIZE_FOR_N_MAX_SOCKREAD*MAX_WNC_SOCKREAD_PAYLOAD+1]; // WNC can return max of 1500 (per sockread)
fkellermavnet 52:9dafcb7f320f 543 if ((MySocketData.length() + 1) < sizeof(stringToCharBuf))
stefanrousseau 41:9b14c40eebf6 544 {
fkellermavnet 53:dcccf2881fa0 545 puts("STRING COPY\r\n");
fkellermavnet 52:9dafcb7f320f 546 strcpy(stringToCharBuf, MySocketData.c_str());
fkellermavnet 53:dcccf2881fa0 547 puts("EXTRACT JSON\r\n");
fkellermavnet 52:9dafcb7f320f 548 if (extract_JSON(stringToCharBuf, &myJsonResponse[0]))
fkellermavnet 52:9dafcb7f320f 549 {
fkellermavnet 52:9dafcb7f320f 550 printf(GRN "JSON : %s" DEF "\n", &myJsonResponse[0]);
fkellermavnet 53:dcccf2881fa0 551 puts("PARSE JSON\r\n");
fkellermavnet 52:9dafcb7f320f 552 parse_JSON(&myJsonResponse[0]);
fkellermavnet 52:9dafcb7f320f 553 }
stefanrousseau 41:9b14c40eebf6 554 }
fkellermavnet 52:9dafcb7f320f 555 else
fkellermavnet 52:9dafcb7f320f 556 puts("BUFFER not big enough for sock data!\r\n");
stefanrousseau 16:17c5916f2d12 557 }
stefanrousseau 16:17c5916f2d12 558 else
stefanrousseau 16:17c5916f2d12 559 {
stefanrousseau 41:9b14c40eebf6 560 printf(RED "No response..." DEF "\r\n");
stefanrousseau 16:17c5916f2d12 561 }
fkellermavnet 53:dcccf2881fa0 562 puts("SOCKREAD DONE\r\n");
stefanrousseau 3:26b3cc155f39 563 } //bTimerExpiredFlag
stefanrousseau 3:26b3cc155f39 564 } //forever loop
JMF 0:9d5134074d84 565 }