Having issue for The Things Network Cayenne LLP. I tried with each steps from add Cayenne integration in TTN to add Lora devices in MyDevices Cayenne. But there’s not any data showing in Cayenne dashboard. Help me in this.
@eptak tagging here
@network Please PM me the deveui of that device. Thanks!
@eptak here it is. 0006110080829003
Hello, is there anyone for Help?
we will look into it and let you know after some time.
Hi,
I’ve looked into the payload we received for your device and there is definitely something wrong with them.
How are you building the payload and what are you trying to send ?
Please make sure your payload match LPP format
You can check in TTN console the payload received, but you may need a small function to translate from base64 to hex for convenience.
For example with Node.JS and two payload sent by your device:
> Buffer.from('IL8qM5qbAo5QAwdi', 'base64').toString("hex")
'20bf2a339a9b028e50030762'
> Buffer.from('AwVj', 'base64').toString("hex")
'030563'
As you can see that doesn’t match anything to our spec.
Hi,
I’m trying to send GPS data. and here blow is code that i tried in payload Decoder, please check if any suggestion in that let me know.
Thanks and regards.
function Decoder(b,port)
{
var decode = {};
var decode204 = {};
var decode205 = {};
var decode207 = {};
if(port == 204)
{
decode204.payload = b;
decode204.porta = port;
decode.lat = b[0]<<16 | b[1]<<8 | b[2];
decode.lng = b[3]<<16 | b[4]<<8 | b[5];
decode204.altitude = b[6]<<8 | b[7];
decode204.hdop = b[8];
decode204.temperature=(b[9]&0x0F)*100;
decode204.temperature+=(b[10]>>4)*10;
decode204.temperature+=(b[10]&0x0F);
if (b[9]&0xF0)
decode204.temperature/=-10;
else
decode204.temperature/=10;
decode204.battery =(b[11]>>4)*10;
decode204.battery+=(b[11]&0x0F);
decode204.latitude = (decode.lat / 8388606) * 90;
decode204.longitude = (decode.lng / 8388606) * 180;
return {
payload: decode204.payload,
port: decode204.porta,
longitude: decode204.longitude,
latitude: decode204.latitude,
altitude: decode204.altitude,
temperature: decode204.temperature,
hdop: decode204.hdop,
}
}
else if(port===205)
{
decode205.payload = b;
decode205.porta = port;
decode205.temperature =(b[0]&0x0F)*100;
decode205.temperature+=(b[1]>>4)*10;
decode205.temperature+=(b[1]&0x0F);
if (b[0]&0xF0)
decode205.temperature/=-10;
else
decode205.temperature/=10;
decode205.battery=(b[2]>>4)*10;
decode205.battery+=(b[2]&0x0F);
return {
payload: decode205.payload,
port: decode205.porta,
longitude: "",
latitude: "",
altitude: "",
temperature: decode205.temperature,
hdop: "",
}
}
else if(port===207)
{
decode207.payload = b;
decode207.porta = port;
decode207.temperature =(b[0]&0x0F)*100;
decode207.temperature+=(b[1]>>4)*10;
decode207.temperature+=(b[1]&0x0F);
if (b[0]&0xF0)
decode207.temperature/=-10;
else
decode207.temperature/=10;
decode207.battery=(b[2]>>4)*10;
decode207.battery+=(b[2]&0x0F);
return {
payload: decode207.payload,
port: decode207.porta,
longitude: "",
latitude: "",
altitude: "",
temperature: decode207.temperature,
hdop: "",
}
}
else
{
decode.porta = port;
decode.payload = b;
return {
payload: decode.payload,
port: decode.porta,
longitude: "",
latitude: "",
altitude: "",
temperature: "",
hdop: "",
}
}
}
Here is the code I used when I was testing a LoRA device. I can’t remember where it came from, but formatData and padGPS are the functions I made to format data for Cayenne and are probably the only ones of interest to you.
#include <SoftwareSerial.h>
#include <Wire.h> // for IIC communication
#include "TimerOne.h"
#include <Adafruit_GPS.h>
//GPS info
Adafruit_GPS GPS(&Serial1);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences.
#define GPSECHO false
// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
//************** Device parameters for registration *****************
////////////////////////////////////////////////////////////
char DEVICE_EUI[] = "xxx";
char DEVICE_ADDR[] = "xxx"; //4 bytes required
char APP_KEY[] = "xxx"; //16 bytes required
char NWK_SESSION_KEY[] = "xxx"; //network session key
char APP_SESSION_KEY[] = "xxx"; //network session key
////////////////////////////////////////////////////////////
//************** ACCELEROMETER THRESHOLDS*******************************
#define xThreshold 0.5
#define yThreshold 0.5
#define zThreshold 0.5
//**************** TEMPERATURE SAMPLE TIME *******************************
#define TEMP_SAMPLE_TIME 100 //sample time for temperature
//******************** Channel Status *******************
//set bit channel on = 1, channel off = 0
//bank 0 = channels 0-7, bank 1 = channels 8-15, bank 2 = channels 16-23, bank 3 = channels 24-31, bank 4 = channels 32-39,
//bank 5 = channels 40-47, bank 6 = channels 48-55, bank 7 = channels 56-63, bank 8 = channels 64-71,
//MSB = highest channel number in bank. Example Bank 2 = b11000000. Channels 23 and 22 are on
byte channelBank[] = {B11111111, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B11111111};
#define accAddress 0x1D //right justified accelerometer address
#define tmpAddress 0x48 //right justified TMP112 address
#define I2C_WRITE Wire.write
#define I2C_READ Wire.read
/******************** ACCELEROMETER Data ************/
// adresss of accelerometer
#define adress_acc 0X1D // MMA8653FC and MMA8652FC
// adress of registers for MMA8653FC
#define ctrl_reg1 0x2A
#define ctrl_reg2 0x2B
#define ctrl_reg3 0x2C
#define ctrl_reg4 0x2D
#define ctrl_reg5 0x2E
#define int_source 0x0C
#define status_ 0x00
#define f_setup 0x09
#define out_x_msb 0x01
#define out_y_msb 0x03
#define out_z_msb 0x05
#define sysmod 0x0B
#define xyz_data_cfg 0x0E
#define ff_mt_cfg 0x15
#define ff_mt_src 0x16
#define ff_mt_ths 0x17
#define ff_mt_count 0x18
//************** set resolution of accelerometer *************************
//#define resolution 0.0038; //resolution for 2g
//#define resolution 0.0078; //resolution for 4g
#define resolution 0.0156; //resolution for 8g
//************** set range of accelerometer *************************
//#define range 0x00 //2G full scale
//#define range 0x01 //4G full scale
#define range 0x02 //8G full scale
//************** configure accelerometer *************************
//#define accConfig 0x00 // Output data rate at 800Hz, no auto wake, no auto scale adjust, no fast read mode
//#define accConfig 0x21 // Output data rate at 200Hz, no auto wake, no auto scale adjust, no fast read mode
#define accConfig 0x41 // Output data rate at 50Hz, no auto wake, no auto scale adjust, no fast read mode
//#define accConfig 0x71 // Output data rate at 1.5Hz, no auto wake, no auto scale adjust, no fast read mode
//****************** sensor variables **************************
float axeXnow ;
float axeYnow ;
float axeZnow ;
float axeXprev;
float axeYprev;
float axeZprev;
float tempC;
int printTemp;
int printXaxis;
int printYaxis;
int printZaxis;
long printLat;
long printLong;
long printAlt;
char charVal[4][5];
char charGPS[2][7];
long tempCounter;
//*******************************************************************************************************
SoftwareSerial loraSerial(10, 11); // RX, TX ** Set to 10, 11 for Mega2560 boards
void setup() {
delay(1000); //startup delay - gives Lora module time to reset if cold start
Serial.begin(115200); //terminal serial port
loraSerial.begin(57600);
Wire.begin(); // join i2c bus
ACC_INIT(); //initialize accelerometer
getConfig(); //get module information
setChannelStatus(); //configure channels to be on or off
configureABP(); //configure Access By Personalization (ABP)
//configureOTAA(); //configure Over The Air Activation (OTAA)
Timer1.initialize(500000); // initialize timer1, and set to 0.5 second period
Timer1.attachInterrupt(systemTimer); //set ISR
I2C_READ_ACC(0x01); //get initial readings
axeXprev = axeXnow;
axeYprev = axeYnow;
axeZprev = axeZnow;
tempCounter = 0;
//GPS Setup
// 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
GPS.begin(9600);
// uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// Set the update rate
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
// Request updates on antenna status, comment out to keep quiet
GPS.sendCommand(PGCMD_ANTENNA);
// the nice thing about this code is you can have a timer0 interrupt go off
// every 1 millisecond, and read data from the GPS for you. that makes the
// loop code a heck of a lot easier!
useInterrupt(true);
delay(1000);
}
//GPS Functions
// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
// if you want to debug, this is a good time to do it!
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.
#endif
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
String padGPS(String hex){
String validHEX;
int len = hex.length();
switch (len){
case 1:
validHEX = "00000" + hex;
break;
case 2:
validHEX = "0000" + hex;
break;
case 3:
validHEX = "000" + hex;
break;
case 4:
validHEX = "00" + hex;
break;
case 5:
validHEX = "0" + hex;
break;
case 6:
validHEX = hex;
break;
default:
validHEX = hex.substring(len - 6, len);
break;
}
return validHEX;
}
uint32_t timer = millis();
void loop() {
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trytng to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
}
/*if (millis() - timer > 2000) {
timer = millis(); // reset the timer
if (GPS.fix) {
int len;
Serial.print("Lat : ");Serial.println(GPS.latitudeDegrees,4);
printLat = (GPS.latitudeDegrees * 10000);
Serial.print("Lat * 10000: ");Serial.println(printLat);
String stringLat = String(printLat,HEX);
Serial.print("stringLat: ");Serial.println(stringLat);
String hexLat = padGPS(stringLat);
Serial.print("Lat HEX: ");Serial.println(hexLat);
hexLat.toCharArray(charGPS[0],7);
Serial.print("Lat toCharArray: ");Serial.println(hexLat);
Serial.print("Long : ");Serial.println(GPS.longitudeDegrees,4);
printLong = (GPS.longitudeDegrees * 10000);
Serial.print("Long * 10000: ");Serial.println(printLong);
String stringLong = String(printLong,HEX);
Serial.print("stringLong: ");Serial.println(stringLong);
String hexLong = padGPS(stringLong);
Serial.print("Long HEX: ");Serial.println(hexLong);
hexLong.toCharArray(charGPS[1],7);
Serial.print("Long toCharArray: ");Serial.println(hexLong);
Serial.print("Alt: ");Serial.println(GPS.altitude);
printAlt = GPS.altitude;
String stringAlt = String(printAlt,HEX);
Serial.print("stringAlt: ");Serial.println(stringAlt);
String hexAlt = padGPS(stringAlt);
Serial.print("Alt HEX: ");Serial.println(hexAlt);
hexAlt.toCharArray(charGPS[2],7);
Serial.print("Alt toCharArray: ");Serial.println(hexAlt);
Serial.print("Prefix; ");
Serial.println("0188");
Serial.print("Lat; ");
Serial.println(charGPS[0]);
Serial.print("Long; ");
Serial.println(charGPS[1]);
Serial.print("Alt; ");
Serial.println(charGPS[2]);
Serial.print("0188");Serial.print(charGPS[0]);Serial.print(charGPS[1]);Serial.print(charGPS[2]);
}
}*/
while (loraSerial.available()) {
Serial.write(loraSerial.read());
}
if (tempCounter >= TEMP_SAMPLE_TIME) //send data every x time
{
getTemperature();
I2C_READ_ACC(0x01);
sendAllData();
tempCounter = 0;
}
delay(50);
I2C_READ_ACC(0x01);
#if 0
if ((abs(axeXprev-axeXnow))>xThreshold || (abs(axeYprev-axeYnow))>yThreshold || (abs(axeZprev-axeZnow))>zThreshold) //send data if any axis exceeds threshold
{
getTemperature();
sendAllData();
axeXprev = axeXnow;
axeYprev = axeYnow;
axeZprev = axeZnow;
}
#endif
}
void sendAllData(void)
{
Serial.println();
Serial.println("****************************************");
Serial.print("Temperature (deg C): ");Serial.println(tempC);
Serial.print("X Axis Now: ");Serial.println(axeXnow);
Serial.print("Y Axis Now: ");Serial.println(axeYnow);
Serial.print("Z Axis Now: ");Serial.println(axeZnow);
Serial.print("X Axis Previous: ");Serial.println(axeXprev);
Serial.print("Y Axis Previous: ");Serial.println(axeYprev);
Serial.print("Z Axis Previous: ");Serial.println(axeZprev);
if (GPS.fix) {
Serial.print("Location (in degrees, works with Google Maps): ");
Serial.print(GPS.latitudeDegrees, 4);
Serial.print(", ");
Serial.println(GPS.longitudeDegrees, 4);
Serial.print("Alt: ");Serial.println(GPS.altitude);
}
Serial.println();
formatData();
loraSerial.print("mac tx uncnf 10 ");loraSerial.print("0167");loraSerial.print(charVal[0]);
loraSerial.print("0271");loraSerial.print(charVal[1]);loraSerial.print(charVal[2]);loraSerial.println(charVal[3]);
delay(5000);
loraSerial.print("mac tx uncnf 10 ");loraSerial.print("0388");loraSerial.print(charGPS[0]);loraSerial.print(charGPS[1]);loraSerial.println(charGPS[2]);
Serial.print("mac tx uncnf 10 ");Serial.print("0167");Serial.print(charVal[0]);
Serial.print("0471");Serial.print(charVal[1]);Serial.print(charVal[2]);Serial.println(charVal[3]);
Serial.print("mac tx uncnf 10 ");Serial.print("0388");Serial.print(charGPS[0]);Serial.print(charGPS[1]);Serial.println(charGPS[2]);
waitCommandResponse();
}
void systemTimer(void)
{
tempCounter++;
}
//************************ format data for lora tx **********************************
//modified for Cayenne Lora
void formatData(void)
{
int len;
printTemp = int(tempC*10);
String stringT = String(printTemp,HEX);
len = stringT.length();
stringT.toCharArray(charVal[0],5);
leadingZero(0,len);
printXaxis = int(axeXnow * 1000);
String stringX = String(printXaxis,HEX);
len = stringX.length();
stringX.toCharArray(charVal[1],5);
leadingZero(1,len);
printYaxis = int(axeYnow * 1000);
String stringY = String(printYaxis,HEX);
len = stringY.length();
stringY.toCharArray(charVal[2],5);
leadingZero(2,len);
printZaxis = int(axeZnow * 1000);
String stringZ = String(printZaxis,HEX);
len = stringZ.length();
stringZ.toCharArray(charVal[3],5);
leadingZero(3,len);
printLat = (GPS.latitudeDegrees * 10000);
String stringLat = String(printLat,HEX);
String hexLat = padGPS(stringLat);
hexLat.toCharArray(charGPS[0],7);
printLong = (GPS.longitudeDegrees * 10000);
String stringLong = String(printLong,HEX);
String hexLong = padGPS(stringLong);
hexLong.toCharArray(charGPS[1],7);
printAlt = GPS.altitude;
String stringAlt = String(printAlt,HEX);
String hexAlt = padGPS(stringAlt);
hexAlt.toCharArray(charGPS[2],7);
}
//********************* Add leading zeros to hex value ********************************
void leadingZero(byte dataID, byte lenStr)
{
charVal[dataID][4]='\0';
if (lenStr==3)
{
charVal[dataID][3]=charVal[dataID][2];
charVal[dataID][2]=charVal[dataID][1];
charVal[dataID][1]=charVal[dataID][0];
charVal[dataID][0]='0';
}
else if (lenStr==2)
{
charVal[dataID][3]=charVal[dataID][1];
charVal[dataID][2]=charVal[dataID][0];
charVal[dataID][1]='0';
charVal[dataID][0]='0';
}
else if (lenStr==1)
{
charVal[dataID][3]=charVal[dataID][0];
charVal[dataID][2]='0';
charVal[dataID][1]='0';
charVal[dataID][0]='0';
}
}
//****************** Write to I2C Slave Registers *********************************************
void I2C_SEND(unsigned char REG_ADDRESS, unsigned char DATA) //SEND data to MMA7660
{
Wire.beginTransmission(adress_acc);
Wire.write(REG_ADDRESS);
Wire.write(DATA);
Wire.endTransmission();
}
//****************************** Read I2C Slave register *******************************************
void I2C_READ_REG(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
{
unsigned char REG_ADDRESS;
int i=0;
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // register to read
Wire.endTransmission();
Wire.requestFrom(adress_acc,1); // read a number of byte and store them in write received
}
//****************** Accelerometer Initialization ************************************
void ACC_INIT()
{
I2C_SEND(ctrl_reg1 ,0X00); // standby to be able to configure
delay(10);
I2C_SEND(f_setup ,B01100000); // set FIFO mode - circular mode 32 byte watermark
delay(5);
I2C_SEND(xyz_data_cfg ,range); // set full range
delay(1);
I2C_SEND(ctrl_reg1 ,accConfig); // configure accelerometer
delay(1);
}
//************************** Read Acceleromter Registers ************************************
void I2C_READ_ACC(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
{
byte REG_ADDRESS[7];
int accel[4];
int i=0;
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // store the register to read in the buffer of the wire library
Wire.endTransmission(); // actually send the data on the bus -note: returns 0 if transmission OK-
Wire.requestFrom(adress_acc,7); // read a number of byte and store them in wire.read (note: by nature, this is called an "auto-increment register adress")
for(i=0; i<7; i++) // 7 because on datasheet p.19 if FREAD=0, on auto-increment, the adress is shifted
// according to the datasheet, because it's shifted, outZlsb are in adress 0x00
// so we start reading from 0x00, forget the 0x01 which is now "status" and make the adapation by ourselves
//this gives:
//0 = status
//1= X_MSB
//2= X_LSB
//3= Y_MSB
//4= Y_LSB
//5= Z_MSB
// 6= Z_LSB
{
REG_ADDRESS[i]=Wire.read(); //each time you read the write.read it gives you the next byte stored. The couter is reset on requestForm
}
// MMA8653FC gives the result in 10bits. 8bits are in _MSB, and 2 are in _LSB
// this part is used to concatenate both, and then put a sign on it (the most significant bit is giving the sign)
// the explanations are on p.14 of the 'application notes' given by freescale.
for (i=1;i<7;i=i+2)
{
accel[0] = (REG_ADDRESS[i+1]|((int)REG_ADDRESS[i]<<8))>>6; // X
if (accel[0]>0x01FF) {accel[1]=(((~accel[0])+1)-0xFC00);} // note: with signed int, this code is optional
else {accel[1]=accel[0];} // note: with signed int, this code is optional
switch(i){
case 1: axeXnow=accel[1]*resolution;
break;
case 3: axeYnow=accel[1]*resolution;
break;
case 5: axeZnow=accel[1]*resolution;
break;
}
}
}
//******************** Temperature Sensor (TMP112) Reading *****************************
void getTemperature(void)
{
long tempSum;
int tempReadingIn[2];
Wire.requestFrom(tmpAddress,2);
tempReadingIn[0] = Wire.read();
tempReadingIn[1] = Wire.read();
//it's a 12bit int, using two's compliment for negative
tempSum = ((tempReadingIn[0] << 8) | tempReadingIn[1]) >> 4;
tempC = tempSum*0.0625;
}
//********************* configure ABP ************************************************
void configureABP(void)
{
loraSerial.print("mac set deveui ");loraSerial.println(DEVICE_EUI);
Serial.print("mac set deveui ");Serial.println(DEVICE_EUI);
waitCommandResponse();
//loraSerial.print("mac set appeui ");loraSerial.println(APP_EUI);
//Serial.print("mac set appeui ");Serial.println(APP_EUI);
//waitCommandResponse();
loraSerial.print("mac set appkey ");loraSerial.println(APP_KEY);
Serial.print("mac set appkey ");Serial.println(APP_KEY);
waitCommandResponse();
loraSerial.print("mac set devaddr ");loraSerial.println(DEVICE_ADDR);
Serial.print("mac set devaddr ");Serial.println(DEVICE_ADDR);
waitCommandResponse();
loraSerial.print("mac set nwkskey ");loraSerial.println(NWK_SESSION_KEY);
Serial.print("mac set nwkskey ");Serial.println(NWK_SESSION_KEY);
waitCommandResponse();
loraSerial.print("mac set appskey ");loraSerial.println(APP_SESSION_KEY);
Serial.print("mac set appskey ");Serial.println(APP_SESSION_KEY);
waitCommandResponse();
loraSerial.println("mac save");
Serial.println("mac save");
waitCommandResponse();
loraSerial.println("mac join abp");
Serial.println("mac join abp");
waitCommandResponse();
}
#if 0 //not supported on free account
//************************ configure OTAA ************************************
void configureOTAA(void)
{
loraSerial.print("mac set deveui ");loraSerial.println(DEVICE_EUI);
Serial.print("mac set deveui ");Serial.println(DEVICE_EUI);
waitCommandResponse();
loraSerial.print("mac set appeui ");loraSerial.println(APP_EUI);
Serial.print("mac set appeui ");Serial.println(APP_EUI);
waitCommandResponse();
loraSerial.print("mac set appkey ");loraSerial.println(APP_KEY);
Serial.print("mac set appkey ");Serial.println(APP_KEY);
waitCommandResponse();
loraSerial.println("mac save");
Serial.println("mac save");
waitCommandResponse();
loraSerial.println("mac join otaa");
Serial.println("mac join otaa");
waitCommandResponse();
}
#endif
//********************* configure channels on or off ******************************
void setChannelStatus()
{
byte channelNumber=0;
for (int x=0; x<9; x++)
{
for (int b=0; b<8; b++)
{
if (bitRead(channelBank[x],b))
{
loraSerial.print("mac set ch status ");loraSerial.print(channelNumber);loraSerial.println(" on");
Serial.print("mac set ch status ");Serial.print(channelNumber);Serial.println(" on");
}
else
{
loraSerial.print("mac set ch status ");loraSerial.print(channelNumber);loraSerial.println(" off");
Serial.print("mac set ch status ");Serial.print(channelNumber);Serial.println(" off");
}
channelNumber++;
waitCommandResponse();
}
}
loraSerial.println("mac set adr off");
Serial.println("mac set adr off");
waitCommandResponse();
loraSerial.println("mac set pwridx 5");
Serial.println("Set Tx power");
waitCommandResponse();
//loraSerial.println("mac set dr 4");
//Serial.println("Set Data Rate 4");
//waitCommandResponse();
loraSerial.println("mac save");
delay(200);
}
//******************** wait for response from module *************************************
void waitCommandResponse(void)
{
unsigned long currentTime,startTime;
startTime = millis();
while (loraSerial.available() == 0)
{
currentTime = millis();
if (currentTime > (startTime + 3000)) //exit wait routine if nor response in 3 seconds
{
Serial.println("No Response from Lora Module");
return;
}
}
while (loraSerial.available())
{
Serial.write(loraSerial.read());
}
}
//************************ get configuration information from module *********************
void getConfig(void)
{
loraSerial.println("sys get ver"); //get module version
Serial.print("Module Version: ");
waitCommandResponse();
Serial.println();
loraSerial.println("sys get hweui"); //get module version
Serial.print("EUI Node Address: ");
waitCommandResponse();
Serial.println();
}