mirror of
https://github.com/timmbogner/Farm-Data-Relay-System
synced 2024-11-08 13:10:29 +00:00
Merge pull request #139 from aviateur17/2023_01_loraImprovements
2023 01 lora improvements
This commit is contained in:
commit
9bb01738c0
@ -41,7 +41,6 @@ DataReading theData[256];
|
|||||||
uint8_t ln;
|
uint8_t ln;
|
||||||
uint8_t newData = event_clear;
|
uint8_t newData = event_clear;
|
||||||
uint8_t newCmd = cmd_clear;
|
uint8_t newCmd = cmd_clear;
|
||||||
bool is_ping = false;
|
|
||||||
|
|
||||||
DataReading fdrsData[256]; // buffer for loadFDRS()
|
DataReading fdrsData[256]; // buffer for loadFDRS()
|
||||||
uint8_t data_count = 0;
|
uint8_t data_count = 0;
|
||||||
|
@ -84,6 +84,7 @@ RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, -1, LORA_SPI);
|
|||||||
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, -1);
|
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, -1);
|
||||||
#endif // CUSTOM_SPI
|
#endif // CUSTOM_SPI
|
||||||
|
|
||||||
|
bool pingFlag = false;
|
||||||
bool transmitFlag = false; // flag to indicate transmission or reception state
|
bool transmitFlag = false; // flag to indicate transmission or reception state
|
||||||
volatile bool enableInterrupt = true; // disable interrupt when it's not needed
|
volatile bool enableInterrupt = true; // disable interrupt when it's not needed
|
||||||
volatile bool operationDone = false; // flag to indicate that a packet was sent or received
|
volatile bool operationDone = false; // flag to indicate that a packet was sent or received
|
||||||
@ -120,8 +121,8 @@ bool tx_time_set = false;
|
|||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
void transmitLoRa(uint16_t *, DataReading *, uint8_t);
|
crcResult transmitLoRa(uint16_t *, DataReading *, uint8_t);
|
||||||
void transmitLoRa(uint16_t *, SystemPacket *, uint8_t);
|
crcResult transmitLoRa(uint16_t *, SystemPacket *, uint8_t);
|
||||||
static uint16_t crc16_update(uint16_t, uint8_t);
|
static uint16_t crc16_update(uint16_t, uint8_t);
|
||||||
|
|
||||||
// CRC16 from https://github.com/4-20ma/ModbusMaster/blob/3a05ff87677a9bdd8e027d6906dc05ca15ca8ade/src/util/crc16.h#L71
|
// CRC16 from https://github.com/4-20ma/ModbusMaster/blob/3a05ff87677a9bdd8e027d6906dc05ca15ca8ade/src/util/crc16.h#L71
|
||||||
@ -167,8 +168,9 @@ void setFlag(void)
|
|||||||
operationDone = true;
|
operationDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transmitLoRa(uint16_t *destMac, DataReading *packet, uint8_t len)
|
crcResult transmitLoRa(uint16_t *destMac, DataReading *packet, uint8_t len)
|
||||||
{
|
{
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
uint16_t calcCRC = 0x0000;
|
uint16_t calcCRC = 0x0000;
|
||||||
|
|
||||||
uint8_t pkt[6 + (len * sizeof(DataReading))];
|
uint8_t pkt[6 + (len * sizeof(DataReading))];
|
||||||
@ -201,9 +203,12 @@ void transmitLoRa(uint16_t *destMac, DataReading *packet, uint8_t len)
|
|||||||
while (true)
|
while (true)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
return crcReturned;
|
||||||
}
|
}
|
||||||
void transmitLoRa(uint16_t *destMac, SystemPacket *packet, uint8_t len)
|
|
||||||
|
crcResult transmitLoRa(uint16_t *destMac, SystemPacket *packet, uint8_t len)
|
||||||
{
|
{
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
uint16_t calcCRC = 0x0000;
|
uint16_t calcCRC = 0x0000;
|
||||||
|
|
||||||
uint8_t pkt[6 + (len * sizeof(SystemPacket))];
|
uint8_t pkt[6 + (len * sizeof(SystemPacket))];
|
||||||
@ -234,6 +239,7 @@ void transmitLoRa(uint16_t *destMac, SystemPacket *packet, uint8_t len)
|
|||||||
while (true)
|
while (true)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
return crcReturned;
|
||||||
}
|
}
|
||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
|
|
||||||
@ -381,7 +387,7 @@ crcResult getLoRa()
|
|||||||
{ // We have received a ping request or reply??
|
{ // We have received a ping request or reply??
|
||||||
if (receiveData[0].param == 1)
|
if (receiveData[0].param == 1)
|
||||||
{ // This is a reply to our ping request
|
{ // This is a reply to our ping request
|
||||||
is_ping = true;
|
pingFlag = true;
|
||||||
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
||||||
}
|
}
|
||||||
else if (receiveData[0].param == 0)
|
else if (receiveData[0].param == 0)
|
||||||
@ -410,7 +416,7 @@ crcResult getLoRa()
|
|||||||
{ // We have received a ping request or reply??
|
{ // We have received a ping request or reply??
|
||||||
if (receiveData[0].param == 1)
|
if (receiveData[0].param == 1)
|
||||||
{ // This is a reply to our ping request
|
{ // This is a reply to our ping request
|
||||||
is_ping = true;
|
pingFlag = true;
|
||||||
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
||||||
}
|
}
|
||||||
else if (receiveData[0].param == 0)
|
else if (receiveData[0].param == 0)
|
||||||
@ -591,8 +597,9 @@ void asyncReleaseLoRaFirst()
|
|||||||
asyncReleaseLoRa(true);
|
asyncReleaseLoRa(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleLoRa()
|
crcResult handleLoRa()
|
||||||
{
|
{
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
if (operationDone) // the interrupt was triggered
|
if (operationDone) // the interrupt was triggered
|
||||||
{
|
{
|
||||||
enableInterrupt = false;
|
enableInterrupt = false;
|
||||||
@ -618,7 +625,7 @@ void handleLoRa()
|
|||||||
}
|
}
|
||||||
else // the previous operation was reception
|
else // the previous operation was reception
|
||||||
{
|
{
|
||||||
returnCRC = getLoRa();
|
crcReturned = getLoRa();
|
||||||
if (!transmitFlag) // return to listen if no transmission was begun
|
if (!transmitFlag) // return to listen if no transmission was begun
|
||||||
{
|
{
|
||||||
radio.startReceive();
|
radio.startReceive();
|
||||||
@ -626,5 +633,6 @@ void handleLoRa()
|
|||||||
enableInterrupt = true;
|
enableInterrupt = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return crcReturned;
|
||||||
}
|
}
|
||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
|
@ -46,6 +46,7 @@ uint8_t ln;
|
|||||||
bool newData;
|
bool newData;
|
||||||
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
|
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
|
||||||
const uint16_t espnow_size = 250 / sizeof(DataReading);
|
const uint16_t espnow_size = 250 / sizeof(DataReading);
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
|
|
||||||
uint32_t gtwy_timeout = 0;
|
uint32_t gtwy_timeout = 0;
|
||||||
uint8_t incMAC[6];
|
uint8_t incMAC[6];
|
||||||
@ -53,7 +54,6 @@ DataReading fdrsData[espnow_size];
|
|||||||
DataReading incData[espnow_size];
|
DataReading incData[espnow_size];
|
||||||
|
|
||||||
uint8_t data_count = 0;
|
uint8_t data_count = 0;
|
||||||
bool is_ping = false;
|
|
||||||
|
|
||||||
uint32_t last_refresh;
|
uint32_t last_refresh;
|
||||||
void (*callback_ptr)(DataReading);
|
void (*callback_ptr)(DataReading);
|
||||||
@ -173,6 +173,9 @@ void handleIncoming()
|
|||||||
|
|
||||||
bool sendFDRS()
|
bool sendFDRS()
|
||||||
{
|
{
|
||||||
|
if(data_count == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
DBG("Sending FDRS Packet!");
|
DBG("Sending FDRS Packet!");
|
||||||
#ifdef USE_ESPNOW
|
#ifdef USE_ESPNOW
|
||||||
esp_now_send(gatewayAddress, (uint8_t *)&fdrsData, data_count * sizeof(DataReading));
|
esp_now_send(gatewayAddress, (uint8_t *)&fdrsData, data_count * sizeof(DataReading));
|
||||||
@ -193,13 +196,26 @@ bool sendFDRS()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LORA
|
#ifdef USE_LORA
|
||||||
transmitLoRa(>wyAddress, fdrsData, data_count);
|
crcReturned = transmitLoRa(>wyAddress, fdrsData, data_count);
|
||||||
DBG(" LoRa sent.");
|
// DBG(" LoRa sent.");
|
||||||
|
#ifdef LORA_ACK
|
||||||
|
if(crcReturned == CRC_OK) {
|
||||||
data_count = 0;
|
data_count = 0;
|
||||||
returnCRC = CRC_NULL;
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef LORA_ACK
|
||||||
|
if(crcReturned == CRC_OK || crcReturned == CRC_NULL) {
|
||||||
|
data_count = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
data_count = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void loadFDRS(float d, uint8_t t)
|
void loadFDRS(float d, uint8_t t)
|
||||||
{
|
{
|
||||||
@ -227,7 +243,6 @@ void loadFDRS(float d, uint8_t t, uint16_t id)
|
|||||||
}
|
}
|
||||||
void sleepFDRS(int sleep_time)
|
void sleepFDRS(int sleep_time)
|
||||||
{
|
{
|
||||||
DBG("Sleepytime!");
|
|
||||||
#ifdef DEEP_SLEEP
|
#ifdef DEEP_SLEEP
|
||||||
DBG(" Deep sleeping.");
|
DBG(" Deep sleeping.");
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
@ -344,27 +359,14 @@ bool addFDRS(int timeout, void (*new_cb_ptr)(DataReading))
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pingFDRS(int timeout)
|
uint32_t pingFDRS(uint32_t timeout)
|
||||||
{
|
{
|
||||||
SystemPacket sys_packet = {.cmd = cmd_ping, .param = 0};
|
|
||||||
#ifdef USE_ESPNOW
|
#ifdef USE_ESPNOW
|
||||||
esp_now_send(gatewayAddress, (uint8_t *)&sys_packet, sizeof(SystemPacket));
|
uint32_t pingResponseMs = pingFDRSEspNow(gatewayAddress, timeout);
|
||||||
DBG(" ESP-NOW ping sent.");
|
return pingResponseMs;
|
||||||
uint32_t ping_start = millis();
|
|
||||||
is_ping = false;
|
|
||||||
while ((millis() - ping_start) <= timeout)
|
|
||||||
{
|
|
||||||
yield(); // do I need to yield or does it automatically?
|
|
||||||
if (is_ping)
|
|
||||||
{
|
|
||||||
DBG("Ping Returned:" + String(millis() - ping_start) + " from " + String(incMAC[5]));
|
|
||||||
return millis() - ping_start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LORA
|
#ifdef USE_LORA
|
||||||
// transmitLoRa(gtwyAddress, sys_packet, data_count); // TODO: Make this congruent to esp_now_send()
|
uint32_t pingResponseMs = pingFDRSLoRa(>wyAddress, timeout);
|
||||||
DBG(" LoRa ping not sent because it isn't implemented.");
|
return pingResponseMs;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,10 @@ uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|||||||
crcResult esp_now_ack_flag;
|
crcResult esp_now_ack_flag;
|
||||||
bool is_added = false;
|
bool is_added = false;
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_ESPNOW
|
#ifdef USE_ESPNOW
|
||||||
|
bool pingFlag = false;
|
||||||
|
|
||||||
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
|
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus)
|
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus)
|
||||||
@ -49,7 +52,7 @@ void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)
|
|||||||
switch (command.cmd)
|
switch (command.cmd)
|
||||||
{
|
{
|
||||||
case cmd_ping:
|
case cmd_ping:
|
||||||
is_ping = true;
|
pingFlag = true;
|
||||||
break;
|
break;
|
||||||
case cmd_add:
|
case cmd_add:
|
||||||
is_added = true;
|
is_added = true;
|
||||||
@ -64,4 +67,28 @@ void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)
|
|||||||
newData = true;
|
newData = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FDRS node pings gateway and listens for a defined amount of time for a reply
|
||||||
|
// Blocking function for timeout amount of time (up to timeout time waiting for reply)(IE no callback)
|
||||||
|
// Returns the amount of time in ms that the ping takes or predefined value if ping fails within timeout
|
||||||
|
uint32_t pingFDRSEspNow(uint8_t *address, uint32_t timeout) {
|
||||||
|
SystemPacket sys_packet = {.cmd = cmd_ping, .param = 0};
|
||||||
|
|
||||||
|
esp_now_send(address, (uint8_t *)&sys_packet, sizeof(SystemPacket));
|
||||||
|
DBG(" ESP-NOW ping sent.");
|
||||||
|
uint32_t ping_start = millis();
|
||||||
|
pingFlag = false;
|
||||||
|
while ((millis() - ping_start) <= timeout)
|
||||||
|
{
|
||||||
|
yield(); // do I need to yield or does it automatically?
|
||||||
|
if (pingFlag)
|
||||||
|
{
|
||||||
|
DBG("ESP-NOW Ping Reply in " + String(millis() - ping_start) + "ms from " + String(address[0], HEX) + ":" + String(address[1], HEX) + ":" + String(address[2], HEX) + ":" + String(address[3], HEX) + ":" + String(address[4], HEX) + ":" + String(address[5], HEX));
|
||||||
|
return (millis() - ping_start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("No ESP-NOW ping returned within " + String(timeout) + "ms.");
|
||||||
|
return UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // USE_ESPNOW
|
#endif // USE_ESPNOW
|
||||||
|
@ -80,6 +80,8 @@ RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, -1, LORA_SPI);
|
|||||||
#else
|
#else
|
||||||
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, -1);
|
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, -1);
|
||||||
#endif // CUSTOM_SPI
|
#endif // CUSTOM_SPI
|
||||||
|
|
||||||
|
bool pingFlag = false;
|
||||||
bool transmitFlag = false; // flag to indicate transmission or reception state
|
bool transmitFlag = false; // flag to indicate transmission or reception state
|
||||||
volatile bool enableInterrupt = true; // disable interrupt when it's not needed
|
volatile bool enableInterrupt = true; // disable interrupt when it's not needed
|
||||||
volatile bool operationDone = false; // flag to indicate that a packet was sent or received
|
volatile bool operationDone = false; // flag to indicate that a packet was sent or received
|
||||||
@ -94,6 +96,8 @@ unsigned long msgOkLoRa = 0; // Number of total LoRa packets with vali
|
|||||||
void printLoraPacket(uint8_t *p, int size);
|
void printLoraPacket(uint8_t *p, int size);
|
||||||
|
|
||||||
uint16_t gtwyAddress = ((gatewayAddress[4] << 8) | GTWY_MAC);
|
uint16_t gtwyAddress = ((gatewayAddress[4] << 8) | GTWY_MAC);
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
crcResult getLoRa();
|
crcResult getLoRa();
|
||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32)
|
#if defined(ESP8266) || defined(ESP32)
|
||||||
@ -109,11 +113,13 @@ void setFlag(void)
|
|||||||
}
|
}
|
||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
|
|
||||||
void handleLoRa()
|
crcResult handleLoRa()
|
||||||
{
|
{
|
||||||
#ifdef USE_LORA
|
#ifdef USE_LORA
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
if (operationDone)
|
if (operationDone)
|
||||||
{ // the interrupt was triggered
|
{ // the interrupt was triggered
|
||||||
|
// DBG("Interrupt Triggered.");
|
||||||
enableInterrupt = false;
|
enableInterrupt = false;
|
||||||
operationDone = false;
|
operationDone = false;
|
||||||
if (transmitFlag)
|
if (transmitFlag)
|
||||||
@ -124,7 +130,7 @@ void handleLoRa()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // the previous operation was reception
|
{ // the previous operation was reception
|
||||||
returnCRC = getLoRa();
|
crcReturned = getLoRa();
|
||||||
if (!transmitFlag) // return to listen if no transmission was begun
|
if (!transmitFlag) // return to listen if no transmission was begun
|
||||||
{
|
{
|
||||||
radio.startReceive();
|
radio.startReceive();
|
||||||
@ -132,6 +138,7 @@ void handleLoRa()
|
|||||||
enableInterrupt = true;
|
enableInterrupt = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return crcReturned;
|
||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +172,7 @@ void begin_lora()
|
|||||||
#endif
|
#endif
|
||||||
radio.setCRC(false);
|
radio.setCRC(false);
|
||||||
LoRaAddress = ((radio.randomByte() << 8) | radio.randomByte());
|
LoRaAddress = ((radio.randomByte() << 8) | radio.randomByte());
|
||||||
|
DBG("LoRa node address is " + String(LoRaAddress, HEX) + " (hex).");
|
||||||
state = radio.startReceive(); // start listening for LoRa packets
|
state = radio.startReceive(); // start listening for LoRa packets
|
||||||
if (state == RADIOLIB_ERR_NONE)
|
if (state == RADIOLIB_ERR_NONE)
|
||||||
{
|
{
|
||||||
@ -178,9 +186,13 @@ void begin_lora()
|
|||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
}
|
}
|
||||||
|
|
||||||
void transmitLoRa(uint16_t *destMAC, DataReading *packet, uint8_t len)
|
// Transmits Lora data by calling RadioLib library function
|
||||||
|
// Returns the CRC result if ACKs are enabled otherwise returns CRC_NULL
|
||||||
|
|
||||||
|
crcResult transmitLoRa(uint16_t *destMAC, DataReading *packet, uint8_t len)
|
||||||
{
|
{
|
||||||
#ifdef USE_LORA
|
#ifdef USE_LORA
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
uint8_t pkt[6 + (len * sizeof(DataReading))];
|
uint8_t pkt[6 + (len * sizeof(DataReading))];
|
||||||
uint16_t calcCRC = 0x0000;
|
uint16_t calcCRC = 0x0000;
|
||||||
|
|
||||||
@ -223,17 +235,17 @@ void transmitLoRa(uint16_t *destMAC, DataReading *packet, uint8_t len)
|
|||||||
unsigned long loraAckTimeout = millis() + FDRS_ACK_TIMEOUT;
|
unsigned long loraAckTimeout = millis() + FDRS_ACK_TIMEOUT;
|
||||||
retries--;
|
retries--;
|
||||||
delay(10);
|
delay(10);
|
||||||
while (returnCRC == CRC_NULL && (millis() < loraAckTimeout))
|
while (crcReturned == CRC_NULL && (millis() < loraAckTimeout))
|
||||||
{
|
{
|
||||||
handleLoRa();
|
crcReturned = handleLoRa();
|
||||||
}
|
}
|
||||||
if (returnCRC == CRC_OK)
|
if (crcReturned == CRC_OK)
|
||||||
{
|
{
|
||||||
// DBG("LoRa ACK Received! CRC OK");
|
// DBG("LoRa ACK Received! CRC OK");
|
||||||
msgOkLoRa++;
|
msgOkLoRa++;
|
||||||
return; // we're done
|
return CRC_OK; // we're done
|
||||||
}
|
}
|
||||||
else if (returnCRC == CRC_BAD)
|
else if (crcReturned == CRC_BAD)
|
||||||
{
|
{
|
||||||
// DBG("LoRa ACK Received! CRC BAD");
|
// DBG("LoRa ACK Received! CRC BAD");
|
||||||
// Resend original packet again if retries are available
|
// Resend original packet again if retries are available
|
||||||
@ -260,29 +272,38 @@ void transmitLoRa(uint16_t *destMAC, DataReading *packet, uint8_t len)
|
|||||||
}
|
}
|
||||||
transmitLoRaMsgwAck++;
|
transmitLoRaMsgwAck++;
|
||||||
#endif // LORA_ACK
|
#endif // LORA_ACK
|
||||||
|
return crcReturned;
|
||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now SystemPackets will not use ACK but will calculate CRC
|
// For now SystemPackets will not use ACK but will calculate CRC
|
||||||
void transmitLoRa(uint16_t *destMAC, SystemPacket *packet, uint8_t len)
|
// Returns CRC_NULL ask SystemPackets do not use ACKS at current time
|
||||||
|
crcResult transmitLoRa(uint16_t *destMAC, SystemPacket *packet, uint8_t len)
|
||||||
{
|
{
|
||||||
#ifdef USE_LORA
|
#ifdef USE_LORA
|
||||||
|
crcResult crcReturned = CRC_NULL;
|
||||||
uint8_t pkt[6 + (len * sizeof(SystemPacket))];
|
uint8_t pkt[6 + (len * sizeof(SystemPacket))];
|
||||||
uint16_t calcCRC = 0x0000;
|
uint16_t calcCRC = 0x0000;
|
||||||
|
|
||||||
|
// Building packet -- address portion - first 4 bytes
|
||||||
pkt[0] = (*destMAC >> 8);
|
pkt[0] = (*destMAC >> 8);
|
||||||
pkt[1] = (*destMAC & 0x00FF);
|
pkt[1] = (*destMAC & 0x00FF);
|
||||||
pkt[2] = (LoRaAddress >> 8);
|
pkt[2] = (LoRaAddress >> 8);
|
||||||
pkt[3] = (LoRaAddress & 0x00FF);
|
pkt[3] = (LoRaAddress & 0x00FF);
|
||||||
|
// Building packet -- data portion - 5 bytes
|
||||||
memcpy(&pkt[4], packet, len * sizeof(SystemPacket));
|
memcpy(&pkt[4], packet, len * sizeof(SystemPacket));
|
||||||
|
// Calculate CRC of address and data portion of the packet
|
||||||
|
// Last 2 bytes are CRC so do not include them in the calculation itself
|
||||||
for (int i = 0; i < (sizeof(pkt) - 2); i++)
|
for (int i = 0; i < (sizeof(pkt) - 2); i++)
|
||||||
{ // Last 2 bytes are CRC so do not include them in the calculation itself
|
{
|
||||||
// printf("CRC: %02X : %d\n",calcCRC, i);
|
// printf("CRC: %02X : %d\n",calcCRC, i);
|
||||||
calcCRC = crc16_update(calcCRC, pkt[i]);
|
calcCRC = crc16_update(calcCRC, pkt[i]);
|
||||||
}
|
}
|
||||||
calcCRC = crc16_update(calcCRC, 0xA1); // Recalculate CRC for No ACK
|
calcCRC = crc16_update(calcCRC, 0xA1); // Recalculate CRC for No ACK
|
||||||
|
// Building packet -- adding CRC - last 2 bytes
|
||||||
pkt[len * sizeof(SystemPacket) + 4] = (calcCRC >> 8);
|
pkt[len * sizeof(SystemPacket) + 4] = (calcCRC >> 8);
|
||||||
pkt[len * sizeof(SystemPacket) + 5] = (calcCRC & 0x00FF);
|
pkt[len * sizeof(SystemPacket) + 5] = (calcCRC & 0x00FF);
|
||||||
|
// Packet is constructed now transmit the packet
|
||||||
DBG("Transmitting LoRa message of size " + String(sizeof(pkt)) + " bytes with CRC 0x" + String(calcCRC, HEX) + " to destination 0x" + String(*destMAC, HEX));
|
DBG("Transmitting LoRa message of size " + String(sizeof(pkt)) + " bytes with CRC 0x" + String(calcCRC, HEX) + " to destination 0x" + String(*destMAC, HEX));
|
||||||
// printLoraPacket(pkt,sizeof(pkt));
|
// printLoraPacket(pkt,sizeof(pkt));
|
||||||
int state = radio.startTransmit(pkt, sizeof(pkt));
|
int state = radio.startTransmit(pkt, sizeof(pkt));
|
||||||
@ -296,9 +317,11 @@ void transmitLoRa(uint16_t *destMAC, SystemPacket *packet, uint8_t len)
|
|||||||
while (true)
|
while (true)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
return crcReturned;
|
||||||
#endif // USE_LORA
|
#endif // USE_LORA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ****DO NOT CALL getLoRa() directly! ***** Call handleLoRa() instead!
|
||||||
// getLoRa for Sensors
|
// getLoRa for Sensors
|
||||||
// USED to get ACKs (SystemPacket type) from LoRa gateway at this point. May be used in the future to get other data
|
// USED to get ACKs (SystemPacket type) from LoRa gateway at this point. May be used in the future to get other data
|
||||||
// Return type is crcResult struct - CRC_OK, CRC_BAD, CRC_NULL. CRC_NULL used for non-ack data
|
// Return type is crcResult struct - CRC_OK, CRC_BAD, CRC_NULL. CRC_NULL used for non-ack data
|
||||||
@ -320,7 +343,7 @@ crcResult getLoRa()
|
|||||||
destMAC = (packet[0] << 8) | packet[1];
|
destMAC = (packet[0] << 8) | packet[1];
|
||||||
sourceMAC = (packet[2] << 8) | packet[3];
|
sourceMAC = (packet[2] << 8) | packet[3];
|
||||||
packetCRC = ((packet[packetSize - 2] << 8) | packet[packetSize - 1]);
|
packetCRC = ((packet[packetSize - 2] << 8) | packet[packetSize - 1]);
|
||||||
// DBG("Packet Address: 0x" + String(packet[0], HEX) + String(packet[1], HEX) + " Self Address: 0x" + String(selfAddress[4], HEX) + String(selfAddress[5], HEX));
|
// DBG("Source Address: 0x" + String(packet[2], HEX) + String(packet[3], HEX) + " Destination Address: 0x" + String(packet[0], HEX) + String(packet[1], HEX));
|
||||||
if ((destMAC == LoRaAddress) || (destMAC == 0xFFFF))
|
if ((destMAC == LoRaAddress) || (destMAC == 0xFFFF))
|
||||||
{ // Check if addressed to this device or broadcast
|
{ // Check if addressed to this device or broadcast
|
||||||
// printLoraPacket(packet,sizeof(packet));
|
// printLoraPacket(packet,sizeof(packet));
|
||||||
@ -381,7 +404,7 @@ crcResult getLoRa()
|
|||||||
{ // We have received a ping request or reply??
|
{ // We have received a ping request or reply??
|
||||||
if (receiveData[0].param == 1)
|
if (receiveData[0].param == 1)
|
||||||
{ // This is a reply to our ping request
|
{ // This is a reply to our ping request
|
||||||
is_ping = true;
|
pingFlag = true;
|
||||||
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
||||||
}
|
}
|
||||||
else if (receiveData[0].param == 0)
|
else if (receiveData[0].param == 0)
|
||||||
@ -410,7 +433,7 @@ crcResult getLoRa()
|
|||||||
{ // We have received a ping request or reply??
|
{ // We have received a ping request or reply??
|
||||||
if (receiveData[0].param == 1)
|
if (receiveData[0].param == 1)
|
||||||
{ // This is a reply to our ping request
|
{ // This is a reply to our ping request
|
||||||
is_ping = true;
|
pingFlag = true;
|
||||||
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
DBG("We have received a ping reply via LoRa from address " + String(sourceMAC, HEX));
|
||||||
}
|
}
|
||||||
else if (receiveData[0].param == 0)
|
else if (receiveData[0].param == 0)
|
||||||
@ -437,8 +460,8 @@ crcResult getLoRa()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// DBG("Incoming LoRa packet of " + String(packetSize) + " bytes received from address 0x" + String(sourceMAC, HEX) + " destined for node address 0x" + String(destMAC, HEX));
|
DBG("Incoming LoRa packet of " + String(packetSize) + " bytes received from address 0x" + String(sourceMAC, HEX) + " destined for node address 0x" + String(destMAC, HEX));
|
||||||
// printLoraPacket(packet,sizeof(packet));
|
// printLoraPacket(packet,sizeof(packet));
|
||||||
return CRC_NULL;
|
return CRC_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,9 +476,39 @@ crcResult getLoRa()
|
|||||||
return CRC_NULL;
|
return CRC_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_LORA
|
|
||||||
return CRC_NULL;
|
return CRC_NULL;
|
||||||
|
#endif // USE_LORA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FDRS Sensor pings gateway and listens for a defined amount of time for a reply
|
||||||
|
// Blocking function for timeout amount of time (up to timeout time waiting for reply)(IE no callback)
|
||||||
|
// Returns the amount of time in ms that the ping takes or predefined value if ping fails within timeout
|
||||||
|
uint32_t pingFDRSLoRa(uint16_t *address, uint32_t timeout)
|
||||||
|
{
|
||||||
|
#ifdef USE_LORA
|
||||||
|
SystemPacket sys_packet = {.cmd = cmd_ping, .param = 0};
|
||||||
|
|
||||||
|
transmitLoRa(address, &sys_packet, 1);
|
||||||
|
DBG("LoRa ping sent to address: 0x" + String(*address, HEX));
|
||||||
|
uint32_t ping_start = millis();
|
||||||
|
pingFlag = false;
|
||||||
|
while ((millis() - ping_start) <= timeout)
|
||||||
|
{
|
||||||
|
handleLoRa();
|
||||||
|
yield(); //do I need to yield or does it automatically?
|
||||||
|
if (pingFlag)
|
||||||
|
{
|
||||||
|
DBG("LoRa Ping Returned: " + String(millis() - ping_start) + "ms.");
|
||||||
|
pingFlag = false;
|
||||||
|
return (millis() - ping_start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("No LoRa ping returned within " + String(timeout) + "ms.");
|
||||||
|
return UINT32_MAX;
|
||||||
|
#endif // USE_LORA
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void printLoraPacket(uint8_t *p, int size)
|
void printLoraPacket(uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
printf("Printing packet of size %d.", size);
|
printf("Printing packet of size %d.", size);
|
||||||
|
Loading…
Reference in New Issue
Block a user