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:
bowenfeng
Date:
Thu Dec 22 09:32:33 2016 +0000
Revision:
87:ca75c5e785a7
Parent:
86:5ff234988f53
Join latest hiking activity instead.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fkellermavnet 68:6e311c747045 1 /* ===================================================================
fkellermavnet 68:6e311c747045 2 Copyright © 2016, AVNET Inc.
fkellermavnet 68:6e311c747045 3
fkellermavnet 68:6e311c747045 4 Licensed under the Apache License, Version 2.0 (the "License");
fkellermavnet 68:6e311c747045 5 you may not use this file except in compliance with the License.
fkellermavnet 68:6e311c747045 6 You may obtain a copy of the License at
fkellermavnet 68:6e311c747045 7
fkellermavnet 68:6e311c747045 8 http://www.apache.org/licenses/LICENSE-2.0
fkellermavnet 68:6e311c747045 9
fkellermavnet 68:6e311c747045 10 Unless required by applicable law or agreed to in writing,
fkellermavnet 68:6e311c747045 11 software distributed under the License is distributed on an
fkellermavnet 68:6e311c747045 12 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
fkellermavnet 68:6e311c747045 13 either express or implied. See the License for the specific
fkellermavnet 68:6e311c747045 14 language governing permissions and limitations under the License.
fkellermavnet 68:6e311c747045 15
fkellermavnet 68:6e311c747045 16 ======================================================================== */
fkellermavnet 68:6e311c747045 17
stefanrousseau 55:3abf9e3f42e6 18 #include "mbed.h"
JMF 0:9d5134074d84 19 #include <cctype>
JMF 0:9d5134074d84 20 #include <string>
JMF 2:0e2ef866af95 21 #include "config_me.h"
stefanrousseau 4:f83bedd9cab4 22 #include "sensors.h"
stefanrousseau 61:f6b93129f954 23 #include "cell_modem.h"
stefanrousseau 11:e6602513730f 24 #include "hardware.h"
stefanrousseau 11:e6602513730f 25
stefanrousseau 61:f6b93129f954 26 I2C i2c(PTC11, PTC10); //SDA, SCL -- define the I2C pins being used
stefanrousseau 56:cb42ff383dab 27 MODSERIAL pc(USBTX, USBRX, 256, 256); // tx, rx with default tx, rx buffer sizes
stefanrousseau 63:90d7c69993cd 28 MODSERIAL mdm(PTD3, PTD2, 4096, 4096);
stefanrousseau 16:17c5916f2d12 29 DigitalOut led_green(LED_GREEN);
stefanrousseau 16:17c5916f2d12 30 DigitalOut led_red(LED_RED);
stefanrousseau 16:17c5916f2d12 31 DigitalOut led_blue(LED_BLUE);
JMF 0:9d5134074d84 32
bowenfeng 85:43d791cd5967 33 #define OK_COLOR 0x2
bowenfeng 85:43d791cd5967 34 #define ERROR_COLOR 0x1
bowenfeng 85:43d791cd5967 35
JMF 0:9d5134074d84 36
stefanrousseau 3:26b3cc155f39 37 //********************************************************************************************************************************************
stefanrousseau 12:7c94ec5069dc 38 //* Create string with sensor readings that can be sent to flow as an HTTP get
stefanrousseau 3:26b3cc155f39 39 //********************************************************************************************************************************************
bowenfeng 84:0bf8168b690a 40 K64F_Sensors_t SENSOR_DATA = {
stefanrousseau 12:7c94ec5069dc 41 .Temperature = "0",
stefanrousseau 12:7c94ec5069dc 42 .Humidity = "0",
stefanrousseau 12:7c94ec5069dc 43 .AccelX = "0",
stefanrousseau 12:7c94ec5069dc 44 .AccelY = "0",
stefanrousseau 12:7c94ec5069dc 45 .AccelZ = "0",
stefanrousseau 12:7c94ec5069dc 46 .MagnetometerX = "0",
stefanrousseau 12:7c94ec5069dc 47 .MagnetometerY = "0",
stefanrousseau 12:7c94ec5069dc 48 .MagnetometerZ = "0",
stefanrousseau 12:7c94ec5069dc 49 .AmbientLightVis = "0",
stefanrousseau 12:7c94ec5069dc 50 .AmbientLightIr = "0",
stefanrousseau 12:7c94ec5069dc 51 .UVindex = "0",
stefanrousseau 12:7c94ec5069dc 52 .Proximity = "0",
stefanrousseau 12:7c94ec5069dc 53 .Temperature_Si7020 = "0",
stefanrousseau 55:3abf9e3f42e6 54 .Humidity_Si7020 = "0",
stefanrousseau 55:3abf9e3f42e6 55 .Virtual_Sensor1 = "0",
stefanrousseau 55:3abf9e3f42e6 56 .Virtual_Sensor2 = "0",
stefanrousseau 55:3abf9e3f42e6 57 .Virtual_Sensor3 = "0",
stefanrousseau 55:3abf9e3f42e6 58 .Virtual_Sensor4 = "0",
stefanrousseau 55:3abf9e3f42e6 59 .Virtual_Sensor5 = "0",
stefanrousseau 55:3abf9e3f42e6 60 .Virtual_Sensor6 = "0",
stefanrousseau 55:3abf9e3f42e6 61 .Virtual_Sensor7 = "0",
stefanrousseau 71:45a5e426df81 62 .Virtual_Sensor8 = "0",
stefanrousseau 72:b500e1507b5f 63 .GPS_Satellites = "0",
stefanrousseau 71:45a5e426df81 64 .GPS_Latitude = "0",
stefanrousseau 71:45a5e426df81 65 .GPS_Longitude = "0",
stefanrousseau 71:45a5e426df81 66 .GPS_Altitude = "0",
stefanrousseau 71:45a5e426df81 67 .GPS_Speed = "0",
stefanrousseau 71:45a5e426df81 68 .GPS_Course = "0"
stefanrousseau 3:26b3cc155f39 69 };
stefanrousseau 12:7c94ec5069dc 70
bowenfeng 85:43d791cd5967 71 char hid[20] = {0};
bowenfeng 85:43d791cd5967 72 char sid[20] = {0};
bowenfeng 85:43d791cd5967 73 char sessionName[20] = {0};
bowenfeng 85:43d791cd5967 74
bowenfeng 84:0bf8168b690a 75 void display_app_firmware_version(void) {
bowenfeng 85:43d791cd5967 76 PUTS("\r\n\r\nHiking Pal Firmware: Release 1.0 - built: "__DATE__" "__TIME__"\r\n\r\n");
fkellermavnet 77:c65eae5b9958 77 }
fkellermavnet 77:c65eae5b9958 78
stefanrousseau 3:26b3cc155f39 79 //Periodic timer
stefanrousseau 3:26b3cc155f39 80 Ticker OneMsTicker;
stefanrousseau 3:26b3cc155f39 81 volatile bool bTimerExpiredFlag = false;
stefanrousseau 3:26b3cc155f39 82 int OneMsTicks = 0;
stefanrousseau 3:26b3cc155f39 83 int iTimer1Interval_ms = 1000;
stefanrousseau 3:26b3cc155f39 84 //********************************************************************************************************************************************
stefanrousseau 3:26b3cc155f39 85 //* Periodic 1ms timer tick
stefanrousseau 3:26b3cc155f39 86 //********************************************************************************************************************************************
bowenfeng 84:0bf8168b690a 87 void OneMsFunction() {
stefanrousseau 3:26b3cc155f39 88 OneMsTicks++;
bowenfeng 84:0bf8168b690a 89 if ((OneMsTicks % iTimer1Interval_ms) == 0) {
stefanrousseau 3:26b3cc155f39 90 bTimerExpiredFlag = true;
stefanrousseau 3:26b3cc155f39 91 }
stefanrousseau 3:26b3cc155f39 92 } //OneMsFunction()
stefanrousseau 3:26b3cc155f39 93
stefanrousseau 16:17c5916f2d12 94 //********************************************************************************************************************************************
stefanrousseau 16:17c5916f2d12 95 //* Set the RGB LED's Color
stefanrousseau 16:17c5916f2d12 96 //* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue)
stefanrousseau 16:17c5916f2d12 97 //********************************************************************************************************************************************
bowenfeng 84:0bf8168b690a 98 void SetLedColor(unsigned char ucColor) {
stefanrousseau 16:17c5916f2d12 99 //Note that when an LED is on, you write a 0 to it:
stefanrousseau 16:17c5916f2d12 100 led_red = !(ucColor & 0x1); //bit 0
stefanrousseau 16:17c5916f2d12 101 led_green = !(ucColor & 0x2); //bit 1
stefanrousseau 16:17c5916f2d12 102 led_blue = !(ucColor & 0x4); //bit 2
stefanrousseau 16:17c5916f2d12 103 } //SetLedColor()
stefanrousseau 16:17c5916f2d12 104
bowenfeng 84:0bf8168b690a 105 void extract_longlong(const char* s, char v[]) {
bowenfeng 84:0bf8168b690a 106 long long value = strtoll(s, NULL, 0);
bowenfeng 84:0bf8168b690a 107 sprintf(v, "%lld", value);
bowenfeng 84:0bf8168b690a 108 }
bowenfeng 84:0bf8168b690a 109
bowenfeng 87:ca75c5e785a7 110 long long find_longlong(const char* s, const char* token, const char** end) {
bowenfeng 87:ca75c5e785a7 111 const char* tokenBegin = strstr(s, token);
bowenfeng 87:ca75c5e785a7 112 if (tokenBegin != 0) {
bowenfeng 87:ca75c5e785a7 113 *end = tokenBegin + strlen(token);
bowenfeng 87:ca75c5e785a7 114 return strtoll(tokenBegin + strlen(token), NULL, 0);
bowenfeng 87:ca75c5e785a7 115 }
bowenfeng 87:ca75c5e785a7 116 return 0;
bowenfeng 87:ca75c5e785a7 117 }
bowenfeng 87:ca75c5e785a7 118
bowenfeng 84:0bf8168b690a 119 void find_longlong(const char* s, const char* token, char v[]) {
bowenfeng 84:0bf8168b690a 120 const char* tokenBegin = strstr(s, token);
bowenfeng 84:0bf8168b690a 121 if (tokenBegin != 0) {
bowenfeng 84:0bf8168b690a 122 extract_longlong(tokenBegin + strlen(token), v);
bowenfeng 84:0bf8168b690a 123 }
bowenfeng 84:0bf8168b690a 124 }
bowenfeng 84:0bf8168b690a 125
bowenfeng 87:ca75c5e785a7 126
bowenfeng 85:43d791cd5967 127 int send_receive(char* request, char* response) {
bowenfeng 85:43d791cd5967 128 int result = cell_modem_Sendreceive(request, response);
bowenfeng 85:43d791cd5967 129 SetLedColor(result ? OK_COLOR : ERROR_COLOR);
bowenfeng 85:43d791cd5967 130 return result;
bowenfeng 85:43d791cd5967 131 }
bowenfeng 85:43d791cd5967 132
bowenfeng 85:43d791cd5967 133 int send_only(char* request) {
bowenfeng 85:43d791cd5967 134 char response[512];
bowenfeng 85:43d791cd5967 135 return send_receive(request, response);
bowenfeng 85:43d791cd5967 136 }
bowenfeng 85:43d791cd5967 137
bowenfeng 87:ca75c5e785a7 138 void find_latest_hiking(char hikingId[]) {
bowenfeng 84:0bf8168b690a 139 char request[512];
bowenfeng 84:0bf8168b690a 140 char response[512];
bowenfeng 84:0bf8168b690a 141 sprintf(request, "GET %s/hikings HTTP/1.1\r\nHost: %s\r\n\r\n", FLOW_BASE_URL, MY_SERVER_URL);
bowenfeng 85:43d791cd5967 142 if (send_receive(&request[0], &response[0])) {
bowenfeng 87:ca75c5e785a7 143 long long llv;
bowenfeng 87:ca75c5e785a7 144 long long latestId = 0;
bowenfeng 87:ca75c5e785a7 145 const char* begin = response;
bowenfeng 87:ca75c5e785a7 146 PRINTF("%s\n\n", begin);
bowenfeng 87:ca75c5e785a7 147
bowenfeng 87:ca75c5e785a7 148 char token[] = "\"id\":";
bowenfeng 87:ca75c5e785a7 149 for (;;) {
bowenfeng 87:ca75c5e785a7 150 llv = find_longlong(begin, token, &begin);
bowenfeng 87:ca75c5e785a7 151
bowenfeng 87:ca75c5e785a7 152 PRINTF("---> %lld\n", llv);
bowenfeng 87:ca75c5e785a7 153 PRINTF("%s\n", begin);
bowenfeng 87:ca75c5e785a7 154
bowenfeng 87:ca75c5e785a7 155 if (llv == 0) {
bowenfeng 87:ca75c5e785a7 156 break;
bowenfeng 87:ca75c5e785a7 157 }
bowenfeng 87:ca75c5e785a7 158 if (llv > latestId) {
bowenfeng 87:ca75c5e785a7 159 latestId = llv;
bowenfeng 87:ca75c5e785a7 160 }
bowenfeng 87:ca75c5e785a7 161 }
bowenfeng 87:ca75c5e785a7 162 sprintf(hikingId, "%lld", latestId);
bowenfeng 87:ca75c5e785a7 163 PRINTF("LATEST HIKING ID: %lld", latestId);
bowenfeng 84:0bf8168b690a 164 }
bowenfeng 84:0bf8168b690a 165 }
bowenfeng 84:0bf8168b690a 166
bowenfeng 84:0bf8168b690a 167 void join_hiking(const char* hikingId, const char* name, char sessionId[]) {
bowenfeng 84:0bf8168b690a 168 char request[512];
bowenfeng 84:0bf8168b690a 169 char response[512];
bowenfeng 84:0bf8168b690a 170 sprintf(request, "GET %s/hikings/%s/sessions?name=%s HTTP/1.1\r\nHost: %s\r\n\r\n", FLOW_BASE_URL, hikingId, name, MY_SERVER_URL);
bowenfeng 85:43d791cd5967 171 if (send_receive(&request[0], &response[0])) {
bowenfeng 84:0bf8168b690a 172 find_longlong(response, "\"id\":", sessionId);
bowenfeng 84:0bf8168b690a 173 }
bowenfeng 84:0bf8168b690a 174 }
bowenfeng 84:0bf8168b690a 175
bowenfeng 85:43d791cd5967 176 void generate_move_request(char request[], const char* hid, const char* sid) {
bowenfeng 85:43d791cd5967 177 sprintf(
bowenfeng 85:43d791cd5967 178 request,
bowenfeng 85:43d791cd5967 179 "GET %s/hikings/%s/sessions/%s/moves?lat=%s&lng=%s HTTP/1.1\r\nHost: %s\r\n\r\n",
bowenfeng 85:43d791cd5967 180 FLOW_BASE_URL,
bowenfeng 85:43d791cd5967 181 hid,
bowenfeng 85:43d791cd5967 182 sid,
bowenfeng 85:43d791cd5967 183 SENSOR_DATA.GPS_Latitude,
bowenfeng 85:43d791cd5967 184 SENSOR_DATA.GPS_Longitude,
bowenfeng 85:43d791cd5967 185 MY_SERVER_URL);
bowenfeng 85:43d791cd5967 186 }
bowenfeng 85:43d791cd5967 187 void report_move(const char* hid, const char* sid) {
bowenfeng 85:43d791cd5967 188 char request[512];
bowenfeng 85:43d791cd5967 189 generate_move_request(request, hid, sid);
bowenfeng 85:43d791cd5967 190 send_only(&request[0]);
bowenfeng 85:43d791cd5967 191 }
bowenfeng 85:43d791cd5967 192
JMF 0:9d5134074d84 193 int main() {
stefanrousseau 72:b500e1507b5f 194 //delay so that the debug terminal can open after power-on reset:
fkellermavnet 77:c65eae5b9958 195 wait (5.0);
stefanrousseau 61:f6b93129f954 196 pc.baud(115200);
fkellermavnet 77:c65eae5b9958 197
fkellermavnet 77:c65eae5b9958 198 display_app_firmware_version();
fkellermavnet 77:c65eae5b9958 199
bowenfeng 85:43d791cd5967 200 PRINTF(GRN "Hiking Pal tracking device started!\r\n\r\n");
JMF 0:9d5134074d84 201
stefanrousseau 61:f6b93129f954 202 //Initialize the I2C sensors that are present
stefanrousseau 11:e6602513730f 203 sensors_init();
stefanrousseau 12:7c94ec5069dc 204 read_sensors();
stefanrousseau 11:e6602513730f 205
stefanrousseau 61:f6b93129f954 206 // Set LED to RED until init finishes
stefanrousseau 61:f6b93129f954 207 SetLedColor(0x1); //Red
JMF 0:9d5134074d84 208 // Initialize the modem
stefanrousseau 64:09004cd610df 209 PRINTF("\r\n");
stefanrousseau 61:f6b93129f954 210 cell_modem_init();
fkellermavnet 77:c65eae5b9958 211 display_wnc_firmware_rev();
fkellermavnet 77:c65eae5b9958 212
stefanrousseau 61:f6b93129f954 213 // Set LED BLUE for partial init
stefanrousseau 61:f6b93129f954 214 SetLedColor(0x4); //Blue
JMF 0:9d5134074d84 215
stefanrousseau 3:26b3cc155f39 216 //Create a 1ms timer tick function:
stefanrousseau 61:f6b93129f954 217 iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS;
stefanrousseau 3:26b3cc155f39 218 OneMsTicker.attach(OneMsFunction, 0.001f) ;
bowenfeng 84:0bf8168b690a 219
bowenfeng 84:0bf8168b690a 220 sprintf(sessionName, "IoT-kit-%d", rand() % 1000);
bowenfeng 84:0bf8168b690a 221
bowenfeng 87:ca75c5e785a7 222 find_latest_hiking(hid);
bowenfeng 84:0bf8168b690a 223 PRINTF("Found Hiking ID: ");
bowenfeng 84:0bf8168b690a 224 PRINTF(hid);
bowenfeng 84:0bf8168b690a 225 PRINTF("\r\n");
bowenfeng 84:0bf8168b690a 226
bowenfeng 84:0bf8168b690a 227 join_hiking(hid, sessionName, sid);
bowenfeng 84:0bf8168b690a 228 PRINTF("Allocated Session ID: ");
bowenfeng 84:0bf8168b690a 229 PRINTF(sid);
bowenfeng 84:0bf8168b690a 230 PRINTF("\r\n");
fkellermavnet 26:8d6e7e7cdcae 231
JMF 2:0e2ef866af95 232 // Send and receive data perpetually
JMF 2:0e2ef866af95 233 while(1) {
bowenfeng 84:0bf8168b690a 234 if (bTimerExpiredFlag) {
stefanrousseau 3:26b3cc155f39 235 bTimerExpiredFlag = false;
stefanrousseau 4:f83bedd9cab4 236 read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor
bowenfeng 85:43d791cd5967 237 report_move(hid, sid);
bowenfeng 86:5ff234988f53 238 }
stefanrousseau 3:26b3cc155f39 239 } //forever loop
JMF 0:9d5134074d84 240 }