PowerBroker2 / SerialTransfer

Arduino library to transfer dynamic, packetized data fast and reliably via Serial, I2C, or SPI
MIT License
408 stars 68 forks source link

Compatibiliy with AtMega4808 under MegaCoreX /w SoftwareSerial #98

Open adelin-mcbsoft opened 1 year ago

adelin-mcbsoft commented 1 year ago

Hello ! So, I know that support for SoftwareSerial is limited, however I'm having an issue that I think it might be not related to it.

I was wondering if the library is compatible with Arduino Nano Every (AtMega4809 or AtMega4808) family, which is ran under MegaCoreX board framework. It's still 8-bit AVR, all my other libraries work, just this one does not.

I replaced Nano @ AtMega328p in a project with a Nano Every (clone) @ AtMega 4808 as I needed more memory, and ran the same code.

My surprise was to see that though I had stable serial communication between two MCUs (AtMega4808 and ESP8266, tested without the library), with this library, the received data between the MCUs was totally different.

For example, I used the SendDatum over UART examples. Works totally fine with the little amount of data present in the examples.

But as soon as I added more data to it, I was receiving totally different numbers on the other side.

For example, on the Nano Every (AtMega4808) I sent the following struct:

struct __attribute__((packed)) STRUCT {
  char z;
  float y;
  int q;
  int t;
  int p;
} testStruct;

and the data:

  testStruct.z = '$';
  testStruct.y = 4.5;
  testStruct.q = 101;
  testStruct.t = 202;
  testStruct.p = 404;

And on the receiving end (ESP8266) I was receiving the following data: 18:46:36.307 -> $ | 4.50 | 13238373 | 1701314964 | 7302252

Which looks to me more like a bit-conversion issue rather than something with SoftwareSerial. And it worked somewhat fine with the Nano 328p.

_(I say "somewhat", as with the Nano 328p I was receiving a lot of CRC_ERRORs due to low memory I guess -- I had only 91 bytes RAM left, however with Nano Every 4808 there are no errors present whatsoever, just the data isn't the same)._

Same thing applies if I try to send it the other way (from ESP8266 to Nano Every 4808). With little data is ok. As soon as I add more, I receive totally different numbers.

Any lead to fix this would be very helpful. Thank you.

PowerBroker2 commented 1 year ago

Looks like an "endian" difference between the two MCUs. Try swapping the byte order on the ints on the receiver and see if it helps. Might also be useful to set the int size manually.

adelin-mcbsoft commented 1 year ago

Both MCUs report being "Little Endian". I ran the following code to find out:

#include <Arduino.h>

#include <limits.h>
#include <stdint.h>

#if CHAR_BIT != 8
#error "unsupported char size"
#endif

enum
{
    O32_LITTLE_ENDIAN = 0x03020100ul,
    O32_BIG_ENDIAN = 0x00010203ul,
    O32_PDP_ENDIAN = 0x01000302ul
};

static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
    { { 0, 1, 2, 3 } };

#define O32_HOST_ORDER (o32_host_order.value)

void setup() 
{
  Serial.begin( 115200 );

  if ( O32_HOST_ORDER == O32_LITTLE_ENDIAN )
  {
    Serial.println( F( "Little Endian" ) );
  }
  else if ( O32_HOST_ORDER == O32_BIG_ENDIAN )
  {
    Serial.println( F( "Big Endian" ) );
  }
  else if ( O32_HOST_ORDER == O32_PDP_ENDIAN )
  {
    Serial.println( F( "PDP Endian" ) );
  }
  else
  {
    Serial.println( F( "Other Endian" ) );
  }
}

So that might not be it. It also fails with floats, not only ints. Weird thing that the CRC validates the packets, so has to be some bit-shifting issue, just can't figure out what...