GrumpyOldPizza / ArduinoCore-stm32l0

Arduino Core for STM32L0
125 stars 67 forks source link

Payload size very limited only with AS923 frequency plan #189

Open Sistrum opened 3 years ago

Sistrum commented 3 years ago

Hello everyone!

I have an issue with the LoRaWAN library. My device sends 1 payload every 10 minutes. When I use the EU868 or the US915 frequency plan, the maximum size of a payload accepted by the LoRaWAN library is about 50 bytes. When I use the AS923, I cannot send more than 11 bytes per payload.

I tried LoRaWAN.setDutyCycle(false) -> No change I tried different times between the payloads (from 20sec to 20min) -> No change I checked also check the air time: AS923, 11 bytes = 288ms AS923, 12 bytes = Doesn't work (library error) EU868, 11 bytes = 1155ms EU868, 50 bytes = 2302ms -> The air time doesn't seem to be the problem.

Did anyone face the same issue? Or have an idea of what to do to solve it? Thanks

GrumpyOldPizza commented 3 years ago

Do you have ADR enabled ?

Sistrum commented 3 years ago

Hi and thanks for your quick answer!

I didn't set it, so, yes, I guess the ADR was enabled (default state). I tried to disable it and chose the minimum and maximum TxPower for Asia (2 and 16) and dataRate = DR_1 but, sadly, it didn't solve the issue.

I added some debug prints in the library in the "_send()" function as followed. The error is always the number 2.

if (LoRaWANQueryTxPossible(0, _DataRate, &txInfo) != LORAMAC_STATUS_OK)
    {
        _tx_active = false;
        _tx_busy = false;

        Serial.println("Error 1");
        return false;
    }

    if (_tx_size > txInfo.CurrentPayloadSize)
    {
        _tx_active = false;
        _tx_busy = false;

        Serial.println("Error 2");
    return false;
    }

    [...]

    if (LoRaWANMcpsRequest(&mcpsReq) != LORAMAC_STATUS_OK)
    {
        _tx_active = false;
        _tx_busy = false;

        Serial.println("Error 3");
        return false;
    }
Sistrum commented 3 years ago

Ok, I found a solution.

In this file -> RegionAS923.h, we found this :

#define AS923_DEFAULT_DATARATE                      DR_2

[...]

#define AS923_DEFAULT_UPLINK_DWELL_TIME             1

[...]

/*!
 * Maximum payload with respect to the data rate index. Cannot operate with repeater.
 * The table is valid for the dwell time configuration of 0 for uplinks and downlink.
 */
* static const uint8_t MaxPayloadOfDatarateDwell0AS923[] = { 51, 51, 51, 115, 242, 242, 242, 242 };<!--EndFragment-->

[...]

/*!
 * Maximum payload with respect to the datarate index. Can operate with and without repeater.
 * The table proides repeater support. The table is only valid for uplinks.
 */
static const uint8_t MaxPayloadOfDatarateDwell1UpAS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 };<!--EndFragment-->

It seemed that the payload size was limited by those constants. So I had 2 solutions: Disable the ADR and choose a higher DataRate (at least DR_3), or, better, keep ADR enable and choose the Dwell0 tab in place of the Dwell1 tab. I chose the second solution but I didn't want to modify directly the library. So I searched in the LoRaWAN library and found this:

int LoRaWANClass::setUpLinkDwellTime(bool enable)
{
    MibRequestConfirm_t mibReq;

    if (!_Band) {
        return 0;
    }

    if (_tx_busy) {
        return 0;
    }

    mibReq.Type = MIB_UPLINK_DWELL_TIME;
    mibReq.Param.DefaultUplinkDwellTime = enable;
    if (LoRaWANMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) {
        return 0;
    }

    if (!_Joined) {
        mibReq.Type = MIB_DEFAULT_UPLINK_DWELL_TIME;
        mibReq.Param.DefaultUplinkDwellTime = enable;
        if (LoRaWANMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) {
            return 0;
        }
    } else {
        if (_Save) {
            _params.UpLinkDwellTime = enable;
            _saveParams();
        }
    }

    return 1;
}

So, in my code, I kept the ADR enable and added this line:

LoRaWAN.setUpLinkDwellTime(0);

And now it's ok. The payload maximum size is now 51.

I'm just not sure about what is the repeater and if I need it or not. Can someone tell me it?

GrumpyOldPizza commented 3 years ago

Interesting. Did you crosscheck that with the region specification ?

The repeater was an idea that never seemed to pan out in the practice. It has been removed by the specification now.

kevin192291 commented 3 years ago

Hello! I have been using this library in the AS923 (jp) region for quite some time with absolutely no problems. The only thing is that the very first message needs to be 11 bytes, the next message can be much higher (230 bytes). Not sure if this helps or if you are doing what I am.... but in case it does :)

if (LoRaWAN.getMaxPayloadSize() > myLPP.getSize()) {
              Serial.print("LoRaWAN about to send: ");
              Serial.print(myLPP.getSize());
              Serial.println(" Bytes of data");
              LoRaWAN.sendPacket(myLPP.getBuffer(), myLPP.getSize());
              myLPP.reset();
              modbusHasData = false;
            } else {
              Serial.println("Can't send too large of a packet in the start, lets just say hi!");
              LoRaWAN.beginPacket();
              LoRaWAN.write(0x68);
              LoRaWAN.write(0x69);
              LoRaWAN.endPacket();
              myLPP.reset();
              modbusHasData = false;
            }