How to send and receive struct data packet over serial

Can someone give me example code for both transmitter and receiver for Arduino board to board UART communication? I tried different different methods but I couldn't find a solution.

Make sure that the baud rate is correct and that you've connected the two Arduinos correctly (TX to RX and RX to TX, using the Serial1 pins).

Hardware side is correct. Also I can send array via UART. But the only part that doesn't work is sending struct via UART.

there was some code in the thread, read above..

1 Like

Can you specify in what form (an array of integers or something else) do you store data about 32 relay states in the transmitter?
In what type of data do you need them in the receiver in the end (before sending to the pins)?

struct Packet
{
    int arr[];
   int sizeArr;

}

this is the data struct I want to transmit and receive

I doubt that the library supports flexible array members. And shouldn't the flexible member be at the end?

It could work fine. Might just be transferring an array of size 0.

Of course, the size of the data must be the first member.

What is the source of the data that you want to transmit ?

It's hard to understand you. Obviously, you don't really want help. No one should write code for you.
Do you need to pass data or do you need a structure?
Before sending, you can transform your structure into any convenient form, transfer, receive, and then return it back to your structure.
Actually, the data about the state of 32 relays can be packed into one integer number, transfer only one number, and then return it back to the array. Simple and fast.

the code i've posted compiles and works (i.e. tested). i don't believe it is bad practice.

i can't say i disagree with you, because i don't understand the point you're trying to make.

He's saying: it may work today, but:

  • It may not work when the next version of the compiler comes out.

  • It may not work if you make a seemingly minor and unrelated change in the code.

  • It may not work if you change the compiler's optimization parameters.

Why? Because the language standard does not say that it must work. Therefore, the object code that the compiler creates with your invalid source code is not required to work to your expectations or, in fact, do anything at all.

Why do you find that so difficult to understand?

you're describing what undefined behavior means. i'm not advocating ignoring it.

i'm describing a very specific case with very restricted use of the pointer value i don't believe casting is undefined, but how the use of the re-casted pointer value is undefined. of course it is. the compiler doesn't know how the code will use it. but it can be used properly.

based on my experience, recasting pointers in this way is fairly conventional.

btw: has anyone provided an alternative version of the code i presented reply #7? it doesn't matter that the code is incomplete, it demonstrates the use of casting to match the processing function interfaces.

It allows you to utilize the same fixed memory locations for different purposes. Memory utilization was more important in the days of 4k * 12 bit total RAM.

I'm transmitting relay ids (Pin numbers connected to Arduino mega). The relays are switching according to the relay array IDs)

It is very difficult to get information from you.
In the first post, you wrote that you need to transfer data between two ESP32s to control 32 relays. I may be wrong, but it seems to me that the ESP32 does not have 32 pins for output.
Now you write that you need to transfer the pin numbers for the Arduino Mega.

  • How many numbers do you need to transfer? Is it always 32 or could it be a different number? Are these numbers in the range 0 to 31, or could there be a different range?
  • Are these numbers in order, or can be an arbitrary order?
  • Do you always need to transmit all 32 numbers, or is it enough to transmit one pin number that needs to be changed at a given time?

This means that you must create a protocol for transferring data. It should be simple and trasmit the minimum required information.
It's strange why you don't want to use the approach from Example 5 of Serial Input Basics - updated?

despite the discussion of more advanced data formats ...

why don't you just send a string with pairs of #s indicating relay-id and state that can be separated using strtok().
"relays 1:0, 2:1, 3:1, ..."

along the lines of what you originally suggested, you could send a binary packet. the code below produced the following output

dump:
   03 01 00 02 01 03 01 00
   00 00 00 00 00 00 00 00
   00 00 00 00 00
#include    <stdio.h>

typedef unsigned char   byte;

#define MAX_RELAY   10

struct Pkt_s {
    byte     size;
    struct RelayIdState {
        byte    id;
        byte    state;
    } idState [MAX_RELAY];
};

void dump (
    byte   *buf,
    int     nByte )
{
    printf ("%s:", __func__);

    for (unsigned n = 0; n < nByte; n++)  {
        if (! (n % 8))
            printf ("\n  ");
        printf (" %02x", buf [n]);
    }
    printf ("\n");
}

int
main ()
{
    Pkt_s  pkt = {};

    pkt.idState [0].id    = 1;
    pkt.idState [0].state = 0;

    pkt.idState [1].id    = 2;
    pkt.idState [1].state = 1;

    pkt.idState [2].id    = 3;
    pkt.idState [2].state = 1;

    pkt.size              = 3;

    dump ((byte*) &pkt, sizeof(pkt));
    return 0;
}
1 Like

Thank you for your replies. The problem was solved by using serial stream char buffer.