From 37c406e6225b176f5ce76441ea294d29b70f9ebd Mon Sep 17 00:00:00 2001 From: Praneeth Challagonda <58634765+Praneethsvch@users.noreply.github.com> Date: Wed, 11 Nov 2020 15:57:07 -0500 Subject: [PATCH 1/6] added cfg via uplink. added new ttn payload decoder .js file --- README.md | 2 +- src/lorawan.cpp | 78 ++++++++++++++++++++++++++------------------ ttnPayloadDecoder.js | 47 ++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 33 deletions(-) create mode 100644 ttnPayloadDecoder.js diff --git a/README.md b/README.md index 206d5726..8652b644 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Flood Sense Sensor Library -This repository contains the source code for the Floodsense sensor which uses ultrasonic sensor technology to detect floods and send the data over LoRa using LoRaWAN protocol. +This repository contains the source code for the Floodsense sensor which uses ultrasonic sensor technology to detect floods and send the data over LoRa using LoRaWAN protocol. [Here](https://github.com/floodsense/sensor_experiments) is another repo containing sensor experiments, analysis and additional support related to this library. **Table of Contents:** diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 17d9663b..fe8c383b 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -5,6 +5,7 @@ #include "lmicpinmappings.h" #include "sensorcfg.h" #include "maxbotix.h" +#include static osjob_t sendjob; @@ -13,7 +14,8 @@ unsigned int TX_INTERVAL; unsigned char lora_packet[5]; -bool TX_COMPLETED = false; +bool TX_COMPLETED = false; // Set to false on start and after sleep; is set to true when an uplink is successful +bool UPDATE_CONFIG = true; // Set to true at start and when there is a change in sensor cfg; used to send sensor cfg via uplink void os_getArtEui (u1_t* buf) { @@ -178,6 +180,7 @@ void onEvent (ev_t ev) { process_received_downlink(); } TX_COMPLETED = true; + UPDATE_CONFIG = false; break; case EV_LOST_TSYNC: Serial.println(F("EV_LOST_TSYNC")); @@ -299,6 +302,8 @@ void process_received_downlink(void) { |Number of readings per measurement| Sampling Rate |Sensor Mode | Duty Cycle in seconds | | 1 byte | 1 byte | 2 bytes | 2 bytes | */ + // set UPDATE_CONFIG to true + UPDATE_CONFIG = true; String str_downlink = String("Processing received downlink...."); writeToSDCard(str_downlink); unsigned int downlink_payload_size = LMIC.dataLen; @@ -310,7 +315,6 @@ void process_received_downlink(void) { switch(downlink_payload_size){ case 1: case 2: - for (int i = 0; i < downlink_payload_size; i++) { dutycycle = (LMIC.frame[LMIC.dataBeg + i]) | ( dutycycle << 8*i); } @@ -322,7 +326,6 @@ void process_received_downlink(void) { break; case 3: - for (int i = 0; i < 2; i++) { dutycycle = (LMIC.frame[LMIC.dataBeg + i]) | ( dutycycle << 8*i); } @@ -341,7 +344,6 @@ void process_received_downlink(void) { break; case 5: - for (int i = 0; i < 2; i++) { dutycycle = (LMIC.frame[LMIC.dataBeg + i]) | ( dutycycle << 8*i); } @@ -350,14 +352,12 @@ void process_received_downlink(void) { } else{ Serial.println("Dutycycle is the same."); } - sensorMode_ = (LMIC.frame[LMIC.dataBeg + 2]) | ( sensorMode_ ); if (sensorMode_!= 0 && sensorMode<=3 ){ update_sensorMode(sensorMode_); } else{ Serial.println("Sensor Mode is the same."); } - sampling_rate = (LMIC.frame[LMIC.dataBeg + 3]) | ( sampling_rate ); sampling_rate = (LMIC.frame[LMIC.dataBeg + 4]) | ( sampling_rate << 8); if (sampling_rate!= 0 ){ @@ -368,7 +368,6 @@ void process_received_downlink(void) { break; case 6: - for (int i = 0; i < 2; i++) { dutycycle = (LMIC.frame[LMIC.dataBeg + i]) | ( dutycycle << 8*i); } @@ -377,14 +376,12 @@ void process_received_downlink(void) { } else{ Serial.println("Dutycycle is the same."); } - sensorMode_ = (LMIC.frame[LMIC.dataBeg + 2]) | ( sensorMode_ ); if (sensorMode_!= 0 && sensorMode<=3 ){ update_sensorMode(sensorMode_); } else{ Serial.println("Sensor Mode is the same."); } - sampling_rate = (LMIC.frame[LMIC.dataBeg + 3]) | ( sampling_rate ); sampling_rate = (LMIC.frame[LMIC.dataBeg + 4]) | ( sampling_rate << 8); if (sampling_rate!= 0 ){ @@ -392,7 +389,6 @@ void process_received_downlink(void) { } else{ Serial.println("Sensor sampling rate is the same."); } - numb_readings = (LMIC.frame[LMIC.dataBeg + 5]) | ( numb_readings ); if (numb_readings!= 0 && numb_readings<=20){ update_no_of_readings(numb_readings); @@ -407,10 +403,11 @@ uint16_t distance; // Measured Battery Level in mVolts float measuredvbat; uint16_t batlevel; +unsigned int ERROR_FLAGS; void prepare_packet(void) { - /* LoraWAN packet format + /* LoraWAN uplink packet format | Error flags | Battery Level | Ultrasonic reading | | 1 byte | 2 bytes | 2 bytes | @@ -422,9 +419,9 @@ void prepare_packet(void) { | 2 bytes | | high byte | low byte | - |---------------------------------------------Error Flags ------------------------------------------------------------| - | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | - | | | | | | | | SD error flag| + |--------------------------------------------- Error Flags -----------------------------------------------------------------------------------------------------------| + | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | + | Used only for CFG update (all other bits are high) | | | | | | | SD error flag| */ byte lowbyte, highbyte, lowbat, highbat; @@ -449,25 +446,42 @@ void prepare_packet(void) { packet_data = String("Battery Level in mVolts is: ") + String(batlevel); writeToSDCard(packet_data); - // Formatting payload - lowbyte = lowByte(distance); - highbyte = highByte(distance); - lora_packet[0] = (unsigned char)lowbyte; - lora_packet[1] = (unsigned char)highbyte; - Serial.print("Distance = "); - Serial.print(distance); - Serial.println(" mm"); - lowbat = lowByte(batlevel); - highbat = highByte(batlevel); - lora_packet[2] = (unsigned char)lowbat; //we're unsigned - lora_packet[3] = (unsigned char)highbat; - lora_packet[4] = (unsigned char)sensorMode; - packet_data = String("Sensor Mode is: ") + String(sensorMode); - writeToSDCard(packet_data); - lora_packet[5] = (unsigned char)SD_ERROR; - packet_data = String("SD Error flag is: ") + String(SD_ERROR); - writeToSDCard(packet_data); + // Error + ERROR_FLAGS = pow(2,0)* SD_ERROR; + // Formatting payload + if (UPDATE_CONFIG == true){ + // Send Sensor Config via Uplink + /* + CFG update uplink Format: + | Error Flag | Sensor Mode | Sensor Sampling Rate | Sensor Number of Readings | + | 255 (FF) | 1 byte | 2 bytes | 1 bytes | + */ + ERROR_FLAGS = 255; + lora_packet[0] = (unsigned char)ERROR_FLAGS; + packet_data = String("CFG Update via Uplink"); + writeToSDCard(packet_data); + lora_packet[1] = (unsigned char)sensorMode; + lowbyte = lowByte(sensor_sampling_rate); + highbyte = highByte(sensor_sampling_rate); + lora_packet[2] = (unsigned char)lowbyte; + lora_packet[3] = (unsigned char)highbyte; + lora_packet[4] = (unsigned char)sensor_numberOfReadings; + } + else { + // Regular Uplink contains: Sensor Error Flags followed by Battery and then Sensor Data + lowbat = lowByte(batlevel); + highbat = highByte(batlevel); + lora_packet[0] = (unsigned char)ERROR_FLAGS; + packet_data = String("SD Error flag is: ") + String(SD_ERROR); + writeToSDCard(packet_data); + lora_packet[1] = (unsigned char)lowbat; //we're unsigned + lora_packet[2] = (unsigned char)highbat; + lowbyte = lowByte(distance); + highbyte = highByte(distance); + lora_packet[3] = (unsigned char)lowbyte; + lora_packet[4] = (unsigned char)highbyte; + } } void lorawan_runloop_once() { diff --git a/ttnPayloadDecoder.js b/ttnPayloadDecoder.js new file mode 100644 index 00000000..32683826 --- /dev/null +++ b/ttnPayloadDecoder.js @@ -0,0 +1,47 @@ +// decoder variable contains Error Flags followed by Battery and sensor data. +function Decoder(b, port) { + var decoded = {}; + + // Error Flags + /* + Format: + |--------------------------------------------- Error Flags -----------------------------------------------------------------------------------------------------------| + | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | + | Used only for CFG update (all other bits are high) | | | | | | | SD error flag| + 255 or FF is a CFG update + */ + var errorFlag = b[0]; + if (errorFlag == 255) { + // Payload is Sensor cfg update + + // Sensor Mode + var sensorMode = b[1]; + decoded.sensorMode = sensorMode; + + // Sensor Sampling Rate + var sensorSamplingRate = (b[3] << 8) | b[2]; + decoded.sensorSamplingRate = sensorSamplingRate; + + // Sensor number of readings per measurement + var sensorNumberOfReadings = b[4]; + decoded.sensorNumberOfReadings = sensorNumberOfReadings; + + } else { + // Regular Payload + + // Converting Error Flag bits + var sdError = errorFlag % 2; + decoded.sdError = sdError; + + // battery + var battery = (b[2] << 8) | b[1]; // battery in centi Volts + battery = battery / 1000; // Convert to Volts + decoded.battery = battery; + + // distance + var distance = (b[4] << 8) | b[3]; + decoded.distance = distance; + } + + return decoded; +} From 5001e4500d4b5de75461e8e4da7b1035dac5dba8 Mon Sep 17 00:00:00 2001 From: Praneeth Challagonda <58634765+Praneethsvch@users.noreply.github.com> Date: Wed, 11 Nov 2020 16:50:59 -0500 Subject: [PATCH 2/6] added duty cycle to cfg update --- src/lorawan.cpp | 24 ++++++++++++++++-------- ttnPayloadDecoder.js | 10 +++++++--- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index fe8c383b..f480eb10 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -12,7 +12,7 @@ static osjob_t sendjob; unsigned int TX_INTERVAL; - +unsigned char cfg_packet[7]; unsigned char lora_packet[5]; bool TX_COMPLETED = false; // Set to false on start and after sleep; is set to true when an uplink is successful bool UPDATE_CONFIG = true; // Set to true at start and when there is a change in sensor cfg; used to send sensor cfg via uplink @@ -61,12 +61,16 @@ void do_send(osjob_t* j) { writeToSDCard(do_sendstr1); } else { // Prepare upstream data transmission at the next possible time. - int lmic_tx_retVAL = LMIC_setTxData2(1, lora_packet, sizeof(lora_packet), 0); + if (UPDATE_CONFIG == true){ + int lmic_tx_retVAL = LMIC_setTxData2(1, cfg_packet, sizeof(cfg_packet), 0); + } else { + int lmic_tx_retVAL = LMIC_setTxData2(1, lora_packet, sizeof(lora_packet), 0); + } String do_sendstr; if (lmic_tx_retVAL == 0) { Serial.println(F("Packet queued and lmic_tx_retVAL is 0.")); } else { - do_sendstr = String ("Something is wrong ") + String("Error number: ") + String(lmic_tx_retVAL); + do_sendstr = String ("Something is wrong: ") + String("Error number: ") + String(lmic_tx_retVAL); Serial.println(do_sendstr); writeToSDCard(do_sendstr); } @@ -458,15 +462,19 @@ void prepare_packet(void) { | 255 (FF) | 1 byte | 2 bytes | 1 bytes | */ ERROR_FLAGS = 255; - lora_packet[0] = (unsigned char)ERROR_FLAGS; + cfg_packet[0] = (unsigned char)ERROR_FLAGS; packet_data = String("CFG Update via Uplink"); writeToSDCard(packet_data); - lora_packet[1] = (unsigned char)sensorMode; + byte lowduty = lowByte(TX_INTERVAL); + byte highduty = highByte(TX_INTERVAL); + cfg_packet[1] = (unsigned char)lowbyte; + cfg_packet[2] = (unsigned char)highbyte; + cfg_packet[3] = (unsigned char)sensorMode; lowbyte = lowByte(sensor_sampling_rate); highbyte = highByte(sensor_sampling_rate); - lora_packet[2] = (unsigned char)lowbyte; - lora_packet[3] = (unsigned char)highbyte; - lora_packet[4] = (unsigned char)sensor_numberOfReadings; + cfg_packet[4] = (unsigned char)lowbyte; + cfg_packet[5] = (unsigned char)highbyte; + cfg_packet[6] = (unsigned char)sensor_numberOfReadings; } else { // Regular Uplink contains: Sensor Error Flags followed by Battery and then Sensor Data diff --git a/ttnPayloadDecoder.js b/ttnPayloadDecoder.js index 32683826..1950a266 100644 --- a/ttnPayloadDecoder.js +++ b/ttnPayloadDecoder.js @@ -14,16 +14,20 @@ function Decoder(b, port) { if (errorFlag == 255) { // Payload is Sensor cfg update + // Duty cycle + var dutyCycle = (b[2]<< 8) | b[1]; + decoded.dutyCycle = dutyCycle; + // Sensor Mode - var sensorMode = b[1]; + var sensorMode = b[3]; decoded.sensorMode = sensorMode; // Sensor Sampling Rate - var sensorSamplingRate = (b[3] << 8) | b[2]; + var sensorSamplingRate = (b[5] << 8) | b[4]; decoded.sensorSamplingRate = sensorSamplingRate; // Sensor number of readings per measurement - var sensorNumberOfReadings = b[4]; + var sensorNumberOfReadings = b[6]; decoded.sensorNumberOfReadings = sensorNumberOfReadings; } else { From bc78c563edca45c8d0014a67ddeb6831f4306c5a Mon Sep 17 00:00:00 2001 From: Praneeth Challagonda <58634765+Praneethsvch@users.noreply.github.com> Date: Wed, 11 Nov 2020 16:54:40 -0500 Subject: [PATCH 3/6] update --- src/lorawan.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index f480eb10..3509cc0a 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -61,10 +61,11 @@ void do_send(osjob_t* j) { writeToSDCard(do_sendstr1); } else { // Prepare upstream data transmission at the next possible time. + int lmic_tx_retVAL; if (UPDATE_CONFIG == true){ - int lmic_tx_retVAL = LMIC_setTxData2(1, cfg_packet, sizeof(cfg_packet), 0); + lmic_tx_retVAL = LMIC_setTxData2(1, cfg_packet, sizeof(cfg_packet), 0); } else { - int lmic_tx_retVAL = LMIC_setTxData2(1, lora_packet, sizeof(lora_packet), 0); + lmic_tx_retVAL = LMIC_setTxData2(1, lora_packet, sizeof(lora_packet), 0); } String do_sendstr; if (lmic_tx_retVAL == 0) { From 225ec5dc5545f75972ea2c7909d6044e08ae7112 Mon Sep 17 00:00:00 2001 From: Praneeth Challagonda <58634765+Praneethsvch@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:02:49 -0500 Subject: [PATCH 4/6] updated payload format --- src/lorawan.cpp | 82 ++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 3509cc0a..8f59f764 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -412,45 +412,8 @@ unsigned int ERROR_FLAGS; void prepare_packet(void) { - /* LoraWAN uplink packet format - | Error flags | Battery Level | Ultrasonic reading | - | 1 byte | 2 bytes | 2 bytes | - - | Ultrasonic reading | - | 2 bytes | - | high byte | low byte | - - | Battery Level | - | 2 bytes | - | high byte | low byte | - - |--------------------------------------------- Error Flags -----------------------------------------------------------------------------------------------------------| - | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | - | Used only for CFG update (all other bits are high) | | | | | | | SD error flag| - */ - byte lowbyte, highbyte, lowbat, highbat; - // Maxbotix - distance = read_sensor_using_modes(sensorMode, sensor_sampling_rate, sensor_numberOfReadings); - Serial.print("Distance = "); - Serial.print(distance); - Serial.println(" mm"); - String packet_data = String("Distance in mm is: ") + String(distance); - writeToSDCard(packet_data); - - // Battery - measuredvbat = analogRead(VBATPIN); //Float - measuredvbat *= 2; // we divided by 2, so multiply back - measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage - measuredvbat /= 1024; // convert to voltage - Serial.print("VBat: " ); Serial.println(measuredvbat); - measuredvbat *= 1000; //make it milli volts to transmit - Serial.print("VBat in mVolts: " ); Serial.println(measuredvbat); - batlevel = measuredvbat; //Payload - packet_data = String("Battery Level in mVolts is: ") + String(batlevel); - writeToSDCard(packet_data); - // Error ERROR_FLAGS = pow(2,0)* SD_ERROR; @@ -468,8 +431,8 @@ void prepare_packet(void) { writeToSDCard(packet_data); byte lowduty = lowByte(TX_INTERVAL); byte highduty = highByte(TX_INTERVAL); - cfg_packet[1] = (unsigned char)lowbyte; - cfg_packet[2] = (unsigned char)highbyte; + cfg_packet[1] = (unsigned char)lowduty; + cfg_packet[2] = (unsigned char)highduty; cfg_packet[3] = (unsigned char)sensorMode; lowbyte = lowByte(sensor_sampling_rate); highbyte = highByte(sensor_sampling_rate); @@ -479,6 +442,47 @@ void prepare_packet(void) { } else { // Regular Uplink contains: Sensor Error Flags followed by Battery and then Sensor Data + + /* LoraWAN uplink packet format + | Error flags | Battery Level | Ultrasonic reading | + | 1 byte | 2 bytes | 2 bytes | + + | Ultrasonic reading | + | 2 bytes | + | high byte | low byte | + + | Battery Level | + | 2 bytes | + | high byte | low byte | + + |--------------------------------------------- Error Flags -----------------------------------------------------------------------------------------------------------| + | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | + | Used only for CFG update (all other bits are high) | | | | | | | SD error flag| + */ + + + + // Maxbotix + distance = read_sensor_using_modes(sensorMode, sensor_sampling_rate, sensor_numberOfReadings); + Serial.print("Distance = "); + Serial.print(distance); + Serial.println(" mm"); + String packet_data = String("Distance in mm is: ") + String(distance); + writeToSDCard(packet_data); + + // Battery + measuredvbat = analogRead(VBATPIN); //Float + measuredvbat *= 2; // we divided by 2, so multiply back + measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage + measuredvbat /= 1024; // convert to voltage + Serial.print("VBat: " ); Serial.println(measuredvbat); + measuredvbat *= 1000; //make it milli volts to transmit + Serial.print("VBat in mVolts: " ); Serial.println(measuredvbat); + batlevel = measuredvbat; //Payload + packet_data = String("Battery Level in mVolts is: ") + String(batlevel); + writeToSDCard(packet_data); + + // Payload lowbat = lowByte(batlevel); highbat = highByte(batlevel); lora_packet[0] = (unsigned char)ERROR_FLAGS; From 30e3d41caa354b2931d652e817a9bd82055b4769 Mon Sep 17 00:00:00 2001 From: Praneeth Challagonda <58634765+Praneethsvch@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:04:48 -0500 Subject: [PATCH 5/6] update --- src/lorawan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 8f59f764..0600d8be 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -413,7 +413,7 @@ unsigned int ERROR_FLAGS; void prepare_packet(void) { byte lowbyte, highbyte, lowbat, highbat; - + String packet_data; // Error ERROR_FLAGS = pow(2,0)* SD_ERROR; @@ -467,7 +467,7 @@ void prepare_packet(void) { Serial.print("Distance = "); Serial.print(distance); Serial.println(" mm"); - String packet_data = String("Distance in mm is: ") + String(distance); + packet_data = String("Distance in mm is: ") + String(distance); writeToSDCard(packet_data); // Battery From 32d1cbc1fa27ac44877d1f8b5382d116bae5b3dc Mon Sep 17 00:00:00 2001 From: Praneeth Challagonda <58634765+Praneethsvch@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:34:53 -0500 Subject: [PATCH 6/6] update flag --- src/lorawan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 0600d8be..1173989b 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -171,6 +171,7 @@ void onEvent (ev_t ev) { Serial.println(F("Received ack")); event_ev = String("Received ack"); writeToSDCard(event_ev); + UPDATE_CONFIG = false; if (LMIC.dataLen) { Serial.print(F("Received ")); Serial.print(LMIC.dataLen); @@ -184,8 +185,7 @@ void onEvent (ev_t ev) { Serial.println(); process_received_downlink(); } - TX_COMPLETED = true; - UPDATE_CONFIG = false; + TX_COMPLETED = true; break; case EV_LOST_TSYNC: Serial.println(F("EV_LOST_TSYNC"));