Hi all,
I am running sensors on 1MHz pro minis with RFM 69W radios sending the sensor data to an MHz pro mini gateway.
I am using the excellent RFM69 library from LowPower labs (GitHub - LowPowerLab/RFM69: RFM69 library for RFM69W, RFM69HW, RFM69CW, RFM69HCW (semtech SX1231, SX1231H))
Everything works pretty nicely, except that the sensor frequently fails to receive/see the ACKs sent by the gateway; I don't believe this is a radio issue, because a) the problem doesn't happen on 8MHz sensors and b) when the sensor actually sees the ACK the RSSI is in the -40 range.
I have a board in promiscuous mode that sees the gateway sending the ACKs right upon receiving the sensor's message.
I suspect that what is happening is that the sensor running at 1MHz is missing the ACK altogether because it arrives between the time the sensor completes its send and the time the library puts the radio in receive mode.
I seem to have improved things somewhat with the small code change below that calls ACKReceived straight away (the original code had two millis() calls), but send(...) still puts the radio in standby mode before ACKReceived calls receiveDone which puts the radio in receive mode.
Does any of the above make sense, and is there a better way to resolve the problem?
Promiscuous node log:
[316s] 0 -> 254 [VOLT power:30, current:3016, min:2000]
[316s] 254 -> 0 [ACK RSSI=-50}
[316s] 0 -> 254 [VOLT power:30, current:3016, min:2000]
[316s] 254 -> 0 [ACK RSSI=-50}
[316s] 0 -> 254 [VOLT power:30, current:3016, min:2000]
(sensor retries twice since it didn't see the ACK. RSSI on the sensor side not printed here, but also in the 50s)
My changes to sendWithRetry:
bool RFM69_ATC::sendWithRetry(uint8_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries, uint8_t retryWaitTime) {
uint32_t sentTime;
for (uint8_t i = 0; i <= retries; i++)
{
sentTime = millis(); // moved here to call ACKReceived ASAP
send(toAddress, buffer, bufferSize, true);
do {
if (ACKReceived(toAddress))
{
return true;
}
}
// tried 10*retryWaitTime here, didn't help...
while (millis() - sentTime < retryWaitTime); // moved here to call ACKReceived ASAP
#ifdef DEBUG
Serial.print(F("No ack after ")); Serial.print(millis() - sentTime); Serial.println("ms"); Serial.flush();
#endif
}
if (_transmitLevel < 31) _transmitLevel++;
return false;
}
My RFM69 call:
boolean sent = radio.sendWithRetry(
GATEWAYID, (const void*)(payload), size, /**RETRIES**/ 2, 235+ random(-20, 20));