Bidirectional Serial Communication problem with Robotdyn Mega Wifi

Hi all, I am trying to send messages back and forth using seemingly a clone of Robotdyn Mega WIFI. Arduino Mega and NodeMCU ESP8266 are on the same board. So, I tried to send data from mega to esp8266 using serial 3 port (of mega). I have followed a sample project I've found in the internet, but it doesn't work. Here are the codes:

/*
  code for Mega
*/

int i = 0;
float load[]  = {40.9, 37.9, 29.3, 39.1, 34.9, 36.5, 37.2, 34.5, 27.2, 22.2, 31.3};
String msgsent = "";

void setup() {
  Serial.begin(9600);
  Serial3.begin(115200 );
  Serial.println("start");
}

void loop() {
  
  if (i < 11) {
    msgsent = "Load: " + String(load[i]);
    
    Serial3.println(msgsent);         // debugging purpose
    Serial.print("from mega ->");
    Serial.println(msgsent);
    delay(100);
    
    if (Serial3.available()) {
      Serial.print("<");              // debugging purpose
      String msg="";
      while (Serial3.available()) {
        msg += char(Serial3.read());
        delay(50);
      }
      Serial.println(msg);
    }
    i++;
  }  
}

And for the ESP8266:

/*
 esp8266 code
*/

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

void loop() {
  if (Serial.available()) {
    String msg="";
    while (Serial.available()) {
      msg += char(Serial.read());
      delay(50);
    }
    // send back 
    Serial.print(msg);
  }
}

It seems that I could send the data to ESP8266, but I didn't get any reply from it. Any one can give me a solution for this? Thank you very much.

Try...

 void loop()
{
  if (Serial.available() > 0)
    Serial.write(Serial.read());
}

Horrors! This is timing based reception, susceptible to all manner of strange bugs.

It works!
Would you please explain why?

However when I changed it a little bit to make sure it really communicate bidirectionally:

void loop() {
  if (Serial.available() > 0)
    Serial.write("from esp8266"+Serial.read());

It didn't work.

Yes, I am aware of that. Do you have any better suggestions?
I just realize that in the sample programs I have, all of them are using one direction only. Even the solution from red_car didn't work again after change a little bit into this:

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

void loop() {
  if (Serial.available() > 0)
    Serial.write("from esp8266"+Serial.read());
}

this code didn't work. So what is the best way of doing this bidirectional communication using UART?

It didn't work because you violated the rules for the types of parameters that you can pass to 'write()'. Please read the documentation on Serial in the Reference section on this site.

void loop()
{
 // if any character is received
  if (Serial.available() > 0)
  // then read one character and write back the same character
    Serial.write(Serial.read());
}

Hope that helps...

I wrote another code, this time I tried to find out whether full duplex communication can be made using this board. I started writing in one direction first, from ESP to Mega, and then I found out, just like you said, timing is very crucial.

/*
this is esp8266 part
*/

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>


char* ssid = "--";
char* password = "--";

bool lsendIP    = true;
bool lsendData  = true;
float load[]    = {40.9, 37.9, 29.3, 39.1, 34.9, 136.5, 37.2, 34.5, 27.2, 22.2, 3331.3};
int i = 0;

void setup() {
  // connecting to wifi network!
  WiFi.begin(ssid,password);
  while(WiFi.status()!=WL_CONNECTED)
  {
    delay(500);
  }
  
  // prepare serial communication
    Serial.begin(115200);  
}

void loop() {
  // send IP Address first!
  DynamicJsonDocument doc(256); 
  if (lsendIP) {
    lsendIP = false;
    doc["type"] = "501";
    doc["ip-address"] = WiFi.localIP().toString();
    serializeJson(doc,Serial);
    Serial.flush();
    delay(200);
  }
  
  if (lsendData) {
    if (i > 10) {
      lsendData = false;
    }
    
    // send data continuosly
    doc["type"] = "503";
    doc["seq"]  = i;
    doc["load"] = load[i];
    serializeJson(doc,Serial);
    i++;
    Serial.flush();
    delay(200);
  }
}

I have to add delay(200) and flush() to make sure the data goes thru the serial port and then read by mega.

/*
 this is arduino mega part..
*/
//#include <SPI.h>
#include <ArduinoJson.h>

int i = 0;


String msgO = "";
float xdata = [];

void setup() {
  Serial.begin(9600);
  Serial3.begin(115200 );
  Serial.println("start");
}

void loop() {
  if (Serial3.available() > 0) {
    // there is data in the buffer?
    String msgI;
    const char* ipdr;
    delay(100);
    Serial.print("getting response ->");
    Serial.println(Serial3.available());
    while(Serial3.available() > 0) {
      msgI += Serial3.readString();
    }
    Serial.println(msgI);
    
    // parsing JSON format
    DynamicJsonDocument doc(256);
    DeserializationError error = deserializeJson(doc,msgI);
    int xseq;
    float xdat;
    if(!error) {
      if (doc["type"]=="501") {
        ipdr = doc["ip-address"];
        Serial.print("IP Address: ");
        Serial.println(ipdr);
      } else if(doc["type"]=="503") {
        xseq = doc["seq"];
        xdat = doc["load"];
        Serial.print("Seq #: ");
        Serial.print(xseq);
        Serial.print(", data: ");
        Serial.println(xdat);
      }
    }
  } 
}

As you said, the timing-based reception is not good, but I can't find another way of doing this. Later I try to implement a 'turn-based' communication between those 2 components (to form a simple hand-shaking mechanism). Any thought?

I think you did not understand. What I am saying is, timing must not be crucial. Successful and robust serial communication is event based, not interval based. Nowhere should you have any code that cares whether a character is available or unavailable at any arbitrary time.

I do understand what you are trying to say about robust serial communication. And that's true. I am not an expert in Arduino, I am just a beginner. I just need some articles or sample codes to give me a clear direction to go. All videos I saw on youtube basically use the same technique, I just copied from them. Perhaps a link or two will certainly help a lot. Thanks in advance.

The reference link list in the introductory help threads in the forum, have links to those.

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