Serial send and receive data

Hi, for a project i need to communicate an arduino due with an arduino nano every. The final purpose is for the Due to send instructions to the nano (to control the position of a motor), and for the nano to send back data about the position of the encoder of the motor.

I was thinking of using serial communication however i am struggling to make the code work.

Connection :
Ground due => ground nano every
TX Serial3 due => logic converter => RX Serial nano
RX Serial 3 due => logic converter => TX Serial Nano
The two boards are connected by two usb wire to the same PC.

I partially created the code and I encounter problems already :

code DUE (taken from a tutorial on the forum except for comE) :

const byte numChars = 32;
char receivedChars[numChars];   

boolean newData = false;
int long t=0;
double N = 0;             

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
    Serial3.begin(9600);
    t=millis();
}

void loop() {
    recvWithEndMarker();
    showNewNumber();
    if (millis()-t>100){
       comE(10.4);
       t=millis();
  }
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    if (Serial3.available() > 0) {
        rc = Serial3.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; 
            ndx = 0;
            newData = true;
        }
    }
}

void comE(double n){
  Serial3.println(String(n));
}

void showNewNumber() {
    if (newData == true) {
        N= 0;       
        N = atof(receivedChars);   
        Serial.print("Recu   ");  
        Serial.println(N);     
        newData = false;
    }
}

Code Nano Every :


int long t=0;

void setup() {
  // put your setup code here, to run once:
  Serial1.begin(9600);
  Serial.begin(9600);
  t=millis();
}

void comE(double cons){
  Serial1.println(String(cons));
}

void loop() {
  if (millis()-t>100){
    comE(2.3);
    t=millis();
  }
}

What I receive :

Recu 10.40
Recu 2.30
Recu 10.40
Recu 2.30
Recu 10.40
Recu 2.30
Recu 10.40

What i would like to receive :

Recu 2.30
Recu 2.30
Recu 2.30

I don't understand why i get 10.4 when i'm only printing it to Serial3 (if i delete comE() function it worked well)

Thank in advance for your help

Is a double variable the same size on both systems ?

Apparently no, 8 byte for due and 4 byte for nano every. Does this create a problem ? i changed the numChars variable to 64 but it doesn't change anything.

I believe so. When you send a double from the Due it sends 8 bytes whilst the Nano is expecting only 4 bytes

Why are you sending a floating point value anyway ?

As an experiment, try sending and receiving an integer value declared as uint16_t to limit it to 2 bytes

So I tried several things, I changed all my variable to integer to simplify.
Then i change comE on the DUE to :

void comE(uint16_t n){
  Serial3.println(String(uint16_t(n)));
}

and send comeE(uint16_t(8));

On the nano i tried to change to

void comE(uint16_t cons){
  Serial1.println(String(uint16_t (cons)));
}

and send comE(uint16_t(2));

I also tried to send on unint16_t to the nano and send on unint32_t to the due.
I changed numChars to 16 and 32 alternativly

However I always obtain :

Recu 2
Recu 8
Recu 2
Recu 8
Recu 2

You have made multiple changes to both sketches so please post both of them again in a new post

Yes sorry it was not clear :

first experiment i tried to move everything to uint16 on due sketch and uint32 on nano (as it seems it's 2 byte for nano and 32 for due) :
Due :

const byte numChars = 16;
char receivedChars[numChars];   

boolean newData = false;
int long t=0;
uint16_t N = 0;             

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
    Serial3.begin(9600);
    t=millis();
}

void loop() {
    recvWithEndMarker();
    showNewNumber();
    if (millis()-t>100){
       comE(uint16_t(8));
       t=millis();
  }
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    if (Serial3.available() > 0) {
        rc = Serial3.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; 
            ndx = 0;
            newData = true;
        }
    }
}

void comE(uint16_t n){
  Serial3.println(String(uint16_t(n)));
}

void showNewNumber() {
    if (newData == true) {
        N= 0;       
        N = atoi(receivedChars);   
        Serial.print("Recu   ");  
        Serial.println(N);     
        newData = false;
    }
}

Nano:

int long t=0;

void setup() {
  // put your setup code here, to run once:
  Serial1.begin(9600);
  Serial.begin(9600);
  t=millis();
}

void comE(uint32_t cons){
  Serial1.println(String(uint32_t (cons)));
}

void loop() {
  if (millis()-t>100){
    comE(2);
    t=millis();
  }
}

I received :

Recu 2
Recu 8
Recu 2
Recu 8

Second experiment, everyting on uint16 :
Due :

const byte numChars = 16;
char receivedChars[numChars];   

boolean newData = false;
int long t=0;
uint16_t N = 0;             

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
    Serial3.begin(9600);
    t=millis();
}

void loop() {
    recvWithEndMarker();
    showNewNumber();
    if (millis()-t>100){
       comE(uint16_t(8));
       t=millis();
  }
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    if (Serial3.available() > 0) {
        rc = Serial3.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; 
            ndx = 0;
            newData = true;
        }
    }
}

void comE(uint16_t n){
  Serial3.println(String(uint16_t(n)));
}

void showNewNumber() {
    if (newData == true) {
        N= 0;       
        N = atoi(receivedChars);   
        Serial.print("Recu   ");  
        Serial.println(N);     
        newData = false;
    }
}

Nano :

int long t=0;

void setup() {
  Serial1.begin(9600);
  Serial.begin(9600);
  t=millis();
}

void comE(uint16_t cons){
  Serial1.println(String(uint16_t (cons)));
}

void loop() {
  if (millis()-t>100){
    comE(uint16_t(2));
    t=millis();
  }
}

here also I receive :

Recu 2
Recu 8
Recu 2
Recu 8

also tried most basic just int and 32 on numChar :

Due :

const byte numChars = 16;
char receivedChars[numChars];   

boolean newData = false;
int long t=0;
int N = 0;             

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
    Serial3.begin(9600);
    t=millis();
}

void loop() {
    recvWithEndMarker();
    showNewNumber();
    if (millis()-t>100){
       comE(8);
       t=millis();
  }
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    if (Serial3.available() > 0) {
        rc = Serial3.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; 
            ndx = 0;
            newData = true;
        }
    }
}

void comE(int n){
  Serial3.println(String(n));
}

void showNewNumber() {
    if (newData == true) {
        N= 0;       
        N = atoi(receivedChars);   
        Serial.print("Recu   ");  
        Serial.println(N);     
        newData = false;
    }
}

Nano :


int long t=0;

void setup() {
  // put your setup code here, to run once:
  Serial1.begin(9600);
  Serial.begin(9600);
  t=millis();
}

void comE(int cons){
  Serial1.println(String(cons));
}

void loop() {
  if (millis()-t>100){
    comE(2);
    t=millis();
  }
}

I get the same result

I tried with an arduino Uno instead of the Due and the sketch work correctly only 2 is print.

That would seem to prove that the problem is due to the size of the variables being used

The whole way you are receiving the data is full of problems. As written, it is unlikely to work reliably. You attempt to receive using an end marker, but also print based on time. ALL you need is the end marker. You set a flag that says you got the end marker, but then don't seem to use it. You also make no accommodation for multiple characters arriving between calls to the receive function. Keep calling the receive function UNTIL the flag is set, then print the result, and flush the received string to start over. Get rid of the timing part of the receive code entirely. Also, you are not checking for a buffer over-run, which WILL bite you in the a$$ at some point.

Also, if you send the numeric data as ASCII strings, then you don't need to care if the sizes of ints and floats are different on different processors, nor do you need to care if one is big-endian and the other is little endian. And, ASCII makes it far to debug, since you can easily SEE the received data.

I have decided to replace the nano by an other due as i can't replace the first due. It work fine and their is no weird value. The problem clearly come from the different format of precessors, I don't precisly know why.

The whole way you are receiving the data is full of problems.

Yes I will ameliorate this now, but the problem of having on my serial '5' don't seem to come from this as I had already tried other functions to retrieve data which gave me the same result.

Anyway thanks you both for your time, have a great day.

You can also encapsulate all that with the SerialTransfer library

Dont double post please

He is sending data in ascii… so no

Do you have the console opened on the nano ?

Sorry for the double post that'll teach me to not read the rules diagonally.
I only opened the due console, but I always had the the two boards powered by the same pc on which I programmed.

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