I am trying to create a trigger in which I can send a downlink message to change the sensitivity of a sensor node. I would like the node to keep sending the battery percentage, but only send; sensor data, and GPS data only when the proper criteria are met. I am having trouble with making an if statement regarding the app data. I have made such a sensitivity setting when I was sending data from node to node, but now that I am sending data to a gateway, I am unsure on how to format this with the case-based uplink system that I am using.
below is the template I am using from the ESP32_LoRaWAN library I’m using
#include <ESP32_LoRaWAN.h>
#include "Arduino.h"
//Include the needed libraries for the ADS and the GPS module
#include <Wire.h>//I2C library
#include <Adafruit_ADS1X15.h>//ADS library
#include "TinyGPS++.h"//Gps module library
//Define the BAND frequency
#define BAND 915E6//set BAND to US which is 915E6 or 915MHz
//Declare your objects which are the GPS module and the ADS1115 in which we can read the geophone inputs
TinyGPSPlus gps;//This is the GPS object that will pretty much do all the grunt work with the NMEA data
Adafruit_ADS1115 ads;/* Use this for the 16-bit version */
//Declare the global variables
int value = analogRead(A0);
float Voltage;
float Perc;
int16_t SensorRead;
float LatRead;
float LonRead;
float AltRead;
int HourRead;
int MinRead;
int SecRead;
/*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */
uint32_t license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607};
/* OTAA para*/
uint8_t DevEui[] = {FILLMEIN };
uint8_t AppEui[] = { FILLMEIN};
uint8_t AppKey[] = { FILLMEIN};
/* ABP para*/
uint8_t NwkSKey[] = {FILLMEIN };
uint8_t AppSKey[] = { FILLMEIN};
uint32_t DevAddr = ( uint32_t )0x007e6ae1;
/*LoraWan channelsmask, default channels 0-7*/
uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
/*LoraWan Class, Class A and Class C are supported*/
DeviceClass_t loraWanClass = CLASS_A;
/*the application data transmission duty cycle. value in [ms].*/
uint32_t appTxDutyCycle = 15000;
/*OTAA or ABP*/
bool overTheAirActivation = true;
/*ADR enable*/
bool loraWanAdr = true;
/* Indicates if the node is sending confirmed or unconfirmed messages */
bool isTxConfirmed = true;
/* Application port */
uint8_t appPort = 2;
/*!
Number of trials to transmit the frame, if the LoRaMAC layer did not
receive an acknowledgment. The MAC performs a datarate adaptation,
according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
to the following table:
Transmission nb | Data Rate
----------------|-----------
1 (first) | DR
2 | DR
3 | max(DR-1,0)
4 | max(DR-1,0)
5 | max(DR-2,0)
6 | max(DR-2,0)
7 | max(DR-3,0)
8 | max(DR-3,0)
Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
the datarate, in case the LoRaMAC layer did not receive an acknowledgment
*/
uint8_t confirmedNbTrials = 8;
/*LoraWan debug level, select in arduino IDE tools.
None : print basic info.
Freq : print Tx and Rx freq, DR info.
Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info.
Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt and MCU deepsleep info.
*/
uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL;
/*LoraWan region, select in arduino IDE tools*/
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
#define LEDPin 25 //LED light
void app(uint8_t data)
{
// lora_printf("data:%d\r\n",data);
switch (data)
{
case 49:
{
pinMode(LEDPin, OUTPUT);
digitalWrite(LEDPin, HIGH);
break;
}
case 50:
{
pinMode(LEDPin, OUTPUT);
digitalWrite(LEDPin, LOW);
break;
}
case 51:
{
break;
}
default:
{
break;
}
}
}
String LoRa_data;
void downLinkDataHandle(McpsIndication_t *mcpsIndication)
{
LoRa_data = "";
lora_printf("+REV DATA:%s,RXSIZE %d,PORT %d\r\n", mcpsIndication->RxSlot ? "RXWIN2" : "RXWIN1", mcpsIndication->BufferSize, mcpsIndication->Port);
lora_printf("+REV DATA:");
app(mcpsIndication->Buffer[0]);
for (uint8_t i = 0; i < mcpsIndication->BufferSize; i++)
{
lora_printf("%02X", mcpsIndication->Buffer[i]);
LoRa_data = LoRa_data + (String)(char)mcpsIndication->Buffer[i];
}
lora_printf("\r\n");
Serial.println(LoRa_data);
}
static void prepareTxFrame( uint8_t port )
{
/*appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in "commissioning.h".
appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE.
if enabled AT, don't modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure.
if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF.
for example, if use REGION_CN470,
the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in "RegionCN470.h".
*/
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW);
float Voltage = value * 5.0 / 1023;
float Percentage = map(Voltage, 3.6, 4.2, 0, 100);
float Perc = ((Percentage * -1) / 3);
int16_t Battery = (Perc + 0);
float LatRead = gps.location.lat();
float LonRead = gps.location.lng();
float AltRead = gps.altitude.feet();
uint16_t HourRead = gps.time.hour();
uint16_t MinRead = gps.time.minute();
uint16_t SecRead = gps.time.second();
int16_t SensorRead = ads.getLastConversionResults();
digitalWrite(Vext, HIGH);
unsigned char *puc;
appDataSize = 22;
appData[0] = (int8_t)(SensorRead >> 8);
appData[1] = (int8_t)SensorRead;
appData[2] = (int8_t)(Battery >> 8);
appData[3] = (int8_t)Battery;
appData[4] = (uint8_t)(HourRead >> 8);
appData[5] = (uint8_t)HourRead;
appData[6] = (uint8_t)(MinRead >> 8);
appData[7] = (uint8_t)MinRead;
appData[8] = (uint8_t)(SecRead >> 8);
appData[9] = (uint8_t)SecRead;
puc = (unsigned char *)(&LatRead);
appData[10] = puc[0];
appData[11] = puc[1];
appData[12] = puc[2];
appData[13] = puc[3];
puc = (unsigned char *)(&LonRead);
appData[14] = puc[0];
appData[15] = puc[1];
appData[16] = puc[2];
appData[17] = puc[3];
puc = (unsigned char *)(&AltRead);
appData[18] = puc[0];
appData[19] = puc[1];
appData[20] = puc[2];
appData[21] = puc[3];
Serial.print("Lat=");
Serial.print(LatRead);
Serial.print(", Lon=");
Serial.print(LonRead);
Serial.print(", Alt=");
Serial.println(AltRead);
Serial.print("Time: ");
Serial.print(HourRead);
Serial.print(":");
Serial.print(MinRead);
Serial.print(":");
Serial.println(SecRead);
Serial.print("Voltage: ");
Serial.print(Voltage);
Serial.print(", Percentage: ");
Serial.println(Perc);
Serial.print("Sensor Reading: ");
Serial.println(SensorRead);
}
// Add your initialization code here
void setup()
{
Serial.begin(115200);
while (!Serial);
SPI.begin(SCK, MISO, MOSI, SS);
Mcu.init(SS, RST_LoRa, DIO0, DIO1, license);
deviceState = DEVICE_STATE_INIT;
Serial2.begin(115200, SERIAL_8N1, 2, 17);
//serial_connection.begin(115200);//This opens up communications to the GPS
//Serial.println("Hello!");
//Serial.println("Single-ended readings from AIN0 with >3.0V comparator");
//Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
//Serial.println("Comparator Threshold: 1000 (3.000V)");
// ADS1015 ADS1115
// ------- -------
// ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
//ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
// ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV
// ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV
// ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV
//ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV
ads.begin();
ads.setGain(GAIN_FOUR);
if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
while (1);
}
// Setup 3V comparator on channel 0
ads.startComparator_SingleEnded(0, 1000);
}
// The loop function is called in an endless loop
void loop ()
{
switch ( deviceState )
{
case DEVICE_STATE_INIT:
{
#if(LORAWAN_DEVEUI_AUTO)
LoRaWAN.generateDeveuiByChipID();
#endif
LoRaWAN.init(loraWanClass, loraWanRegion);
break;
}
case DEVICE_STATE_JOIN:
{
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND:
{
prepareTxFrame( appPort );
LoRaWAN.send(loraWanClass);
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE:
{
// Schedule next packet transmission
txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP:
{
LoRaWAN.sleep(loraWanClass, debugLevel);
break;
}
default:
{
deviceState = DEVICE_STATE_INIT;
break;
}
}
}