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