Slow serial communication between esp and arduino

I am sending information between my nodemcu esp8266 and my arduino mega.
The two are connected from pin D5 (ESP)---->RX2(MEGA). tx--->rx because i am only sending the arduino. But the information is sent too slowly with delays on each line. Here is the mega code:

  Serial2.begin(9600);
if(Serial2.available() > 0){
    character = Serial2.read();
    if(character == '#'){
      Serial.println(message);
      if(message.startsWith("ho")){
        message.remove(0,2);
        hours = message.toInt();;
      }else if(message.startsWith("m")){
        message.remove(0,1);
        minutes = message.toInt();;
      }else if(message.startsWith("s")){
        message.remove(0,1);
        seconds = message.toInt();
      }else if(message.startsWith("t")){
        message.remove(0,1);
        outTemp = message.toFloat();
      }else if(message.startsWith("hu")){
        message.remove(0,2);
        outHum = message.toFloat();
      }
      message = "";
      Serial.println();
    }else{
      message.concat(character);
    }
  }

and the code from the esp:

SoftwareSerial s(D6,D5); //RX,TX
void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  s.begin(9600);
void loop() {
  ArduinoCloud.update();
  // Your code here 
  if(temperature != 0){
  s.print("ho"+time_hours+"#");
  s.print("m"+time_minutes+"#");
  s.print("s"+time_seconds+"#");
  s.print("t"+String(temperature)+"#");
  s.print("hu"+String(humidity)+"#");
  
  Serial.println("ho"+time_hours+"#");
  Serial.println("m"+time_minutes+"#");
  Serial.println("s"+time_seconds+"#");
  Serial.println("t"+String(temperature)+"#");
  Serial.println("hu"+String(humidity)+"#");
  delay(500);
  }
}

I know i have delay(500) but that doesnt explain that each lineof infortmtion is beingsend every like 6 seconds.
for exmaple the mega gets:

ho19
six seconds later
m30
six seconds later
s50
.....

Please state clearly, what information, messages, and data items your are sending from ESP8266 to MEGA using UART Port. Also mention the type number of your temp-humidity sensor.

OK, the sensors are not connected to the esp8266. They are connected to another arduino that is outside. Its information is being synced with the arduino or cloud. The data has different kinds of information. I have 5 pieces of information I send: hours(1-24), minutes(1-60),seconds(1-60),temp(mostly 10-40), humidity(20-90). I only send strings

For each data, I start with a letter to identify it: hours is ho, minutes is m, temp is t etc

Then you can send your five pieces of data items in the following comma separated format:
s.print("23, 53, 47, 25, 57"); //hrs, min, sec, temp, humidity

At the receiver, you use strtoul() to retrieve the individual data items.

Test Programs:

ESP8266 Sketch:

#include <SoftwareSerial.h>
SoftwareSerial s(D6, D5); //SRX, STX

void setup() 
{
  Serial.begin(115200);
  s.begin(9600);
}

void loop() 
{
  s.print("23, 53, 47, 25, 57");//null is not sent
  s.println();
  delay(1000);  //test interval
}

UNO Sketch

#include <SoftwareSerial.h>
SoftwareSerial s(2, 3); //SRX, STX
char myData[20];
char *ptr;

void setup()
{
  Serial.begin(115200);
  s.begin(9600);
}

void loop()
{
  byte n = s.available();
  if (n != 0)
  {
    byte m = s.readBytesUntil('n', myData, 20);
    myData[m] = '\0';
    //Serial.println(myData);
    //------------------------------------
    byte hrs = strtoul(myData, &ptr, 10);
    Serial.print("Hrs: "); Serial.print(hrs);

    byte min = strtoul(ptr+1, &ptr, 10);
    Serial.print("  Min: "); Serial.print(min);

    byte sec = strtoul(ptr+1, &ptr, 10);
    Serial.print("  Sec: "); Serial.println(sec);
  }
}

Receiver Monitor:

Hrs: 23  Min: 53  Sec: 47
Hrs: 23  Min: 53  Sec: 47

Didnt think about it i will try and let you know. Thanks

Working Principle of strtoul() Function:

The function parses (reads a character from a character type array and checks if it is a decimal or hexadecimal digit) a string (array of characters) and stops at the non-digit character. The ASCII codes of the digits which have been parsed so far are converted into a numerical number and are saved in a variable. For example:

char myArray[] = β€œ1234, 56, 78”;
char *temPtr;
unsigned int x1 = strtoul(myArray, &temPtr, 10); // x1 = 0x04D2
Serial.println(x1, DEC); //shows: 1234

The arg3 (= 10) says that the function looks for decimal digits in the array. The parsing stops at the first comma (,); there remains the sub-array/sub-string (, 56, 78) which will be parsed next time to extract 56. Now, we need a pointer variable (*temPtr) to point the beginning of the sub-array. The arg2 (= &temPtr) passes to the pointer variable the address of the character at which parsing had stopped and thus offers a way to the strtoul() function to locate the beginning of the sub-array.

(1) Enter 1234, 56, 78 into the InputBox of SM and then select β€œNewline” and then click on the Send button. As a result the following ASCII codes will be travelling towards UNO: 31 32 33 34 2C 20 35 36 2C 20 37 38 0A.

(2) Codes for UNO to receive the above frames and then extract the decimal numbers using strtoul (string to unsigned long) function and then save them into variables x1, x2, and x3.

Char myArray[20]; //array to hold arrived characters
Char *temPtr; //pointer to hold the beginning address of the remaining sub-string

void setup()
{
     //insert codes as needed
}

void loop()
{
   while(Serial.available() > 0) //check that the buffer holds at least one character
   {
       byte m = Serial.readBytesUntil(β€˜\n’, myArray, 20); //save characters except NL
       myArray[m] = β€˜\0’; //null byte
       Serial.println(myArray); //shows: 1234, 56, 78
       //-----------------------------------------------
       unsigned int x1 = strtoul(myArray, &temPtr, 10);
       Serial.println(x1, DEC); //shows: 1234
       Serial.println(x1, HEX); //shows: x1 = 0x02D4

       //Next parsing will begin by skipping the comma. T
       unsigned byte x2 = strtoul(temPtr+1, &temPtr, 10); //x2 = 0x38 = 56
       Serial.println(x2, DEC); //shows: 56
       unsigned byte x3 = strtoul(temPtr, &temPtr, 10); //x3 = 0x4E = 78
       Serial.println(x3, DEC); //shows: 78
    }
}

Thank you it works great but sometimes the data saved to the wrong place:

Hrs: 0  Min: 0  Sec: 0
temp: 48  hum: 18

Hrs: 21  Min: 48  Sec: 18
temp: 25  hum: 41


if (Serial2.available() != 0)
  {
    byte m = Serial2.readBytesUntil('n', myData, 20);
    myData[m] = '\0';
    //Serial.println(myData);
    //------------------------------------
    byte hrs = strtoul(myData, &ptr, 10);
    Serial.print("Hrs: "); Serial.print(hrs);

    byte min = strtoul(ptr+1, &ptr, 10);
    Serial.print("  Min: "); Serial.print(min);

    byte sec = strtoul(ptr+1, &ptr, 10);
    Serial.print("  Sec: "); Serial.println(sec);

    byte temp = strtoul(ptr+1, &ptr, 10);
    Serial.print("temp: "); Serial.print(temp);

    byte hum = strtoul(ptr+1, &ptr, 10);
    Serial.print("  hum: "); Serial.println(hum);
  }

esp code:

s.print(time_hours+","+time_minutes+","+time_seconds+","+String(temperature)+","+String(humidity));
 s.println();
delay(1000);

the array when there is a problem ,,54,25.40,76.20

Also what do i do when i get floats. like the temperature is a float so

22, 04, 14, 25.32, 75.50

Hrs: 22  Min: 4  Sec: 14
temp: 25  hum: 32

as you see the hum is 32 instead of 72 because it was 25.32 in the temperature

Send it as a scaled integer, not a float. Multiply by 100, then send and divide by 100.

1 Like

Ok thanks

Why not using Json coding/decoding? Then you have to send 1 object and decode one object.

Ok so it works most of the time but sometimes it or doesn't sends all of the information or the information get messed up. like the hours is 75.56 and the temp is 01. I think it's because the esp doesn't get the right info. I will try to find solution tomorrow, if any of you got an idea it will help.
Thanks

How do you do that? do you have any example

UDP is not a reliable protocol by itself. It has no (or only hardware based) error checking, and no flow control, handshaking or session control.

You are getting what you paid for.

You have any idea how can i still use it because i dont want my clock to show 7650:2540:00

You could put a packet wrapper around the data, with error correction. Like TCP-IP. Or you could just use TCP-IP.

The data is being sent with the arduino iot cloud

Oh, sorry, actually I got two threads mixed up... NM.

Are you 100% sure that the sender is sending the right data? E.g. did you serial print it separately at the sending end, to compare with the received data?

I am checking right now i havent seen anything strange yet the only thing that sometimes it will just pause and not send or print nothing for like 10 seconds