kimutai ngetich
/
gps_accelerometer
getting location and activity
main.cpp@0:68ca78749806, 2019-03-11 (annotated)
- Committer:
- kimutaingetich
- Date:
- Mon Mar 11 09:24:37 2019 +0000
- Revision:
- 0:68ca78749806
time changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kimutaingetich | 0:68ca78749806 | 1 | #include "mbed.h" |
kimutaingetich | 0:68ca78749806 | 2 | #include "mbed_trace.h" |
kimutaingetich | 0:68ca78749806 | 3 | #include "mbed_events.h" |
kimutaingetich | 0:68ca78749806 | 4 | #include "LoRaWANInterface.h" |
kimutaingetich | 0:68ca78749806 | 5 | #include "SX1276_LoRaRadio.h" |
kimutaingetich | 0:68ca78749806 | 6 | #include "CayenneLPP.h" |
kimutaingetich | 0:68ca78749806 | 7 | #include "lora_radio_helper.h" |
kimutaingetich | 0:68ca78749806 | 8 | #include "standby.h" |
kimutaingetich | 0:68ca78749806 | 9 | #include "GPS.h" |
kimutaingetich | 0:68ca78749806 | 10 | #include "ADXL345_I2C.h" |
kimutaingetich | 0:68ca78749806 | 11 | |
kimutaingetich | 0:68ca78749806 | 12 | |
kimutaingetich | 0:68ca78749806 | 13 | #define GPSBaud 9600 |
kimutaingetich | 0:68ca78749806 | 14 | #define STANDBY_TIME_S 1 * 60 |
kimutaingetich | 0:68ca78749806 | 15 | #define SENSOR_READ_ATTEMPTS 3 |
kimutaingetich | 0:68ca78749806 | 16 | #define SENSOR_WAIT_TIME 3000 //slow sensor, no more than once per 2 seconds |
kimutaingetich | 0:68ca78749806 | 17 | |
kimutaingetich | 0:68ca78749806 | 18 | |
kimutaingetich | 0:68ca78749806 | 19 | |
kimutaingetich | 0:68ca78749806 | 20 | static uint32_t DEVADDR_1 = 0x260118F6; |
kimutaingetich | 0:68ca78749806 | 21 | static uint8_t NWKSKEY_1[] = { 0x90, 0xF9, 0x6E, 0x7E, 0x9C, 0x38, 0x75, 0xD5, 0x59, 0x75, 0x6D, 0x91, 0x62, 0x22, 0x73, 0x1C }; |
kimutaingetich | 0:68ca78749806 | 22 | static uint8_t APPSKEY_1[] = { 0x73, 0x0B, 0x09, 0xB7, 0x93, 0xBA, 0x69, 0xEF, 0x69, 0xC4, 0x0E, 0xEF, 0xBD, 0x43, 0x19, 0x61 }; |
kimutaingetich | 0:68ca78749806 | 23 | |
kimutaingetich | 0:68ca78749806 | 24 | |
kimutaingetich | 0:68ca78749806 | 25 | static Serial pc(SERIAL_TX, SERIAL_RX, 9600); |
kimutaingetich | 0:68ca78749806 | 26 | static GPS gps(PA_9, PB_7); |
kimutaingetich | 0:68ca78749806 | 27 | ADXL345_I2C accelerometer(D14, D15); |
kimutaingetich | 0:68ca78749806 | 28 | |
kimutaingetich | 0:68ca78749806 | 29 | |
kimutaingetich | 0:68ca78749806 | 30 | // The port we're sending and receiving on |
kimutaingetich | 0:68ca78749806 | 31 | #define MBED_CONF_LORA_APP_PORT 15 |
kimutaingetich | 0:68ca78749806 | 32 | |
kimutaingetich | 0:68ca78749806 | 33 | |
kimutaingetich | 0:68ca78749806 | 34 | |
kimutaingetich | 0:68ca78749806 | 35 | // EventQueue is required to dispatch events around |
kimutaingetich | 0:68ca78749806 | 36 | static EventQueue ev_queue; |
kimutaingetich | 0:68ca78749806 | 37 | |
kimutaingetich | 0:68ca78749806 | 38 | // Constructing Mbed LoRaWANInterface and passing it down the radio object. |
kimutaingetich | 0:68ca78749806 | 39 | static LoRaWANInterface lorawan(radio); |
kimutaingetich | 0:68ca78749806 | 40 | |
kimutaingetich | 0:68ca78749806 | 41 | // Application specific callbacks |
kimutaingetich | 0:68ca78749806 | 42 | static lorawan_app_callbacks_t callbacks; |
kimutaingetich | 0:68ca78749806 | 43 | |
kimutaingetich | 0:68ca78749806 | 44 | // LoRaWAN stack event handler |
kimutaingetich | 0:68ca78749806 | 45 | static void lora_event_handler(lorawan_event_t event); |
kimutaingetich | 0:68ca78749806 | 46 | |
kimutaingetich | 0:68ca78749806 | 47 | // Send a message over LoRaWAN |
kimutaingetich | 0:68ca78749806 | 48 | static void send_message() { |
kimutaingetich | 0:68ca78749806 | 49 | CayenneLPP payload(50); |
kimutaingetich | 0:68ca78749806 | 50 | |
kimutaingetich | 0:68ca78749806 | 51 | if( gps.sample() == 1) { |
kimutaingetich | 0:68ca78749806 | 52 | |
kimutaingetich | 0:68ca78749806 | 53 | float latitude = gps.latitude; |
kimutaingetich | 0:68ca78749806 | 54 | float longitude = gps.longitude; |
kimutaingetich | 0:68ca78749806 | 55 | float altitude= (gps.utc/100)+465; |
kimutaingetich | 0:68ca78749806 | 56 | |
kimutaingetich | 0:68ca78749806 | 57 | |
kimutaingetich | 0:68ca78749806 | 58 | printf("latitude: %0.4f, longitude: %0.4f, altitude: %f\r\n",latitude,longitude,altitude); |
kimutaingetich | 0:68ca78749806 | 59 | |
kimutaingetich | 0:68ca78749806 | 60 | payload.addGPS(2, latitude,longitude,altitude); |
kimutaingetich | 0:68ca78749806 | 61 | |
kimutaingetich | 0:68ca78749806 | 62 | |
kimutaingetich | 0:68ca78749806 | 63 | wait(1); |
kimutaingetich | 0:68ca78749806 | 64 | |
kimutaingetich | 0:68ca78749806 | 65 | } |
kimutaingetich | 0:68ca78749806 | 66 | else |
kimutaingetich | 0:68ca78749806 | 67 | { |
kimutaingetich | 0:68ca78749806 | 68 | printf("no gps detected"); |
kimutaingetich | 0:68ca78749806 | 69 | } |
kimutaingetich | 0:68ca78749806 | 70 | |
kimutaingetich | 0:68ca78749806 | 71 | int readings[3] = {0, 0, 0}; |
kimutaingetich | 0:68ca78749806 | 72 | |
kimutaingetich | 0:68ca78749806 | 73 | printf("\n Animal activity \n"); |
kimutaingetich | 0:68ca78749806 | 74 | |
kimutaingetich | 0:68ca78749806 | 75 | printf("Device ID is: 0x%02x\n", accelerometer.getDeviceID()); |
kimutaingetich | 0:68ca78749806 | 76 | wait(.001); |
kimutaingetich | 0:68ca78749806 | 77 | |
kimutaingetich | 0:68ca78749806 | 78 | if (accelerometer.setPowerControl(0x00)){ |
kimutaingetich | 0:68ca78749806 | 79 | printf("didn't intitialize power control\n"); |
kimutaingetich | 0:68ca78749806 | 80 | } |
kimutaingetich | 0:68ca78749806 | 81 | //Full resolution, +/-16g, 4mg/LSB. |
kimutaingetich | 0:68ca78749806 | 82 | wait(.001); |
kimutaingetich | 0:68ca78749806 | 83 | |
kimutaingetich | 0:68ca78749806 | 84 | if(accelerometer.setDataFormatControl(0x0B)){ |
kimutaingetich | 0:68ca78749806 | 85 | printf("didn't set data format\n"); |
kimutaingetich | 0:68ca78749806 | 86 | } |
kimutaingetich | 0:68ca78749806 | 87 | wait(.001); |
kimutaingetich | 0:68ca78749806 | 88 | |
kimutaingetich | 0:68ca78749806 | 89 | //3.2kHz data rate. |
kimutaingetich | 0:68ca78749806 | 90 | if(accelerometer.setDataRate(ADXL345_3200HZ)){ |
kimutaingetich | 0:68ca78749806 | 91 | printf("didn't set data rate\n"); |
kimutaingetich | 0:68ca78749806 | 92 | } |
kimutaingetich | 0:68ca78749806 | 93 | wait(.001); |
kimutaingetich | 0:68ca78749806 | 94 | |
kimutaingetich | 0:68ca78749806 | 95 | //Measurement mode. |
kimutaingetich | 0:68ca78749806 | 96 | |
kimutaingetich | 0:68ca78749806 | 97 | if(accelerometer.setPowerControl(MeasurementMode)) { |
kimutaingetich | 0:68ca78749806 | 98 | printf("didn't set the power control to measurement\n"); |
kimutaingetich | 0:68ca78749806 | 99 | } |
kimutaingetich | 0:68ca78749806 | 100 | wait(0.01); |
kimutaingetich | 0:68ca78749806 | 101 | |
kimutaingetich | 0:68ca78749806 | 102 | accelerometer.getOutput(readings); |
kimutaingetich | 0:68ca78749806 | 103 | |
kimutaingetich | 0:68ca78749806 | 104 | |
kimutaingetich | 0:68ca78749806 | 105 | printf("X-axis= %i, Y-axis= %i, Z-axis= %i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]); |
kimutaingetich | 0:68ca78749806 | 106 | |
kimutaingetich | 0:68ca78749806 | 107 | payload.addAccelerometer(3, readings[0], readings[1], readings[2]); |
kimutaingetich | 0:68ca78749806 | 108 | |
kimutaingetich | 0:68ca78749806 | 109 | wait(2); |
kimutaingetich | 0:68ca78749806 | 110 | |
kimutaingetich | 0:68ca78749806 | 111 | |
kimutaingetich | 0:68ca78749806 | 112 | |
kimutaingetich | 0:68ca78749806 | 113 | |
kimutaingetich | 0:68ca78749806 | 114 | |
kimutaingetich | 0:68ca78749806 | 115 | |
kimutaingetich | 0:68ca78749806 | 116 | if (payload.getSize() > 0) { |
kimutaingetich | 0:68ca78749806 | 117 | printf("Sending %d bytes\n", payload.getSize()); |
kimutaingetich | 0:68ca78749806 | 118 | |
kimutaingetich | 0:68ca78749806 | 119 | int16_t retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, payload.getBuffer(), payload.getSize(), MSG_UNCONFIRMED_FLAG); |
kimutaingetich | 0:68ca78749806 | 120 | |
kimutaingetich | 0:68ca78749806 | 121 | // for some reason send() ret\urns -1... I cannot find out why, the stack returns the right number. I feel that this is some weird Emscripten quirk |
kimutaingetich | 0:68ca78749806 | 122 | if (retcode < 0) { |
kimutaingetich | 0:68ca78749806 | 123 | retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - duty cycle violation\n") |
kimutaingetich | 0:68ca78749806 | 124 | : printf("send() - Error code %d\n", retcode); |
kimutaingetich | 0:68ca78749806 | 125 | |
kimutaingetich | 0:68ca78749806 | 126 | standby(STANDBY_TIME_S); |
kimutaingetich | 0:68ca78749806 | 127 | } |
kimutaingetich | 0:68ca78749806 | 128 | |
kimutaingetich | 0:68ca78749806 | 129 | printf("%d bytes scheduled for transmission\n", retcode); |
kimutaingetich | 0:68ca78749806 | 130 | } |
kimutaingetich | 0:68ca78749806 | 131 | |
kimutaingetich | 0:68ca78749806 | 132 | else |
kimutaingetich | 0:68ca78749806 | 133 | standby(STANDBY_TIME_S); |
kimutaingetich | 0:68ca78749806 | 134 | } |
kimutaingetich | 0:68ca78749806 | 135 | |
kimutaingetich | 0:68ca78749806 | 136 | int main() { |
kimutaingetich | 0:68ca78749806 | 137 | set_time(0); |
kimutaingetich | 0:68ca78749806 | 138 | |
kimutaingetich | 0:68ca78749806 | 139 | printf("\r==========================\n"); |
kimutaingetich | 0:68ca78749806 | 140 | printf("\r cattle monitor \n"); |
kimutaingetich | 0:68ca78749806 | 141 | printf("\r==========================\n"); |
kimutaingetich | 0:68ca78749806 | 142 | |
kimutaingetich | 0:68ca78749806 | 143 | printf("Sending every %d seconds\n", STANDBY_TIME_S); |
kimutaingetich | 0:68ca78749806 | 144 | |
kimutaingetich | 0:68ca78749806 | 145 | // Enable trace output for this demo, so we can see what the LoRaWAN stack does |
kimutaingetich | 0:68ca78749806 | 146 | mbed_trace_init(); |
kimutaingetich | 0:68ca78749806 | 147 | |
kimutaingetich | 0:68ca78749806 | 148 | if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) { |
kimutaingetich | 0:68ca78749806 | 149 | printf("LoRa initialization failed!\n"); |
kimutaingetich | 0:68ca78749806 | 150 | return -1; |
kimutaingetich | 0:68ca78749806 | 151 | } |
kimutaingetich | 0:68ca78749806 | 152 | |
kimutaingetich | 0:68ca78749806 | 153 | // prepare application callbacks |
kimutaingetich | 0:68ca78749806 | 154 | callbacks.events = mbed::callback(lora_event_handler); |
kimutaingetich | 0:68ca78749806 | 155 | lorawan.add_app_callbacks(&callbacks); |
kimutaingetich | 0:68ca78749806 | 156 | |
kimutaingetich | 0:68ca78749806 | 157 | // Disable adaptive data rating |
kimutaingetich | 0:68ca78749806 | 158 | if (lorawan.disable_adaptive_datarate() != LORAWAN_STATUS_OK) { |
kimutaingetich | 0:68ca78749806 | 159 | printf("\rdisable_adaptive_datarate failed!\n"); |
kimutaingetich | 0:68ca78749806 | 160 | return -1; |
kimutaingetich | 0:68ca78749806 | 161 | } |
kimutaingetich | 0:68ca78749806 | 162 | |
kimutaingetich | 0:68ca78749806 | 163 | lorawan.set_datarate(0); // SF12BW125 |
kimutaingetich | 0:68ca78749806 | 164 | |
kimutaingetich | 0:68ca78749806 | 165 | lorawan_connect_t connect_params; |
kimutaingetich | 0:68ca78749806 | 166 | connect_params.connect_type = LORAWAN_CONNECTION_ABP; |
kimutaingetich | 0:68ca78749806 | 167 | |
kimutaingetich | 0:68ca78749806 | 168 | connect_params.connection_u.abp.dev_addr = DEVADDR_1; |
kimutaingetich | 0:68ca78749806 | 169 | connect_params.connection_u.abp.nwk_skey = NWKSKEY_1; |
kimutaingetich | 0:68ca78749806 | 170 | connect_params.connection_u.abp.app_skey = APPSKEY_1; |
kimutaingetich | 0:68ca78749806 | 171 | |
kimutaingetich | 0:68ca78749806 | 172 | lorawan_status_t retcode = lorawan.connect(connect_params); |
kimutaingetich | 0:68ca78749806 | 173 | |
kimutaingetich | 0:68ca78749806 | 174 | if (retcode == LORAWAN_STATUS_OK || |
kimutaingetich | 0:68ca78749806 | 175 | retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { |
kimutaingetich | 0:68ca78749806 | 176 | } else { |
kimutaingetich | 0:68ca78749806 | 177 | printf("Connection error, code = %d\n", retcode); |
kimutaingetich | 0:68ca78749806 | 178 | return -1; |
kimutaingetich | 0:68ca78749806 | 179 | } |
kimutaingetich | 0:68ca78749806 | 180 | |
kimutaingetich | 0:68ca78749806 | 181 | printf("Connection - In Progress ...\r\n"); |
kimutaingetich | 0:68ca78749806 | 182 | |
kimutaingetich | 0:68ca78749806 | 183 | // make your event queue dispatching events forever |
kimutaingetich | 0:68ca78749806 | 184 | ev_queue.dispatch_forever(); |
kimutaingetich | 0:68ca78749806 | 185 | } |
kimutaingetich | 0:68ca78749806 | 186 | |
kimutaingetich | 0:68ca78749806 | 187 | // This is called from RX_DONE, so whenever a message came in |
kimutaingetich | 0:68ca78749806 | 188 | static void receive_message() |
kimutaingetich | 0:68ca78749806 | 189 | { |
kimutaingetich | 0:68ca78749806 | 190 | uint8_t rx_buffer[50] = { 0 }; |
kimutaingetich | 0:68ca78749806 | 191 | int16_t retcode; |
kimutaingetich | 0:68ca78749806 | 192 | retcode = lorawan.receive(MBED_CONF_LORA_APP_PORT, rx_buffer, |
kimutaingetich | 0:68ca78749806 | 193 | sizeof(rx_buffer), |
kimutaingetich | 0:68ca78749806 | 194 | MSG_UNCONFIRMED_FLAG); |
kimutaingetich | 0:68ca78749806 | 195 | |
kimutaingetich | 0:68ca78749806 | 196 | if (retcode < 0) { |
kimutaingetich | 0:68ca78749806 | 197 | printf("receive() - Error code %d\n", retcode); |
kimutaingetich | 0:68ca78749806 | 198 | return; |
kimutaingetich | 0:68ca78749806 | 199 | } |
kimutaingetich | 0:68ca78749806 | 200 | |
kimutaingetich | 0:68ca78749806 | 201 | printf("Data received on port %d (length %d): ", MBED_CONF_LORA_APP_PORT, retcode); |
kimutaingetich | 0:68ca78749806 | 202 | |
kimutaingetich | 0:68ca78749806 | 203 | for (uint8_t i = 0; i < retcode; i++) { |
kimutaingetich | 0:68ca78749806 | 204 | printf("%02x ", rx_buffer[i]); |
kimutaingetich | 0:68ca78749806 | 205 | } |
kimutaingetich | 0:68ca78749806 | 206 | printf("\n"); |
kimutaingetich | 0:68ca78749806 | 207 | } |
kimutaingetich | 0:68ca78749806 | 208 | |
kimutaingetich | 0:68ca78749806 | 209 | // Event handler |
kimutaingetich | 0:68ca78749806 | 210 | static void lora_event_handler(lorawan_event_t event) { |
kimutaingetich | 0:68ca78749806 | 211 | switch (event) { |
kimutaingetich | 0:68ca78749806 | 212 | case CONNECTED: |
kimutaingetich | 0:68ca78749806 | 213 | printf("Connection - Successful\n"); |
kimutaingetich | 0:68ca78749806 | 214 | ev_queue.call_in(1000, &send_message); |
kimutaingetich | 0:68ca78749806 | 215 | break; |
kimutaingetich | 0:68ca78749806 | 216 | case DISCONNECTED: |
kimutaingetich | 0:68ca78749806 | 217 | ev_queue.break_dispatch(); |
kimutaingetich | 0:68ca78749806 | 218 | printf("Disconnected Successfully\n"); |
kimutaingetich | 0:68ca78749806 | 219 | break; |
kimutaingetich | 0:68ca78749806 | 220 | case TX_DONE: |
kimutaingetich | 0:68ca78749806 | 221 | printf("Message Sent to Network Server\n"); |
kimutaingetich | 0:68ca78749806 | 222 | standby(STANDBY_TIME_S); |
kimutaingetich | 0:68ca78749806 | 223 | break; |
kimutaingetich | 0:68ca78749806 | 224 | case TX_TIMEOUT: |
kimutaingetich | 0:68ca78749806 | 225 | case TX_ERROR: |
kimutaingetich | 0:68ca78749806 | 226 | case TX_CRYPTO_ERROR: |
kimutaingetich | 0:68ca78749806 | 227 | case TX_SCHEDULING_ERROR: |
kimutaingetich | 0:68ca78749806 | 228 | printf("Transmission Error - EventCode = %d\n", event); |
kimutaingetich | 0:68ca78749806 | 229 | standby(STANDBY_TIME_S); |
kimutaingetich | 0:68ca78749806 | 230 | break; |
kimutaingetich | 0:68ca78749806 | 231 | case RX_DONE: |
kimutaingetich | 0:68ca78749806 | 232 | printf("Received message from Network Server\n"); |
kimutaingetich | 0:68ca78749806 | 233 | receive_message(); |
kimutaingetich | 0:68ca78749806 | 234 | break; |
kimutaingetich | 0:68ca78749806 | 235 | case RX_TIMEOUT: |
kimutaingetich | 0:68ca78749806 | 236 | case RX_ERROR: |
kimutaingetich | 0:68ca78749806 | 237 | printf("Error in reception - Code = %d\n", event); |
kimutaingetich | 0:68ca78749806 | 238 | break; |
kimutaingetich | 0:68ca78749806 | 239 | case JOIN_FAILURE: |
kimutaingetich | 0:68ca78749806 | 240 | printf("OTAA Failed - Check Keys\n"); |
kimutaingetich | 0:68ca78749806 | 241 | break; |
kimutaingetich | 0:68ca78749806 | 242 | default: |
kimutaingetich | 0:68ca78749806 | 243 | MBED_ASSERT("Unknown Event"); |
kimutaingetich | 0:68ca78749806 | 244 | } |
kimutaingetich | 0:68ca78749806 | 245 | } |