Sending Packet sized above 64 bytes

Hello, I'm trying my hand at Arduino for the first time.
I'm trying to send data to my gateway via the MKR1310, but it only works as long as I keep the maximum packet size of 64 bytes.
The following code works, but as soon as I set BUFFER_SIZE >64, the Serial Monitor shows me an error sending message. Can't I send packets larger than 64 bytes with the MKR1310? I look forward to suggestions for a solution.

#include <MKRWAN.h>
#include "ArduinoLowPower.h"
#include "arduino_secrets.h"

#define SEND_INTERVAL 8 // Send interval in mins
#define BUFFER_SIZE  64 // Data buffer size in bytes

String appEui = SECRET_APP_EUI;
String appKey = SECRET_APP_KEY;

LoRaModem modem;

int totalRuns = 0;         // Gesamtanzahl der Durchläufe
int successfulRuns = 0;    // Anzahl der erfolgreichen Durchläufe

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Begin debugging...");

  if (!modem.begin(EU868)) {
    while (1) {}
  };

  Serial.print("Firmware version: ");
  Serial.println(modem.version());
  Serial.print("Device EUI: ");
  Serial.println(modem.deviceEUI());

  delay(5000);

  int connected = modem.joinOTAA(appEui, appKey);
  if (!connected) {
    while (1) {}
  }
  
  modem.dataRate(5);

  modem.setADR(true);
}

void loop() {
  totalRuns++;  // Erhöhe die Anzahl der Durchläufe bei jedem Start des Loop
  
  delay(2000);
  Serial.println("Delay for 1 seconds");

  uint8_t buffer2[BUFFER_SIZE] = {0};
  delay(1000);
  Serial.println("Buffer sensor readings");

  int err = 0;
  modem.beginPacket();
  modem.write(buffer2, BUFFER_SIZE);
  Serial.println("Started LoRa packet");

  err = modem.endPacket(true);
  Serial.println("Ended LoRa packet");

  if (err > 0) {
    successfulRuns++;  // Erhöhe die Anzahl der erfolgreichen Durchläufe, wenn das Senden erfolgreich war
    Serial.println("Message sent correctly!");
  } else {
    Serial.println("Error sending message");
  }
  
  Serial.print("Current run: ");
  Serial.print(totalRuns);
  Serial.print(", Successful runs: ");
  Serial.println(successfulRuns);
  
  if ((totalRuns - successfulRuns) > 3) {
    Serial.println("Restarting Arduino...");
    delay(2000); // wait 2 Sec before restart
    NVIC_SystemReset(); // FĂĽhre einen Systemneustart durch
  }
  
  delay(SEND_INTERVAL * 60000); // Convert mins to milliseconds
}

The options are to change the library code, or to break large messages into pieces <= 64 bytes, send them individually, and reconstruct at the other end.

could you explain the first option in more detail, i would be very grateful.

You can change the internal buffer size in the library code. You will need to make a copy of the code, and keep it in a separate place, like a subfolder of the sketch folder. The "#include" will need to refer to the new library location.

This is not recommended for a first-time project, unless you are already familiar with C/C++ coding.

Here is one place to start

And here is code that assumes a fixed buffer size:

   */
  int8_t waitResponse(uint32_t timeout, String& data,
                       ConstStr r1=GFP(LORA_OK), ConstStr r2=GFP(LORA_ERROR),
                       ConstStr r3=NULL, ConstStr r4=NULL, ConstStr r5=NULL,
                       ConstStr r6=NULL, ConstStr r7=NULL, ConstStr r8=NULL)
  {
    data.reserve(64);

And just by the way, this library is really awful code and not a good example to follow. Arduino.cc scraped the bottom of the barrel for this!

        if (r1 && data.endsWith(r1)) {
          index = 1;
          goto finish;
        } else if (r2 && data.endsWith(r2)) {
          index = 2;
          goto finish;
1 Like

Thank you for the response and suggestion. In the same folder where the sketch is located, I copied the original MKRWAN folder and switched the value from 64 to 128 in the mkrwan.h file, as described. However, this alone did not help. The successful transmission occurred at a maximum of 64 bytes. Then, in the same mkrwan.h file, I modified this section from 64 to 128 without giving it much thought:

size_t modemGetMaxSize() {
    if (isArduinoFW()) {
      return 64;
    }
    sendAT(GF("+MSIZE?"));
    if (waitResponse(2000L) != 1) {
      return 0;
    }
    streamSkipUntil('=');
    return stream.readStringUntil('\r').toInt();
  }

Afterwards, I attempted to increase the buffer size again and was able to reach 76 bytes.

Did I do something wrong?

Thank you in advance.

There must be other places where buffer size 64 is assumed.

It is for exactly that reason that I wrote "this is one place to start".

To successfully modify the code (especially such poorly written code as this), unfortunately you need to track down all the parts and understand how they work together.

The waitResponse() code I quoted appears to be part of the receive functionality, so look for transmit parts.

It would probably be easier for you to write the application to live within the 64 byte limitation.

Thank you for the response. So, there is no hardware limitation? That's good to hear.

Of course there is: the radio has limitations, processor memory is limited, etc.

A LoRa device has a maximum packet length of 255 bytes.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.