Receiced serial data is wrong

Hello everyone,

I'm using the Arduino Uno and A D1mini. The arduino Uno is sending Data to the D1Mini (ESP8266) via serial communication every ~2secs.

The D1mini, successfully read datas but the output is wrong. It seems it's guetting 2 datas at once, instead of 1 by 1.

Baud Rate is 9600 on both side. I tried 57600 and 115200. Doesn't change

Code from Arduino side (called by another function every 2 secs)

//Initialize the communication between the 2Cards
void SerialComClass::InitCom()
{
    softSerial.begin(9600);
    softSerial.setTimeout(100);
    Serial.print("Test");
    softSerial.println("Hello, world?");
    pinMode(12,INPUT);
    pinMode(13,OUTPUT);
}

///Push/Transmit Data to the D1Mini
void SerialComClass::PushData(int moveState)
{
    if(moveState){
   softSerial.print("true");
    }
    else{
        softSerial.print("false");
    }

    Serial.println("Sending " + (String)moveState);
        
}

From the D1Mini

void GetNewData()

{

  while(softSerial.available()>0)

  {

    valStr=softSerial.readString();
  Serial.println("receive "+valStr);

  }

}

Serial Monitor :
1:50:53.091 -> receive falsetrue
11:50:56.921 -> receive falsetrue
11:51:00.768 -> receive false
11:51:04.925 -> receive truefalsetrue
11:51:09.129 -> receive falsetrue
11:51:13.195 -> receive falsetrue
11:51:17.542 -> receive falsetrue
11:51:21.347 -> receive falsetrue
11:51:25.224 -> receive falsetrue
11:51:29.154 -> receive falsetrue

Where I Expected
Receive False
Receive True

Because you are 100% depending on timing, instead of delimiter symbols like comma or end-of-line, to separate the data fields. That forces the receiving code to guess where a message begins and ends. Serial data is asynchronous. Consider using separators and reading with readStringUntil().

Hi, thanks for the help. I replaced by readStringUntil() but here is what I have

Serial Monitor[Arduino Side]:

12:27:26.753 -> Sending 0
12:27:28.852 -> Sending 1
12:27:30.863 -> Sending 0
12:27:32.862 -> Sending 1
12:27:34.869 -> Sending 0
12:27:36.881 -> Sending 1
12:27:38.889 -> Sending 0
12:27:40.897 -> Sending 1

Serial Monitor [D1 mini Side]
12:29:09.629 -> receive true
12:29:13.367 -> receive true
12:29:17.218 -> receive true
12:29:21.191 -> receive true
12:29:24.931 -> receive false
12:29:30.759 -> receive true
12:29:34.590 -> receive true
12:29:38.386 -> receive true

It's still not working as expected....It drives me crazy. It's been a day I'm looking everywhere. I read that it could be because of the speed

But I don't understand how to manage this problem.

Nor do we, since you didn't provide updated code. Don't edit the original post.

Also, you seem to have completely ignored my advice about how to fix it. Things are going to be very slow if you don't at least respond to advice.

The Uno is a 5V device so it is outputting 5V
The D1 Mini is a 3V3 device so expects 3V3 at its inputs

If you connect the 2 boards with no voltage level shifting between them then it may work, but beware of possible damage to the D1 Mini

Hi, I do have a voltage divider and hence a 3.3V. There is no issue from that side, I measured it to make sure before plugin the D1Mini.

I didn't ignored your advice (at least not willingly).
As said, the pushed data is managed by another script (servo motors script).

Here is the updated code:

Arduino
void FirebaseComClass::PushData(int moveState)

{

if(moveState){

softSerial.print("true-");

}

else{

    softSerial.print("false-");

}

Serial.println("Sending " + (String)moveState);

}
D1Mini

void GetNewData()

{

  while(softSerial.available()>0)

  {

    valStr=softSerial.readStringUntil('-');
  Serial.println("receive "+valStr);

  }

}

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

Oh? Where did you say that? Is it your "script"? (really should be "sketch") Why can't you change it?

Sorry I'm from the videogame industry, I might not use the proper terms.
Anyway, here is why I can't change it (or maybe I'm missing something) :

ServoControl.cpp => Calls the SerialCom
From a loop, The servo goes from 0 to 180 then from 180 to 0. Works as intended :+1:

//When called, move the servo from a position to another
void ServoControlClass::MoveServo(bool stop_i) 
{
  stop_o=stop_i;
  
  if(!stop_o)
  {
    if(currentPos==0)
    {
      delay(2000);
      moving_o=1;
      SerialComClass.PushData(ServoControl_cls.moving_o);
      servo1.write(180);
      servo2.write(180);
      currentPos=180;
      delay(2000);
      moving_o=0;
      SerialComClass.PushData(ServoControl_cls.moving_o);
    }
    if(currentPos==180)
    {
      delay(2000);
      moving_o=1;
      SerialComClass.PushData(ServoControl_cls.moving_o);
      servo1.write(0);
      servo2.write(0);
      currentPos=0;
      delay(2000);  
      moving_o=0;
      SerialComClass.PushData(ServoControl_cls.moving_o);
    }
  }
  else
  {
    servo1.write(0);
    servo2.write(0);
  }


}

SerialCom
Called by the servoClass. Send true or false. Works as intended :+1:

//Initialize the communication between the 2Cards
void SerialComClass::InitCom()
{
    softSerial.begin(9600);
    softSerial.setTimeout(100);
    Serial.print("Test");
    softSerial.println("Hello, world?");
    pinMode(12,INPUT);
    pinMode(13,OUTPUT);
}

///Push/Transmit Data to the D1Mini
void SerialComClass::PushData(int moveState)
{
    if(moveState){
   softSerial.print("true-");
    }
    else{
        softSerial.print("false-");
    }

    Serial.println("Sending " + (String)moveState);

    

        
}

Serial monitor from arduino

13:29:58.454 -> Sending 1
13:30:00.474 -> Sending 0
13:30:02.479 -> Sending 1
13:30:04.496 -> Sending 0
13:30:06.500 -> Sending 1
13:30:08.510 -> Sending 0
13:30:10.516 -> Sending 1

D1mini Side
GetNewData() is called by a loop
void ReadData() is called by a loop


void loop() {
  // put your main code here, to run repeatedly:
  //Get New InputData();
  GetNewData();

  //Send new data
  ReadData();
}

void GetNewData()
{
  while(softSerial.available()>0)
  {
    valStr=softSerial.readStringUntil('-');
    newData=true;
  }

}

//Read datas 
void ReadData()
{
    Serial.println("receive "+valStr);

    if(valInt==0)
    {
      valBool=false;
    }
    if(valInt==1)
    {
      valBool=true;
    }

   newData=false;
}

Serial Monitor from D1Mini

13:31:05.446 -> receive false
13:31:09.613 -> receive false
13:31:13.320 -> receive false
13:31:17.009 -> receive false
13:31:20.769 -> receive false
13:31:24.404 -> receive true
13:31:28.183 -> receive true
13:31:31.943 -> receive true

That we can't see...

I manage to solve the problem. The readStringUntil finallt did the job! Thank you.
I used the newData bool (Can't find where I read it, but it works )

D1 Mini

void loop() {
  // put your main code here, to run repeatedly:
  
  //Get New InputData();
  GetNewData();

  //Send new data
  ReadData();
}

void GetNewData()
{
  while(softSerial.available()>0)
  {
    valStr=softSerial.readStringUntil('-');
    newData=true;
  }

}


void ReadData()
{

    if(newData)
    {
          Serial.println("receive "+valStr);
  
         newData=false;
    }
}
1 Like