🤖Have you ever tried Chat.M5Stack.com before asking??😎
OSZAR »
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    SizeOf Structure M5Stack Core2 vs NANO

    Arduino
    2
    2
    31
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      SirMichael
      last edited by

      I've been struggling with trying to pass a structure between an Arduino NANO and an M5Stack Core2 through Serial Comms.

      I can get the structure to pass correctly between two Arduino UNOs or NANOs, but when I try to get it to use on my project between a NANO and the M5Stack Core2, it fails. (Serial comms passes strings just fine!)

      I finally figured out that the sizeof the Structure is reported as 15 bytes on the NANO and 24 bytes on the M5Stack Core2.

      I changed my declarations from:
      byte to uint8_t
      int to uint32_t

      on the NANO and M5.

      I do also have a double in the structure:

      //Use the same struct for comms both ways!
      struct AmpStruct {
        uint8_t bMode;
        uint16_t iBand;
        double dVolts;
        uint16_t iAmpTemp;
        uint16_t iFanOutput;
        uint16_t iFwdPower;
        uint16_t iRefPower;
      };
      //Initialize the values to create the usable structure
      AmpStruct AmpData = {0, 0, 0, 0, 0, 0, 0};
      

      Can anyone tell me what the difference is? Is there a way to make the structure the same between the two? There has to be way to declare the variables so they take up the same number of bytes on the two platorms.

      I do have the comms working by passing strings, but I'd like to use the Structure within the communications.

      Sir Michael

      Y 1 Reply Last reply Reply Quote 1
      • Y
        yuyun2000 @SirMichael
        last edited by

        @SirMichael
        The issue you're encountering is due to differences in data alignment and padding between the Arduino NANO (AVR architecture) and the M5Stack Core2 (ESP32 architecture). Here's why the sizeof your structure differs and how to fix it:

        Why the Size Differs

        Data Alignment:

        The ESP32 (Core2) aligns data to 4-byte boundaries by default for performance reasons, while the AVR (NANO) does not.
        This causes the compiler to insert padding bytes between struct members to meet alignment requirements.

        Double Precision (double):

        On AVR, double is typically 4 bytes (same as float).
        On ESP32, double is 8 bytes (true IEEE 754 double precision).
        This alone explains part of the size difference.

        Padding:

        The ESP32 compiler may insert padding after uint16_t members to align the double to an 8-byte boundary.

        How to Fix It
        To ensure the struct has the same size and layout on both platforms, you can:

        Use #pragma pack:

        Force the compiler to use 1-byte alignment (no padding) for the struct:#pragma pack(push, 1) // Disable padding
        struct AmpStruct {
        uint8_t bMode;
        uint16_t iBand;
        float dVolts; // Use float instead of double for consistency
        uint16_t iAmpTemp;
        uint16_t iFanOutput;
        uint16_t iFwdPower;
        uint16_t iRefPower;
        };
        #pragma pack(pop) // Restore default alignment

        Note: Replace double with float to ensure consistency (4 bytes on both platforms).

        Manually Pad the Struct:

        If you must use double, manually add padding to match the ESP32 layout:struct AmpStruct {
        uint8_t bMode;
        uint8_t _pad1; // Manual padding
        uint16_t iBand;
        double dVolts;
        uint16_t iAmpTemp;
        uint16_t iFanOutput;
        uint16_t iFwdPower;
        uint16_t iRefPower;
        };

        Use Serialization:

        Instead of sending the raw struct, serialize it into a byte array with fixed sizes:uint8_t buffer[24]; // Adjust size as needed
        buffer[0] = AmpData.bMode;
        memcpy(&buffer[1], &AmpData.iBand, 2);
        memcpy(&buffer[3], &AmpData.dVolts, 8); // Or use float
        // ... repeat for other members
        Serial.write(buffer, sizeof(buffer));

        Key Takeaways

        Use float instead of double unless you need the extra precision.
        Force 1-byte alignment with #pragma pack to avoid padding.
        Test the struct size on both platforms after changes:Serial.print("Size of AmpStruct: ");
        Serial.println(sizeof(AmpStruct));

        https://chat.m5stack.com/

        1 Reply Last reply Reply Quote 1
        • First post
          Last post
          OSZAR »