Corrupted communications between atmega2560 and ESP8266

Hello there,

I'm using this board - WiFi R3(atmega2560 + esp8266)
...and I trying to send messages to Serial(to ESP8266) with 115200 baud rate, and I get exactly corupted message, for example -
Bad: seupDate
Good: setupDate
...Or
Bad:

*ing aslast 
*WM: Connection resul: 
*WM: 3
*WM: IP Address:
*WM: 192.168.1.100

Good:

*WM: 
*WM: AutoConnect
*WM: Connecting as wifi client...
*WM: Status:
*WM: 0
*WM: Using last saved values, should be faster
*WM: Connection result: 
*WM: 3
*WM: IP Address:
*WM: 192.168.1.100

Also I know the problem is getting the message because when I see the ESP8266 serial monitor I get a good message.

Some context:

  • I trying to send about 150 messages less than 1 second. For example here one message: {"pixel":150,"rgb":"0, 0, 0"}
  • I'm getting messages on atmega2560(send from ESP8266) by Serial3 port
  • Baud rate is exactly the same
  • I use this method for read messages:
void doReadSerial() {
  static char *message = new char[MAX_MESSAGE_LENGTH];
  static unsigned int message_pos = 0;
  char inByte = Serial3.read();

  if (inByte != ';' && (message_pos < MAX_MESSAGE_LENGTH - 1)) {
    message[message_pos] = inByte;
    message_pos++;
  } else {
    message[message_pos] = '\0';
    strcpy(buffer, message);
    Serial.println(message);
    __processMessage();
    message_pos = 0;
    delete[] message;
  }
}
  • I run doReadSerial() in the loop()
  • The message is corrupted exactly on Serial3, and the code translates it to Serial
  • The code in loop() does not affect the reading of Serial3. Since after removing all the rest of the code from loop(), the messages remained corrupted
  • Here's my loop():
void loop() {
  while (Serial3.available() > 0) { doReadSerial(); }
  changeModeButton.read();
  turnOffButton.read();
  if (__FLAG__doModes) { modes[modeSelected](); }
}

Thanks :slight_smile:

How about you try like this

void doReadSerial() {
  static char message[MAX_MESSAGE_LENGTH] = {'\0'};
  static unsigned int message_pos = 0;
  char inByte = Serial3.read();

  if (inByte != ';' && (message_pos < MAX_MESSAGE_LENGTH - 1)) {
    message[message_pos] = inByte;
    message_pos++;
  } else {
    message[message_pos] = '\0';
    strcpy(buffer, message);
    Serial.println(message);
    __processMessage();
    message_pos = 0;
  }
}

I'm sorry but it didn't help

Maybe it's hardware related, the dip-switches are always suspect. Try switching them back and forth a few times, they may be just a little corroded. Your sketch looks fine to me.

Just to confirm, your loop() looks like this ?

void loop() {
  while (Serial3.available() > 0) { doReadSerial(); }
}

btw it looks like you are used to using Java or Python or something.
I would write this like this

void loop() {
  while (Serial3.available() > 0) { 
    doReadSerial(); 
  }
}

or like this

void loop() {
  while (Serial3.available()) doReadSerial();
}

It's cosmetics of course, but i always put a closing curly brace on a line by itself, and never anything on a line after an opening curly brace.

btw the link you posted shows different kinds of boards, but i figured you have one of these

I agree with Deva Rishi, adding: Ensure grounding of both transceivers (shared is better).

I'm sorry, I've been away for a long time.
@Deva_Rishi, yes, I have the board you mentioned.
I changed the DIP switches several times (4, to be exact) and it did not help.
Even when my code looks like this, the message is still corrupted:

void loop() {
  while (Serial3.available()) doReadSerial();
}

Aren't the settings listed on the board?

You misunderstood me, I probably set the switches correctly (ON 1 2 3 and 4), I switched each of them four more times

I don't believe that I misunderstood you.
How do you know that is the correct setting?

Here is the DIP switch table for my board. I use the "CH340 connect to Mega2560 COM3 connect to ESP8266".

Some fact: If I set baud rate to 1200, the message will not be corrupted.
But it will be too slow (I need a speed of 115200 baud and above)

This example uses a higher baud rate:
Arduino - Web Server (Mega 2560 R3 built-in ESP8266) (gabrielcsapo.com)

On my board, all switches are set in the same way as in the example. But there is one caveat, I do not use AT firmware

Is there any code in your sketch which relies on interrupts ?

Shouldn't be an issue if you are using hwSerial. I think you can max out the UART of the Mega at 1Mbps (the ESP can do even more )

That shouldn't matter at all. I think you may be overflowing the RX-buffer of the Mega.
The ESP can send so much data that the Mega might not be able to process it all.
For testing purposes, send at a High Baud rate (250Kbps) but never send a message longer than 64 bytes, and wait 1 second in between messages.

Other possibility is of course that the level shifter on the board is just too slow, but that would usually result in 'broken bytes' not missing bytes.
If the Mega is caught up in an interrupt, the RX interrupt will not call the function transferring the data from the FIFO to the buffer.
Or if the read() function isn't called before the RX-buffer is full, any bytes received will be discarded.

To confirm the hardware is working properly, Upload a simple Serial-Passthrough sketch. You know you haven't shared the full sketch, which may include objects that do use interrupts, so we can't be sure.

That is what i mean, there may be processes going on that do not need to be called from loop()

Yes, I use EasyButton

Baud Rate: 115200
...and this message is intact :partying_face:, but why does sending require this delay?

Maybe I do not have time to write characters to the buffer?

Then i suggest you use a different method of debouncing. But you know that because of your lack of information (the complete sketch !) we had several different suggestions.

That means that the RX-buffer overflows. The bytes are transferred to the RX-buffer just fine, but you do not read from it in time, probably because Easy button is holding the processor up for too long.
You can increase the size of the RX-buffer i think without to much issue, simply by re-defining it's size, but that does increase the size for all used Serial objects i think (just looking at hardwareSerial.h & .cpp atm.
so

#define SERIAL_RX_BUFFER_SIZE 128 // 256 would be the max or the type of the index needs to be 16 bit.

will probably fix it already. You have the memory available, but it is a tad wasteful.

You have time, but you need to read the buffer before it is full.

Thank you! You helped me. And one more question, is it possible to clear the buffer or make it larger than 256?

Sorry but after a few tests I noticed that the corruption is still there even if #define SERIAL_RX_BUFFER_SIZE 1024.

But the messages got less corrupted