diff --git a/crossbow/crossbow.ino b/crossbow/crossbow.ino index f3d8fa2..9204c6e 100644 --- a/crossbow/crossbow.ino +++ b/crossbow/crossbow.ino @@ -124,6 +124,15 @@ void onQspSuccess(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDev //If recide received a valid frame, that means it can start to talk qsp->canTransmit = true; + /* + * RX module hops to next channel after frame has been received + */ +#ifdef DEVICE_MODE_RX + hopFrequency(radioState, true, radioState->lastReceivedChannel); + radioState->failedDwellsCount = 0; // We received a frame, so we can just reset this counter + LoRa.receive(); //Put radio back into receive mode +#endif + //Store the last timestamp when frame was received if (qsp->frameId < QSP_FRAME_COUNT) { qsp->lastFrameReceivedAt[qsp->frameId] = millis(); @@ -157,14 +166,6 @@ void onQspSuccess(QspConfiguration_t *qsp, TxDeviceState_t *txDeviceState, RxDev break; } - /* - * RX module hops to next channel after frame has been received - */ -#ifdef DEVICE_MODE_RX - hopFrequency(radioState, true, radioState->lastReceivedChannel); - LoRa.receive(); //Put radio back into receive mode -#endif - qsp->transmitWindowOpen = true; } @@ -326,6 +327,26 @@ void loop(void) uint32_t currentMillis = millis(); /* + * This routine handles resync of TX/RX while hoppping frequencies + */ +#ifdef DEVICE_MODE_RX + + //In the beginning just keep jumping forward and try to resync over lost single frames + if (radioState.failedDwellsCount < 6 && radioState.channelEntryMillis + RX_CHANNEL_DWELL_TIME < currentMillis) { + hopFrequency(&radioState, true, radioState.channel); + LoRa.receive(); + radioState.failedDwellsCount++; + } + + // If we are loosing more frames, start jumping in the opposite direction since probably we are completely out of sync now + if (radioState.failedDwellsCount >= 6 && radioState.channelEntryMillis + (RX_CHANNEL_DWELL_TIME * 5) < currentMillis) { + hopFrequency(&radioState, false, radioState.channel); //Start jumping in opposite direction to resync + LoRa.receive(); + } + +#endif + + /* * Detect the moment when radio module stopped transmittig and put it * back in to receive state */ diff --git a/crossbow/variables.h b/crossbow/variables.h index 6481cfa..fa13dd6 100644 --- a/crossbow/variables.h +++ b/crossbow/variables.h @@ -14,6 +14,7 @@ #define RSSI_CHANNEL 11 #define TX_TRANSMIT_SLOT_RATE 67 //ms +#define RX_CHANNEL_DWELL_TIME (TX_TRANSMIT_SLOT_RATE + 10) //Dwell on a channel slightly longer #define RX_FAILSAFE_DELAY (TX_TRANSMIT_SLOT_RATE * 8) #define TX_FAILSAFE_DELAY (RX_FAILSAFE_DELAY * 4) @@ -108,6 +109,7 @@ struct RadioState_t { uint8_t channel = 0; uint8_t lastReceivedChannel = 0; uint32_t channelEntryMillis = 0; + uint8_t failedDwellsCount = 0; }; struct TxDeviceState_t {