Tweak LoRa timing, tx/rx stats

pull/193/head
Jeff Lehman 3 months ago
parent 3477c70e55
commit 718f919253

@ -137,11 +137,13 @@ int loraAckState = stReady;
volatile bool transmitFlag = false; // flag to indicate transmission or reception state
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
unsigned long receivedLoRaMsg = 0; // Number of total LoRa packets destined for us and of valid size
unsigned long ackOkLoRaMsg = 0; // Number of total LoRa packets with valid CRC
unsigned long loraAckTimeout = 0;
unsigned long rxCountDR = 0; // Number of total LoRa DR packets destined for us and of valid size
unsigned long rxCountSP = 0; // Number of total LoRa SP packets destined for us and of valid size
unsigned long rxCountCrcOk = 0; // Number of total Lora packets with valid CRC
unsigned long txCountDR = 0; // Number of total LoRa DR packets transmitted
unsigned long txCountSP = 0; // Number of total LoRa SP packets transmitted
extern time_t now;
unsigned long transmitLoRaMsgwAck = 0; // Number of total LoRa packets destined for us and of valid size
unsigned long msgOkLoRa = 0; // Number of total LoRa packets with valid CRC
time_t netTimeOffset = UINT32_MAX; // One direction of LoRa Ping time in units of seconds (1/2 full ping time)
unsigned long tx_start_time = 0;
@ -239,6 +241,7 @@ void transmitLoRa(uint16_t *destMac, DataReading *packet, uint8_t len)
while (true)
;
}
txCountDR++;
return;
}
@ -279,6 +282,7 @@ void transmitLoRa(uint16_t *destMac, SystemPacket *packet, uint8_t len)
while (true)
;
}
txCountSP++;
return;
}
@ -487,15 +491,7 @@ crcResult receiveLoRa()
#endif
{ // Check if addressed to this device or broadcast
// printLoraPacket(packet,sizeof(packet));
if (receivedLoRaMsg != 0)
{ // Avoid divide by 0
DBG1("Incoming LoRa. Size: " + String(packetSize) + " Bytes, RSSI: " + String(radio.getRSSI()) + "dBm, SNR: " + String(radio.getSNR()) + "dB, PacketCRC: 0x" + String(packetCRC, HEX) + ", Total LoRa received: " + String(receivedLoRaMsg) + ", CRC Ok Pct " + String((float)ackOkLoRaMsg / receivedLoRaMsg * 100) + "%");
}
else
{
DBG1("Incoming LoRa. Size: " + String(packetSize) + " Bytes, RSSI: " + String(radio.getRSSI()) + "dBm, SNR: " + String(radio.getSNR()) + "dB, PacketCRC: 0x" + String(packetCRC, HEX) + ", Total LoRa received: " + String(receivedLoRaMsg));
}
receivedLoRaMsg++;
DBG1("Incoming LoRa. Size: " + String(packetSize) + " Bytes, RSSI: " + String(radio.getRSSI()) + "dBm, SNR: " + String(radio.getSNR()) + "dB, PacketCRC: 0x" + String(packetCRC, HEX));
// Evaluate CRC
for (int i = 0; i < (packetSize - 2); i++)
{ // Last 2 bytes of packet are the CRC so do not include them in calculation
@ -504,6 +500,7 @@ crcResult receiveLoRa()
}
if ((packetSize - 6) % sizeof(DataReading) == 0)
{ // DataReading type packet
rxCountDR++;
if (calcCRC == packetCRC)
{ // We've received a DR and sending an ACK
SystemPacket ACK = {.cmd = cmd_ack, .param = CRC_OK};
@ -523,27 +520,29 @@ crcResult receiveLoRa()
newData = event_clear; // do not process data as data may be corrupt
return CRC_BAD; // Exit function and do not update newData to send invalid data further on
}
rxCountCrcOk++;
memcpy(&theData, &packet[4], packetSize - 6); // Split off data portion of packet (N - 6 bytes (6 bytes for headers and CRC))
ln = (packetSize - 6) / sizeof(DataReading);
ackOkLoRaMsg++;
if (memcmp(&sourceMAC, &LoRa1, 2) == 0)
{ // Check if it is from a registered sender
newData = event_lora1;
return CRC_OK;
}
if (memcmp(&sourceMAC, &LoRa2, 2) == 0)
else if (memcmp(&sourceMAC, &LoRa2, 2) == 0)
{
newData = event_lora2;
return CRC_OK;
}
newData = event_lorag;
return CRC_OK;
else {
newData = event_lorag;
return CRC_OK;
}
}
else if ((packetSize - 6) == sizeof(SystemPacket))
{
unsigned int ln = (packetSize - 6) / sizeof(SystemPacket);
SystemPacket receiveData[ln];
rxCountSP++;
if ((packetCRC == calcCRC) || (packetCRC == crc16_update(calcCRC, 0xA1)))
{
memcpy(receiveData, &packet[4], packetSize - 6); // Split off data portion of packet (N bytes)
@ -595,7 +594,7 @@ crcResult receiveLoRa()
DBG2("Received some LoRa SystemPacket data that is not yet handled. To be handled in future enhancement.");
DBG2("ln: " + String(ln) + "data type: " + String(receiveData[0].cmd));
}
ackOkLoRaMsg++;
rxCountCrcOk++;
return CRC_OK;
}
else
@ -647,6 +646,10 @@ crcResult LoRaTxRxOperation()
loraTxState = stCompleted;
DBG1("LoRa airtime: " + String(millis() - tx_start_time) + "ms");
radio.startReceive(); // return to listen mode
// Start ACK timeout after transmission is completed.
if(loraAckState == stInProcess) {
loraAckTimeout = millis();
}
transmitFlag = false;
// Serial.println("TxINT!");
}
@ -750,6 +753,7 @@ void handleLoRa()
static DataReading *data;
static uint16_t address;
static unsigned long lastTxtime = 0;
static unsigned long statsTime = 0;
LoRaTxRxOperation();
@ -777,21 +781,20 @@ void handleLoRa()
}
static int retries = FDRS_LORA_RETRIES;
static unsigned long loraAckTimeout = 0;
// Process any DR ACKs in progress
if(loraTxState == stReady && loraAckState != stReady) {
if (loraAckState == stCrcMatch)
{
DBG1("LoRa ACK Received! CRC OK");
msgOkLoRa++;
free(data);
data = NULL;
retries = FDRS_LORA_RETRIES;
len = 0;
loraAckState = stReady;
}
else if(retries < 0) {
DBG2("Retries Exhausted.");
DBG1("Retries Exhausted.");
retries = FDRS_LORA_RETRIES;
if(ISBUFFFULL(drBuff)) {
len = 0;
@ -803,39 +806,41 @@ void handleLoRa()
len = 0;
free(data);
data = NULL;
loraAckState = stReady;
}
else if (loraAckState == stCrcMismatch)
{
DBG1("LoRa ACK Received! CRC BAD");
// Resend original packet again if retries are available
loraAckState = stReady;
}
else if (TDIFF(loraAckTimeout,FDRS_ACK_TIMEOUT)) {
DBG1("LoRa Timeout waiting for ACK!");
// resend original packet again if retries are available
loraAckState = stReady;
}
if(loraTxState == stCompleted) {
loraTxState = stReady;
}
loraAckState = stReady;
return;
}
// It's polite to Listen more than you talk
if(TDIFF(lastTxtime,(TXDELAYMS + random(0,50)))) {
// Start Transmit data from the SystemPacket queue
if(!ISBUFFEMPTY(spBuff) && (loraTxState == stReady)) {
DBG2("SP Index: start: " + String(spBuff.startIdx) + " end: " + String(spBuff.endIdx) + " Address: 0x" + String(*(spBuff.address + spBuff.startIdx),HEX) + " Cmd: " + String(spBuff.sp->cmd));
// Lora ping request stuff here
if((spBuff.sp + spBuff.startIdx)->cmd == cmd_ping && (spBuff.sp + spBuff.startIdx)->param == ping_request) {
loraPing.status = stInProcess;
loraPing.start = millis();
DBG1("LoRa ping request sent to address: 0x" + String(*(spBuff.address + spBuff.startIdx), HEX));
}
transmitLoRa((spBuff.address + spBuff.startIdx), (spBuff.sp + spBuff.startIdx), 1);
BUFFINCSTART(spBuff);
// Start Transmit data from the SystemPacket queue
if(!ISBUFFEMPTY(spBuff) && (loraTxState == stReady)) {
DBG2("SP Index: start: " + String(spBuff.startIdx) + " end: " + String(spBuff.endIdx) + " Address: 0x" + String(*(spBuff.address + spBuff.startIdx),HEX) + " Cmd: " + String(spBuff.sp->cmd));
// Lora ping request stuff here
if((spBuff.sp + spBuff.startIdx)->cmd == cmd_ping && (spBuff.sp + spBuff.startIdx)->param == ping_request) {
loraPing.status = stInProcess;
loraPing.start = millis();
DBG1("LoRa ping request sent to address: 0x" + String(*(spBuff.address + spBuff.startIdx), HEX));
}
transmitLoRa((spBuff.address + spBuff.startIdx), (spBuff.sp + spBuff.startIdx), 1);
BUFFINCSTART(spBuff);
}
// It's polite to Listen more than you talk
if(TDIFF(lastTxtime,(TXDELAYMS + random(0,50)))) {
// Start Transmit data from the DataReading queue
if((!ISBUFFEMPTY(drBuff) || (data != NULL)) && loraTxState == stReady && loraAckState == stReady)
{
@ -872,7 +877,6 @@ void handleLoRa()
{
retries--;
loraAckState = stInProcess;
loraAckTimeout = millis();
transmitLoRa(&address, data, len);
}
}
@ -889,7 +893,12 @@ void handleLoRa()
}
lastTxtime = millis();
}
// Print LoRa statistics
if(TDIFFSEC(statsTime,65) && (rxCountDR + rxCountSP) > 0) {
statsTime = millis();
DBG1("LoRa Stats - Rx DR:" + String(rxCountDR) + " SP:" + String(rxCountSP) + " Tx DR:" + String(txCountDR) + " SP:" + String(txCountSP) + " CRC OK: " + String(rxCountCrcOk/(rxCountDR + rxCountSP) * 100) + "%");
}
// Change to ready at the end so only one transmit happens per function call
if(loraTxState == stCompleted) {
loraTxState = stReady;

Loading…
Cancel
Save