I added functionality to get the RSSI, BER, and Cell Neighbor for reporting connection issues to M2X
Dependencies: mbed FXOS8700CQ mbed-rtos WNCInterface M2XStreamClient-JMF jsonlite
main.cpp@13:99c72ab600c9, 2019-04-18 (annotated)
- Committer:
- ng977t
- Date:
- Thu Apr 18 22:58:31 2019 +0000
- Revision:
- 13:99c72ab600c9
- Parent:
- 12:0dfd0129f75d
I added functionality to get the RSSI, BER, and Cell Neighbor for reporting connection issues to M2X
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JMF | 0:62feed0f1fd9 | 1 | // |
JMF | 0:62feed0f1fd9 | 2 | // This file contains an example implementation of M2X using the HTTP interface as the underlying |
JMF | 0:62feed0f1fd9 | 3 | // transport. |
JMF | 0:62feed0f1fd9 | 4 | // |
JMF | 0:62feed0f1fd9 | 5 | |
JMF | 0:62feed0f1fd9 | 6 | #include "mbed.h" |
JMF | 0:62feed0f1fd9 | 7 | #include "WNCInterface.h" |
jk431j | 7:721eb6bb68d3 | 8 | #include "IOTSMS.h" |
JMF | 0:62feed0f1fd9 | 9 | |
JMF | 0:62feed0f1fd9 | 10 | #define MBED_PLATFORM |
JMF | 0:62feed0f1fd9 | 11 | #define M2X_ENABLE_READER |
JMF | 0:62feed0f1fd9 | 12 | |
JMF | 0:62feed0f1fd9 | 13 | #include <jsonlite.h> |
JMF | 0:62feed0f1fd9 | 14 | #include "M2XStreamClient.h" |
JMF | 0:62feed0f1fd9 | 15 | |
jk431j | 4:08979e323c6e | 16 | #include "sensors.h" |
jk431j | 7:721eb6bb68d3 | 17 | #include "config_me.h" |
jk431j | 4:08979e323c6e | 18 | |
JMF | 0:62feed0f1fd9 | 19 | #define CRLF "\n\r" |
JMF | 0:62feed0f1fd9 | 20 | |
jk431j | 7:721eb6bb68d3 | 21 | //startup SMS, disabled by default |
jk431j | 7:721eb6bb68d3 | 22 | //#define STARTUP_SMS |
JMF | 0:62feed0f1fd9 | 23 | |
jk431j | 9:3f5dfac96ac1 | 24 | //command processing enabled by default |
jk431j | 9:3f5dfac96ac1 | 25 | #define COMMANDS_ENABLED |
jk431j | 9:3f5dfac96ac1 | 26 | |
jk431j | 9:3f5dfac96ac1 | 27 | //update all streams in one command, disabled by default |
jk431j | 9:3f5dfac96ac1 | 28 | //#define SINGLE_UPDATE |
jk431j | 9:3f5dfac96ac1 | 29 | |
JMF | 0:62feed0f1fd9 | 30 | WNCInterface eth; |
jk431j | 7:721eb6bb68d3 | 31 | WNCSms sms; |
JMF | 0:62feed0f1fd9 | 32 | Client client; |
JMF | 0:62feed0f1fd9 | 33 | M2XStreamClient m2xClient(&client, m2xKey); |
JMF | 0:62feed0f1fd9 | 34 | TimeService timeService(&m2xClient); |
jk431j | 4:08979e323c6e | 35 | |
jk431j | 4:08979e323c6e | 36 | I2C i2c(PTC11, PTC10); //SDA, SCL -- define the I2C pins being used |
jk431j | 4:08979e323c6e | 37 | Serial pc(USBTX, USBRX); // tx, rx |
jk431j | 4:08979e323c6e | 38 | DigitalOut led_green(LED_GREEN); |
jk431j | 4:08979e323c6e | 39 | DigitalOut led_red(LED_RED); |
jk431j | 4:08979e323c6e | 40 | DigitalOut led_blue(LED_BLUE); |
jk431j | 4:08979e323c6e | 41 | |
jk431j | 6:731f412e6571 | 42 | K64F_Sensors_t SENSOR_DATA = {}; |
jk431j | 9:3f5dfac96ac1 | 43 | K64F_Sensors_t OLD_SENSOR_DATA = {}; |
jk431j | 7:721eb6bb68d3 | 44 | bool bStop = false; |
jk431j | 9:3f5dfac96ac1 | 45 | bool bSendDataNow = false; |
jk431j | 9:3f5dfac96ac1 | 46 | bool bSendSMS = false; |
jk431j | 8:b82d330e10e9 | 47 | bool bM2XConfigured; |
jk431j | 8:b82d330e10e9 | 48 | |
jk431j | 8:b82d330e10e9 | 49 | Ticker WatchdogTicker; |
jk431j | 8:b82d330e10e9 | 50 | int watchdogTicks = 0; |
jk431j | 8:b82d330e10e9 | 51 | bool bWatchdogOn = false; |
jk431j | 8:b82d330e10e9 | 52 | unsigned char lastLedColor = 0; |
jk431j | 4:08979e323c6e | 53 | |
jk431j | 9:3f5dfac96ac1 | 54 | InterruptIn btn3(SW3); |
jk431j | 9:3f5dfac96ac1 | 55 | InterruptIn btn2(SW2); |
jk431j | 9:3f5dfac96ac1 | 56 | |
jk431j | 9:3f5dfac96ac1 | 57 | #ifdef SINGLE_UPDATE |
jk431j | 9:3f5dfac96ac1 | 58 | const char* allStreamNames[] = { hStreamName, tStreamName, accelStreamNames[0], accelStreamNames[1], accelStreamNames[2] }; |
jk431j | 9:3f5dfac96ac1 | 59 | #endif |
jk431j | 9:3f5dfac96ac1 | 60 | |
jk431j | 4:08979e323c6e | 61 | //******************************************************************************************************************************************** |
jk431j | 4:08979e323c6e | 62 | //* Set the RGB LED's Color |
jk431j | 4:08979e323c6e | 63 | //* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue) |
jk431j | 4:08979e323c6e | 64 | //******************************************************************************************************************************************** |
jk431j | 4:08979e323c6e | 65 | void SetLedColor(unsigned char ucColor) |
jk431j | 4:08979e323c6e | 66 | { |
jk431j | 4:08979e323c6e | 67 | //Note that when an LED is on, you write a 0 to it: |
jk431j | 4:08979e323c6e | 68 | led_red = !(ucColor & 0x1); //bit 0 |
jk431j | 4:08979e323c6e | 69 | led_green = !(ucColor & 0x2); //bit 1 |
jk431j | 4:08979e323c6e | 70 | led_blue = !(ucColor & 0x4); //bit 2 |
jk431j | 8:b82d330e10e9 | 71 | |
jk431j | 8:b82d330e10e9 | 72 | lastLedColor = ucColor; |
jk431j | 4:08979e323c6e | 73 | } //SetLedColor() |
jk431j | 4:08979e323c6e | 74 | |
jk431j | 8:b82d330e10e9 | 75 | struct Watchdog { |
jk431j | 8:b82d330e10e9 | 76 | Watchdog() { |
jk431j | 8:b82d330e10e9 | 77 | bWatchdogOn = true; |
jk431j | 8:b82d330e10e9 | 78 | }; |
jk431j | 8:b82d330e10e9 | 79 | |
jk431j | 8:b82d330e10e9 | 80 | ~Watchdog() { |
jk431j | 8:b82d330e10e9 | 81 | bWatchdogOn = false; |
jk431j | 8:b82d330e10e9 | 82 | }; |
jk431j | 8:b82d330e10e9 | 83 | }; |
jk431j | 8:b82d330e10e9 | 84 | |
jk431j | 8:b82d330e10e9 | 85 | #define WATCHDOG struct Watchdog aWatchdog; |
jk431j | 8:b82d330e10e9 | 86 | |
jk431j | 8:b82d330e10e9 | 87 | void watchdog_check() |
jk431j | 8:b82d330e10e9 | 88 | { |
jk431j | 8:b82d330e10e9 | 89 | // watchdog function is run every 1/4th of a second |
jk431j | 8:b82d330e10e9 | 90 | if(bWatchdogOn) { |
jk431j | 8:b82d330e10e9 | 91 | watchdogTicks++; |
jk431j | 8:b82d330e10e9 | 92 | |
jk431j | 8:b82d330e10e9 | 93 | // blink LED while watchdog is running |
jk431j | 8:b82d330e10e9 | 94 | if (watchdogTicks % 2 == 1) { |
jk431j | 8:b82d330e10e9 | 95 | led_red = led_green = led_blue = 1; |
jk431j | 8:b82d330e10e9 | 96 | } else { |
jk431j | 8:b82d330e10e9 | 97 | SetLedColor(lastLedColor); |
jk431j | 8:b82d330e10e9 | 98 | }; |
jk431j | 8:b82d330e10e9 | 99 | } else { |
jk431j | 8:b82d330e10e9 | 100 | watchdogTicks = 0; |
jk431j | 8:b82d330e10e9 | 101 | SetLedColor(lastLedColor); |
jk431j | 8:b82d330e10e9 | 102 | } |
jk431j | 8:b82d330e10e9 | 103 | |
jk431j | 9:3f5dfac96ac1 | 104 | // reset if the watchod is on for more than 10 seconds |
jk431j | 9:3f5dfac96ac1 | 105 | if(watchdogTicks > 30 * 4) NVIC_SystemReset(); |
jk431j | 8:b82d330e10e9 | 106 | } |
jk431j | 8:b82d330e10e9 | 107 | |
jk431j | 8:b82d330e10e9 | 108 | |
jk431j | 8:b82d330e10e9 | 109 | bool power_on() { |
jk431j | 8:b82d330e10e9 | 110 | return (RCM->SRS0 & RCM_SRS0_POR_MASK); |
jk431j | 8:b82d330e10e9 | 111 | } |
jk431j | 8:b82d330e10e9 | 112 | |
JMF | 0:62feed0f1fd9 | 113 | |
jk431j | 4:08979e323c6e | 114 | bool ExecuteCommand(const char* Command) |
jk431j | 4:08979e323c6e | 115 | { |
jk431j | 4:08979e323c6e | 116 | char cLedColor = *Command; |
jk431j | 4:08979e323c6e | 117 | switch(cLedColor) |
jk431j | 4:08979e323c6e | 118 | { |
jk431j | 4:08979e323c6e | 119 | case 'O': |
jk431j | 4:08979e323c6e | 120 | { //Off |
jk431j | 4:08979e323c6e | 121 | SetLedColor(0); |
jk431j | 4:08979e323c6e | 122 | break; |
jk431j | 4:08979e323c6e | 123 | } |
jk431j | 4:08979e323c6e | 124 | case 'R': |
jk431j | 4:08979e323c6e | 125 | { //Red |
jk431j | 4:08979e323c6e | 126 | SetLedColor(1); |
jk431j | 4:08979e323c6e | 127 | break; |
jk431j | 4:08979e323c6e | 128 | } |
jk431j | 4:08979e323c6e | 129 | case 'G': |
jk431j | 4:08979e323c6e | 130 | { //Green |
jk431j | 4:08979e323c6e | 131 | SetLedColor(2); |
jk431j | 4:08979e323c6e | 132 | break; |
jk431j | 4:08979e323c6e | 133 | } |
jk431j | 4:08979e323c6e | 134 | case 'Y': |
jk431j | 4:08979e323c6e | 135 | { //Yellow |
jk431j | 4:08979e323c6e | 136 | SetLedColor(3); |
jk431j | 4:08979e323c6e | 137 | break; |
jk431j | 4:08979e323c6e | 138 | } |
jk431j | 4:08979e323c6e | 139 | case 'B': |
jk431j | 4:08979e323c6e | 140 | { //Blue |
jk431j | 4:08979e323c6e | 141 | SetLedColor(4); |
jk431j | 4:08979e323c6e | 142 | break; |
jk431j | 4:08979e323c6e | 143 | } |
jk431j | 4:08979e323c6e | 144 | case 'M': |
jk431j | 8:b82d330e10e9 | 145 | { //Magenta or M2X |
jk431j | 8:b82d330e10e9 | 146 | char Key[33], Device[33]; |
jk431j | 8:b82d330e10e9 | 147 | |
jk431j | 8:b82d330e10e9 | 148 | int count = sscanf(Command, "M2X:%32s:%32s", Key, Device); |
jk431j | 8:b82d330e10e9 | 149 | if (count == 2) { |
jk431j | 8:b82d330e10e9 | 150 | pc.printf("Got key %s and device %s" CRLF, Key, Device); |
jk431j | 8:b82d330e10e9 | 151 | strncpy(deviceId, Device, 32); |
jk431j | 8:b82d330e10e9 | 152 | strncpy(m2xKey, Key, 32); |
jk431j | 8:b82d330e10e9 | 153 | bM2XConfigured = true; |
jk431j | 8:b82d330e10e9 | 154 | } else |
jk431j | 8:b82d330e10e9 | 155 | SetLedColor(5); |
jk431j | 4:08979e323c6e | 156 | break; |
jk431j | 4:08979e323c6e | 157 | } |
jk431j | 4:08979e323c6e | 158 | case 'T': |
jk431j | 4:08979e323c6e | 159 | { //Turquoise |
jk431j | 4:08979e323c6e | 160 | SetLedColor(6); |
jk431j | 4:08979e323c6e | 161 | break; |
jk431j | 4:08979e323c6e | 162 | } |
jk431j | 4:08979e323c6e | 163 | case 'W': |
jk431j | 4:08979e323c6e | 164 | { //White |
jk431j | 9:3f5dfac96ac1 | 165 | int Delay = 0, Polls = 0; |
jk431j | 9:3f5dfac96ac1 | 166 | |
jk431j | 9:3f5dfac96ac1 | 167 | pc.printf("Processing WAIT command" CRLF); |
jk431j | 9:3f5dfac96ac1 | 168 | int count = sscanf(Command, "WAIT:%d:%d", Delay, Polls); |
jk431j | 9:3f5dfac96ac1 | 169 | if (count == 2) { |
jk431j | 9:3f5dfac96ac1 | 170 | pc.printf("Reconfiguring wait loop to %d delay and %d polls ...", Delay, Polls); |
jk431j | 9:3f5dfac96ac1 | 171 | if ((Delay > 5) && (Delay < 300) |
jk431j | 9:3f5dfac96ac1 | 172 | && (Polls > 0) && (Polls < 100)) { |
jk431j | 9:3f5dfac96ac1 | 173 | bSendDataNow = true; |
jk431j | 9:3f5dfac96ac1 | 174 | commandDelay = Delay; |
jk431j | 9:3f5dfac96ac1 | 175 | commandPolls = Polls; |
jk431j | 9:3f5dfac96ac1 | 176 | pc.printf("done" CRLF); |
jk431j | 9:3f5dfac96ac1 | 177 | } else |
jk431j | 9:3f5dfac96ac1 | 178 | pc.printf("discarding invalid parameters!" CRLF); |
jk431j | 9:3f5dfac96ac1 | 179 | } else |
jk431j | 9:3f5dfac96ac1 | 180 | SetLedColor(7); |
jk431j | 4:08979e323c6e | 181 | break; |
jk431j | 4:08979e323c6e | 182 | } |
jk431j | 7:721eb6bb68d3 | 183 | case 'S': |
jk431j | 7:721eb6bb68d3 | 184 | { //Stop |
jk431j | 7:721eb6bb68d3 | 185 | bStop = true; |
jk431j | 7:721eb6bb68d3 | 186 | break; |
jk431j | 7:721eb6bb68d3 | 187 | } |
jk431j | 4:08979e323c6e | 188 | default: |
jk431j | 4:08979e323c6e | 189 | { |
jk431j | 4:08979e323c6e | 190 | return false; |
jk431j | 4:08979e323c6e | 191 | } |
jk431j | 4:08979e323c6e | 192 | } //switch(cLedColor) |
jk431j | 4:08979e323c6e | 193 | return true; |
JMF | 0:62feed0f1fd9 | 194 | } |
JMF | 0:62feed0f1fd9 | 195 | |
JMF | 0:62feed0f1fd9 | 196 | |
jk431j | 4:08979e323c6e | 197 | void on_data_point_found(const char* at, const char* value, int index, void* context, int type) { |
jk431j | 4:08979e323c6e | 198 | pc.printf(">>Found a data point, index: %d type: %d" CRLF, index, type); |
jk431j | 4:08979e323c6e | 199 | pc.printf(">>At: %s" CRLF " Value: %s" CRLF, at, value); |
jk431j | 4:08979e323c6e | 200 | } |
jk431j | 4:08979e323c6e | 201 | |
jk431j | 4:08979e323c6e | 202 | void on_fill_data(Print *print, void *context) { |
jk431j | 4:08979e323c6e | 203 | // no data to fill |
JMF | 0:62feed0f1fd9 | 204 | } |
JMF | 0:62feed0f1fd9 | 205 | |
jk431j | 9:3f5dfac96ac1 | 206 | |
jk431j | 4:08979e323c6e | 207 | void on_command_found(const char* id, const char* name, int index, void *context) { |
jk431j | 7:721eb6bb68d3 | 208 | pc.printf("\t|Found a command, index: %d" CRLF, index); |
jk431j | 7:721eb6bb68d3 | 209 | pc.printf("\t|ID: %s" CRLF "\t|Name: %s" CRLF, id, name); |
jk431j | 4:08979e323c6e | 210 | ExecuteCommand(name); |
jk431j | 4:08979e323c6e | 211 | m2xClient.markCommandProcessed(deviceId, id, on_fill_data, NULL); |
jk431j | 7:721eb6bb68d3 | 212 | pc.printf("\t|Command confirmed" CRLF, id, name); |
JMF | 0:62feed0f1fd9 | 213 | } |
JMF | 0:62feed0f1fd9 | 214 | |
jk431j | 9:3f5dfac96ac1 | 215 | |
jk431j | 7:721eb6bb68d3 | 216 | void on_msg_rcvd( WNCSmsMsg& msg ) { |
jk431j | 7:721eb6bb68d3 | 217 | pc.printf(YEL "SMS received from %s" CRLF, msg.number.c_str()); |
jk431j | 7:721eb6bb68d3 | 218 | pc.printf("|Timestamp: %s %s" CRLF, msg.date.c_str(), msg.time.c_str()); |
jk431j | 7:721eb6bb68d3 | 219 | pc.printf("|Text: '%s'" CRLF, msg.msg.c_str()); |
jk431j | 7:721eb6bb68d3 | 220 | pc.printf(WHT); |
jk431j | 7:721eb6bb68d3 | 221 | ExecuteCommand(msg.msg.c_str()); |
jk431j | 7:721eb6bb68d3 | 222 | } |
jk431j | 4:08979e323c6e | 223 | |
jk431j | 8:b82d330e10e9 | 224 | |
jk431j | 9:3f5dfac96ac1 | 225 | void button_2_pressed() { |
jk431j | 9:3f5dfac96ac1 | 226 | bSendSMS = true; |
jk431j | 9:3f5dfac96ac1 | 227 | } |
jk431j | 9:3f5dfac96ac1 | 228 | |
jk431j | 9:3f5dfac96ac1 | 229 | |
jk431j | 9:3f5dfac96ac1 | 230 | void button_3_pressed() { |
jk431j | 9:3f5dfac96ac1 | 231 | bSendDataNow = true; |
jk431j | 9:3f5dfac96ac1 | 232 | } |
jk431j | 9:3f5dfac96ac1 | 233 | |
jk431j | 9:3f5dfac96ac1 | 234 | |
jk431j | 9:3f5dfac96ac1 | 235 | void process_buttons() { |
jk431j | 9:3f5dfac96ac1 | 236 | char smsText[100]; |
jk431j | 9:3f5dfac96ac1 | 237 | |
jk431j | 9:3f5dfac96ac1 | 238 | if (bSendSMS) { |
jk431j | 9:3f5dfac96ac1 | 239 | bSendSMS = false; |
jk431j | 9:3f5dfac96ac1 | 240 | |
jk431j | 9:3f5dfac96ac1 | 241 | snprintf(smsText, 100, "Last temperature was %.2f", SENSOR_DATA.Temperature); |
jk431j | 9:3f5dfac96ac1 | 242 | int response = sms.send("5277", smsText); |
jk431j | 9:3f5dfac96ac1 | 243 | pc.printf(YEL "Button SMS %s sent." CRLF, response ? "was" : "NOT"); |
jk431j | 9:3f5dfac96ac1 | 244 | pc.printf(WHT); |
jk431j | 9:3f5dfac96ac1 | 245 | }; |
jk431j | 9:3f5dfac96ac1 | 246 | } |
jk431j | 9:3f5dfac96ac1 | 247 | |
jk431j | 9:3f5dfac96ac1 | 248 | bool check_accelerometer_change() { |
jk431j | 9:3f5dfac96ac1 | 249 | read_sensors(); |
jk431j | 9:3f5dfac96ac1 | 250 | |
jk431j | 9:3f5dfac96ac1 | 251 | float diffX, diffY, diffZ; |
jk431j | 9:3f5dfac96ac1 | 252 | diffX = abs(SENSOR_DATA.AccelX - OLD_SENSOR_DATA.AccelX); |
jk431j | 9:3f5dfac96ac1 | 253 | diffY = abs(SENSOR_DATA.AccelY - OLD_SENSOR_DATA.AccelY); |
jk431j | 9:3f5dfac96ac1 | 254 | diffZ = abs(SENSOR_DATA.AccelZ - OLD_SENSOR_DATA.AccelZ); |
jk431j | 9:3f5dfac96ac1 | 255 | |
jk431j | 9:3f5dfac96ac1 | 256 | bool changed = (diffX > 0.5) || (diffY > 0.5) || (diffZ > 0.5); |
jk431j | 9:3f5dfac96ac1 | 257 | if (changed) { |
jk431j | 9:3f5dfac96ac1 | 258 | bSendDataNow = true; |
jk431j | 9:3f5dfac96ac1 | 259 | pc.printf("Accelerometer changed, sending data immediately." CRLF); |
jk431j | 9:3f5dfac96ac1 | 260 | }; |
jk431j | 9:3f5dfac96ac1 | 261 | |
jk431j | 9:3f5dfac96ac1 | 262 | return changed; |
jk431j | 9:3f5dfac96ac1 | 263 | } |
jk431j | 9:3f5dfac96ac1 | 264 | |
jk431j | 8:b82d330e10e9 | 265 | |
JMF | 0:62feed0f1fd9 | 266 | int main() { |
jk431j | 4:08979e323c6e | 267 | char timestamp[25]; |
jk431j | 4:08979e323c6e | 268 | int length = 25; |
jk431j | 4:08979e323c6e | 269 | int response; |
jk431j | 9:3f5dfac96ac1 | 270 | |
jk431j | 7:721eb6bb68d3 | 271 | ExecuteCommand("Red"); |
jk431j | 9:3f5dfac96ac1 | 272 | |
jk431j | 7:721eb6bb68d3 | 273 | pc.baud(115200); |
jk431j | 9:3f5dfac96ac1 | 274 | pc.printf("M2X StarterKit demo (compiled " __DATE__ ", " __TIME__ "): initializing the network" CRLF); |
jk431j | 8:b82d330e10e9 | 275 | response = eth.init("m2m.com.attz"); |
jk431j | 4:08979e323c6e | 276 | pc.printf("WNC Module %s initialized (%02X)." CRLF, response?"IS":"IS NOT", response); |
jk431j | 4:08979e323c6e | 277 | if( !response ) { |
jk431j | 8:b82d330e10e9 | 278 | pc.printf(" - - - - - - - SYSTEM RESET - - - - - - - " CRLF CRLF); |
jk431j | 4:08979e323c6e | 279 | NVIC_SystemReset(); |
jk431j | 4:08979e323c6e | 280 | } |
jk431j | 7:721eb6bb68d3 | 281 | |
jk431j | 7:721eb6bb68d3 | 282 | response = sms.init(1, on_msg_rcvd); |
jk431j | 7:721eb6bb68d3 | 283 | pc.printf("SMS interface %s initialized (%02X)." CRLF, response?"IS NOT":"IS", response); |
jk431j | 7:721eb6bb68d3 | 284 | if (!response) { |
jk431j | 7:721eb6bb68d3 | 285 | pc.printf("SMS number is %s" CRLF , sms.getSMSNbr()); |
jk431j | 7:721eb6bb68d3 | 286 | }; |
jk431j | 7:721eb6bb68d3 | 287 | |
jk431j | 4:08979e323c6e | 288 | response = eth.connect(); |
jk431j | 4:08979e323c6e | 289 | pc.printf("IP Address: %s " CRLF CRLF, eth.getIPAddress()); |
jk431j | 7:721eb6bb68d3 | 290 | |
jk431j | 7:721eb6bb68d3 | 291 | ExecuteCommand("Yellow"); |
jk431j | 4:08979e323c6e | 292 | |
jk431j | 4:08979e323c6e | 293 | pc.printf("Initialize the sensors" CRLF); |
jk431j | 4:08979e323c6e | 294 | sensors_init(); |
jk431j | 4:08979e323c6e | 295 | read_sensors(); |
jk431j | 8:b82d330e10e9 | 296 | |
jk431j | 8:b82d330e10e9 | 297 | bM2XConfigured = *deviceId && *m2xKey; |
jk431j | 8:b82d330e10e9 | 298 | if (!bM2XConfigured) { |
jk431j | 8:b82d330e10e9 | 299 | pc.printf(RED "Waiting for SMS configuration" CRLF); |
jk431j | 8:b82d330e10e9 | 300 | |
jk431j | 8:b82d330e10e9 | 301 | while (!bM2XConfigured) { |
jk431j | 8:b82d330e10e9 | 302 | ExecuteCommand("Red"); |
jk431j | 8:b82d330e10e9 | 303 | delay(1000); |
jk431j | 8:b82d330e10e9 | 304 | ExecuteCommand("Yellow"); |
jk431j | 8:b82d330e10e9 | 305 | delay(1000); |
jk431j | 8:b82d330e10e9 | 306 | } |
jk431j | 8:b82d330e10e9 | 307 | }; |
jk431j | 8:b82d330e10e9 | 308 | |
jk431j | 8:b82d330e10e9 | 309 | // set up watchdog ticker running every quarter of a second |
jk431j | 8:b82d330e10e9 | 310 | WatchdogTicker.attach(watchdog_check, 0.25); |
jk431j | 7:721eb6bb68d3 | 311 | |
jk431j | 9:3f5dfac96ac1 | 312 | { //WATCHDOG |
jk431j | 8:b82d330e10e9 | 313 | pc.printf(WHT "initialize the M2X time service" CRLF); |
jk431j | 8:b82d330e10e9 | 314 | if (!m2x_status_is_success(timeService.init())) |
jk431j | 8:b82d330e10e9 | 315 | pc.printf("Cannot initialize time service!" CRLF); |
jk431j | 8:b82d330e10e9 | 316 | else { |
jk431j | 8:b82d330e10e9 | 317 | timeService.getTimestamp(timestamp, &length); |
jk431j | 8:b82d330e10e9 | 318 | pc.printf("Current timestamp: %s" CRLF, timestamp); |
jk431j | 8:b82d330e10e9 | 319 | }; |
jk431j | 8:b82d330e10e9 | 320 | }; |
jk431j | 9:3f5dfac96ac1 | 321 | |
jk431j | 9:3f5dfac96ac1 | 322 | btn2.fall(&button_2_pressed); |
jk431j | 9:3f5dfac96ac1 | 323 | btn3.fall(&button_3_pressed); |
jk431j | 8:b82d330e10e9 | 324 | |
jk431j | 7:721eb6bb68d3 | 325 | ExecuteCommand("Green"); |
jk431j | 9:3f5dfac96ac1 | 326 | |
jk431j | 7:721eb6bb68d3 | 327 | #ifdef STARTUP_SMS |
jk431j | 7:721eb6bb68d3 | 328 | response = sms.send("5277", "IoT StarterKit is now running!"); |
jk431j | 7:721eb6bb68d3 | 329 | pc.printf("Startup SMS %s sent." CRLF, response ? "was" : "NOT"); |
jk431j | 7:721eb6bb68d3 | 330 | #endif |
jk431j | 9:3f5dfac96ac1 | 331 | |
jk431j | 9:3f5dfac96ac1 | 332 | #ifdef COMMANDS_ENABLED |
jk431j | 8:b82d330e10e9 | 333 | { WATCHDOG |
jk431j | 8:b82d330e10e9 | 334 | pc.printf("Query for pending commands ..." CRLF); |
jk431j | 8:b82d330e10e9 | 335 | response = m2xClient.listCommands(deviceId, on_command_found, NULL, "status=pending"); |
jk431j | 8:b82d330e10e9 | 336 | pc.printf("listCommands response code: %d" CRLF, response); |
jk431j | 8:b82d330e10e9 | 337 | }; |
jk431j | 9:3f5dfac96ac1 | 338 | #endif |
jk431j | 8:b82d330e10e9 | 339 | |
jk431j | 7:721eb6bb68d3 | 340 | while (!bStop) { |
jk431j | 4:08979e323c6e | 341 | // read sensor values |
jk431j | 4:08979e323c6e | 342 | read_sensors(); |
JMF | 0:62feed0f1fd9 | 343 | |
jk431j | 8:b82d330e10e9 | 344 | { WATCHDOG |
jk431j | 9:3f5dfac96ac1 | 345 | #ifndef SINGLE_UPDATE |
jk431j | 8:b82d330e10e9 | 346 | // post the humidity value |
jk431j | 8:b82d330e10e9 | 347 | pc.printf("Post updateStreamValue (humidity = %.2f)..." CRLF, SENSOR_DATA.Humidity); |
jk431j | 8:b82d330e10e9 | 348 | response = m2xClient.updateStreamValue(deviceId, hStreamName, SENSOR_DATA.Humidity); |
jk431j | 8:b82d330e10e9 | 349 | pc.printf("Post response code: %d" CRLF, response); |
jk431j | 8:b82d330e10e9 | 350 | |
jk431j | 8:b82d330e10e9 | 351 | // post the temp value |
jk431j | 8:b82d330e10e9 | 352 | pc.printf("Post updateStreamValue (temp = %.2f)..." CRLF, SENSOR_DATA.Temperature); |
jk431j | 8:b82d330e10e9 | 353 | response = m2xClient.updateStreamValue(deviceId, tStreamName, SENSOR_DATA.Temperature); |
jk431j | 8:b82d330e10e9 | 354 | pc.printf("Post response code: %d" CRLF, response); |
jk431j | 8:b82d330e10e9 | 355 | |
jk431j | 8:b82d330e10e9 | 356 | // post accelerometer values |
jk431j | 9:3f5dfac96ac1 | 357 | pc.printf("Post postDeviceUpdate (accelerometer [%.2f,%.2f,%.2f])..." CRLF, SENSOR_DATA.AccelX, SENSOR_DATA.AccelY, SENSOR_DATA.AccelZ); |
jk431j | 8:b82d330e10e9 | 358 | response = m2xClient.postDeviceUpdate(deviceId, 3, accelStreamNames, (float []){SENSOR_DATA.AccelX, SENSOR_DATA.AccelY, SENSOR_DATA.AccelZ}); |
jk431j | 8:b82d330e10e9 | 359 | pc.printf("Post response code: %d" CRLF, response); |
ng977t | 12:0dfd0129f75d | 360 | |
ng977t | 12:0dfd0129f75d | 361 | // post the signal value |
ng977t | 12:0dfd0129f75d | 362 | pc.printf("Post updateStreamValue (signal = %.2f)..." CRLF, SENSOR_DATA.Signal_Strength); |
ng977t | 12:0dfd0129f75d | 363 | response = m2xClient.updateStreamValue(deviceId, sStreamName, SENSOR_DATA.Signal_Strength); |
ng977t | 12:0dfd0129f75d | 364 | pc.printf("Post response code: %d" CRLF, response); |
ng977t | 12:0dfd0129f75d | 365 | |
ng977t | 12:0dfd0129f75d | 366 | // post the signal error value |
ng977t | 12:0dfd0129f75d | 367 | pc.printf("Post updateStreamValue (error = %d)..." CRLF, SENSOR_DATA.Error); |
ng977t | 12:0dfd0129f75d | 368 | response = m2xClient.updateStreamValue(deviceId, eStreamName, SENSOR_DATA.Error); |
ng977t | 12:0dfd0129f75d | 369 | pc.printf("Post response code: %d" CRLF, response); |
ng977t | 12:0dfd0129f75d | 370 | |
ng977t | 12:0dfd0129f75d | 371 | // post the neighbor value |
ng977t | 12:0dfd0129f75d | 372 | pc.printf("Post updateStreamValue (neighbor = %s)..." CRLF, SENSOR_DATA.Neighbor); |
ng977t | 12:0dfd0129f75d | 373 | //response = m2xClient.updateStreamValues(deviceId, nStreamName, SENSOR_DATA.Neighbor); |
ng977t | 12:0dfd0129f75d | 374 | pc.printf("Post response code: %d" CRLF, response); |
ng977t | 12:0dfd0129f75d | 375 | |
jk431j | 9:3f5dfac96ac1 | 376 | #else |
jk431j | 9:3f5dfac96ac1 | 377 | // post all values at one |
jk431j | 9:3f5dfac96ac1 | 378 | pc.printf("Post all stream values [%.2f,%.2f,%.2f,%.2f,%.2f])..." CRLF, SENSOR_DATA.Humidity, SENSOR_DATA.Temperature, SENSOR_DATA.AccelX, SENSOR_DATA.AccelY, SENSOR_DATA.AccelZ); |
jk431j | 9:3f5dfac96ac1 | 379 | response = m2xClient.postDeviceUpdate(deviceId, 5, allStreamNames, (float []){SENSOR_DATA.Humidity, SENSOR_DATA.Temperature, SENSOR_DATA.AccelX, SENSOR_DATA.AccelY, SENSOR_DATA.AccelZ}); |
jk431j | 9:3f5dfac96ac1 | 380 | pc.printf("Post response code: %d" CRLF, response); |
jk431j | 9:3f5dfac96ac1 | 381 | #endif |
jk431j | 8:b82d330e10e9 | 382 | timeService.getTimestamp(timestamp, &length); |
jk431j | 8:b82d330e10e9 | 383 | pc.printf("%s waiting for %d seconds... " CRLF , timestamp, commandDelay * commandPolls); |
jk431j | 8:b82d330e10e9 | 384 | }; |
jk431j | 4:08979e323c6e | 385 | |
jk431j | 9:3f5dfac96ac1 | 386 | // save old sensor data, we will use them to check for accelerometer change |
jk431j | 9:3f5dfac96ac1 | 387 | OLD_SENSOR_DATA = SENSOR_DATA; |
jk431j | 9:3f5dfac96ac1 | 388 | // sleep loop, check for accelerometer changes and pending commands |
jk431j | 7:721eb6bb68d3 | 389 | for (short idx=0; idx < commandPolls; idx++) { |
jk431j | 7:721eb6bb68d3 | 390 | // wait commandDelay seconds |
jk431j | 9:3f5dfac96ac1 | 391 | for (short delays=0; delays < commandDelay; delays++) { |
jk431j | 9:3f5dfac96ac1 | 392 | delay(1000); |
jk431j | 9:3f5dfac96ac1 | 393 | // if the buttons were pressed process them immediately |
jk431j | 9:3f5dfac96ac1 | 394 | process_buttons(); |
jk431j | 9:3f5dfac96ac1 | 395 | check_accelerometer_change(); |
jk431j | 9:3f5dfac96ac1 | 396 | // button 3 skips wait and sends data right away |
jk431j | 9:3f5dfac96ac1 | 397 | if (bSendDataNow || bStop) |
jk431j | 9:3f5dfac96ac1 | 398 | break; |
jk431j | 9:3f5dfac96ac1 | 399 | }; |
jk431j | 9:3f5dfac96ac1 | 400 | |
jk431j | 9:3f5dfac96ac1 | 401 | #ifdef COMMANDS_ENABLED |
jk431j | 7:721eb6bb68d3 | 402 | // and then query for commands |
jk431j | 8:b82d330e10e9 | 403 | { WATCHDOG |
jk431j | 8:b82d330e10e9 | 404 | pc.printf("\tQuery for pending commands ..." CRLF); |
jk431j | 8:b82d330e10e9 | 405 | response = m2xClient.listCommands(deviceId, on_command_found, NULL, "status=pending"); |
jk431j | 8:b82d330e10e9 | 406 | pc.printf("\tlistCommands response code: %d" CRLF, response); |
jk431j | 9:3f5dfac96ac1 | 407 | }; |
jk431j | 9:3f5dfac96ac1 | 408 | #endif |
jk431j | 9:3f5dfac96ac1 | 409 | |
jk431j | 9:3f5dfac96ac1 | 410 | //if button 3 was pressed skip the wait and send data right away |
jk431j | 9:3f5dfac96ac1 | 411 | if (bSendDataNow || bStop) { |
jk431j | 9:3f5dfac96ac1 | 412 | bSendDataNow = false; |
jk431j | 9:3f5dfac96ac1 | 413 | break; |
jk431j | 9:3f5dfac96ac1 | 414 | }; |
jk431j | 4:08979e323c6e | 415 | } |
jk431j | 7:721eb6bb68d3 | 416 | }; |
jk431j | 7:721eb6bb68d3 | 417 | |
jk431j | 7:721eb6bb68d3 | 418 | pc.printf("Done sending data. Still accepting SMS commands." CRLF); |
jk431j | 7:721eb6bb68d3 | 419 | bStop = false; |
jk431j | 7:721eb6bb68d3 | 420 | while (!bStop) { |
jk431j | 7:721eb6bb68d3 | 421 | delay(1000); |
jk431j | 7:721eb6bb68d3 | 422 | }; |
jk431j | 7:721eb6bb68d3 | 423 | |
jk431j | 7:721eb6bb68d3 | 424 | pc.printf("- - - - - - - THE END - - - - - - - " CRLF); |
jk431j | 7:721eb6bb68d3 | 425 | NVIC_SystemReset(); |
jk431j | 8:b82d330e10e9 | 426 | } |