Author Topic: Suggestion for possible improvements of RFM69 library  (Read 2620 times)

RoSchmi

  • NewMember
  • *
  • Posts: 23
  • Country: de
Suggestion for possible improvements of RFM69 library
« on: December 18, 2016, 09:40:45 AM »
First of all, thank you for making you great library open source.
In the last months I studied the code quite intensively and found two minor points of potential improvements.
1) Concerns RFM69_ATC: If ATC is activated and the recipient does not return ACKs, the sender dials up the power level til it reaches 31. It would be nice, if the maximal powerlevel could be limited to a value defined by the user. This could be achieved through a second optional parameter to the setPowerLevel function specifying the maximum value to which the power is dialed up when the recipient is not online.
2) Concerns the sendACK and canSend methods:

Code: [Select]
RFM69::canSend() 
{                                                                                                      // CSMA_LIMIT = - 90
    if (_mode == RF69_MODE_RX && PAYLOADLEN == 0 && readRSSI() < CSMA_LIMIT) // if signal stronger than -100dBm is detected assume channel activity
    {
        setMode(RF69_MODE_STANDBY);
        return true;
    }
    return false;
}

Code: [Select]
// should be called immediately after reception in case sender wants ACK
void RFM69::sendACK(const void* buffer, uint8_t bufferSize) {
  ACK_REQUESTED = 0;   // TWS added to make sure we don't end up in a timing race and infinite loop sending Acks
  uint8_t sender = SENDERID;
  int16_t _RSSI = RSSI; // save payload received RSSI value
  writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
  uint32_t now = millis();
  while (!canSend() && millis() - now < RF69_CSMA_LIMIT_MS) receiveDone();    // RF69_CSMA_LIMIT_MS = 1000 ms
  SENDERID = sender;    // TWS: Restore SenderID after it gets wiped out by receiveDone()
  sendFrame(sender, buffer, bufferSize, false, true);
  RSSI = _RSSI; // restore payload RSSI
}

It seems that there are some RFM69 modules which do not return the correct actual RSSI Level in the readRSSI() function. In your library the threshold CSMA_LIMIT is set to -90 but those modules return values of about -70 or -80 that the canSend method always returns false until the timeout RF69_CSMA_LIMIT_MS (set to 1000 ms) has expired. This timeout seems to be to long since in the sendWithRetry method the longest possible wait time for an ACC is 256 ms. So the transmitter will evt. fire the full number of retries as it doesn't get the ACK in the time window of 256 ms. So it would evt. be better to set the RF69_CSMA_LIMIT_MS to e.g. 200 ms.
It should be considered to let the CSMA_LIMIT flow in a range from lets say -60 to -90 through a function like this in the send and sendACK method.
Code: [Select]
//replace in sendACK: while (!canSend() && millis() - now < RF69_CSMA_LIMIT_MS) receiveDone();

//with something like this:
 
  uint32_t StartTime = millis();
  while (true)
            {
                if (canSend())
                {
                    _adjusted_CSMA_LIMIT = _adjusted_CSMA_LIMIT - 1;
                    _adjusted_CSMA_LIMIT = _adjusted_CSMA_LIMIT < -90 ? -90 : _adjusted_CSMA_LIMIT;
                   break;
                }
                if (millis() - StartTime > RF69_CSMA_LIMIT_MS)
                {
                    // Level is stepped up from -90 in steps of 2, but not higher than -60
                    _adjusted_CSMA_LIMIT = _adjusted_CSMA_LIMIT + 2;
                    _adjusted_CSMA_LIMIT = _adjusted_CSMA_LIMIT > -60 ? -60 : _adjusted_CSMA_LIMIT;
                    break;
                }
                    receiveDone();
            }
Kind regards
RoSchmi

WhiteHare

  • Hero Member
  • *****
  • Posts: 1300
  • Country: us
Re: Suggestion for possible improvements of RFM69 library
« Reply #1 on: December 18, 2016, 11:08:40 AM »
Those are good suggestions.  CanSend has also been known to hang things, and so--lacking a better solution--some people have simply eliminated it altogether.

joelucid

  • Hero Member
  • *****
  • Posts: 868
Re: Suggestion for possible improvements of RFM69 library
« Reply #2 on: December 18, 2016, 11:41:10 AM »
Quote
It would be nice, if the maximal powerlevel could be limited to a value defined by the user. This could be achieved through a second optional parameter to the setPowerLevel function specifying the maximum value to which the power is dialed up when the recipient is not online.

Here's what I do: I'll always send the last retry attempt at full tx power regardless of the current adjusted power settings. If that attempt also fails I conclude that the gw is not reachable and ignore all failed packets of this send attempt for ATC purposes.

This avoids the problem you describe and also ensures that transient link impairments can be overcome in the last attempt.

Joe

RoSchmi

  • NewMember
  • *
  • Posts: 23
  • Country: de
Re: Suggestion for possible improvements of RFM69 library
« Reply #3 on: December 18, 2016, 12:10:43 PM »
Quote
Here's what I do: I'll always send the last retry attempt at full tx power regardless of the current adjusted power settings. If that attempt also fails I conclude that the gw is not reachable and ignore all failed packets of this send attempt for ATC purposes.

This avoids the problem you describe and also ensures that transient link impairments can be overcome in the last attempt.

Interesting solution, but the transmitter sends at least one send with full power. I thought more of a situation where I know that there is a good connection with a certain power level, but the gateway is sometimes switched off. In such a situation the transmitter should not send with a high power that is above the level allowed by FCC regulations and should not unnecessarily waste the battery.

joelucid

  • Hero Member
  • *****
  • Posts: 868
Re: Suggestion for possible improvements of RFM69 library
« Reply #4 on: December 18, 2016, 12:16:18 PM »
Quote
In such a situation the transmitter should not send with a high power that is above the level allowed by FCC regulations and should not unnecessarily waste the battery.

True. I actually need that feature, too, for my coin cell motes. There I do set a max power level but then still use that level in the last send attempt. I just don't want ATC to react to a unreachable gw at all.

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Suggestion for possible improvements of RFM69 library
« Reply #5 on: December 18, 2016, 05:28:15 PM »
1) Concerns RFM69_ATC: If ATC is activated and the recipient does not return ACKs, the sender dials up the power level til it reaches 31.
The original ATC code did not do this, if no ACK was received, no adjustment is done.   This is a recent change in the LowPower branch and was added because some felt that if the TX level started too low to reach the GW, then there would be no means of updating the TX level.  In my nodes (unless coin cell powered as Joe points out) I always start a new mote at max TX level and set a reasonable RSSI target (-69dB).  So, as long as the gateway is reachable (running or out of range even at max level), then the Mote settles into a comfortable and sufficient level.

Tom

joelucid

  • Hero Member
  • *****
  • Posts: 868
Re: Suggestion for possible improvements of RFM69 library
« Reply #6 on: December 18, 2016, 06:15:00 PM »
Quote
The original ATC code did not do this, if no ACK was received, no adjustment is done.

Wouldn't that require that you send the last attempt at full power though? Otherwise how do you deal with situations where link quality becomes impaired? Example: the weekend house - when I leave on Sundays I turn the blinds down. That reduces link quality enough that some motes have to dial up.

I guess with 69 dBm you have around 31 dBm of fade margin so you might be ok. Still.

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Suggestion for possible improvements of RFM69 library
« Reply #7 on: December 19, 2016, 08:41:53 AM »
I guess with 69 dBm you have around 31 dBm of fade margin so you might be ok.
Exactly so...

Now, if you raise the faraday cage around your house...

RoSchmi

  • NewMember
  • *
  • Posts: 23
  • Country: de
Re: Suggestion for possible improvements of RFM69 library
« Reply #8 on: December 19, 2016, 07:38:33 PM »
The original ATC code did not do this, if no ACK was received, no adjustment is done.   This is a recent change in the LowPower branch and was added because some felt that if the TX level started too low to reach the GW, then there would be no means of updating the TX level.  In my nodes (unless coin cell powered as Joe points out) I always start a new mote at max TX level and set a reasonable RSSI target (-69dB).  So, as long as the gateway is reachable (running or out of range even at max level), then the Mote settles into a comfortable and sufficient level.
Tom

Thanks, I'll have a closer look on your code later. Is your TomWS1/RFM69_ATC still compatible with the actual LowPowerLab RFM69 library?

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Suggestion for possible improvements of RFM69 library
« Reply #9 on: December 19, 2016, 09:54:00 PM »
Thanks, I'll have a closer look on your code later. Is your TomWS1/RFM69_ATC still compatible with the actual LowPowerLab RFM69 library?
Interesting question.  I've been working with my own local version and I'll have to check to see if there are any variations from this to what is on github.  Also, I'm maintaining my own local copy of RFM69 Library so same requirement applies here.  On the surface, it 'should' be ok, but I can't say for sure without testing.  I've been watching updates to RFM69 library and didn't see anything I needed to follow.  Hence, I've simply kept what I know works for me. 

I can't promise that I'll look at this before the new year.  I've got too many other projects to complete before the end of this year.

Net: get my github version and diff with what's in current lowpower version.  Use what works for you...

Tom