Atmega 2560 <-> ESP8266 communication

Hi,

I am using Atmega 2560 with embedded ESP8266 board. I have a webserver protocol within the ESP8266 module which will send data packet to Atmega 2560 using Serial port. (works fine)

However, my challenge is sending data packets from Atmega 2560 to ESP8266 so that it can update the webpage with sensor values. Kindly share me your feedback if you were able to perform this activity.

mock code at Atmega 2560

byte temp[] ={5,15,25};
byte temp2[] ={};

HardwareSerial *ESPComm = (HardwareSerial *)&Serial3;

void setup() {
  //transfer packet to ESP
  Serial.begin(115200);
  // recieve packets from ESP
  ESPComm->begin(115200);    
  
}

void loop() {

     ESPComm->write( '0' );
      //transfer packets from ESP to MCU
    if ( Serial3.available() )   {  Serial.write( Serial3.read() );  }
 
  //  listen for user input and send it to the ESP8266
    if ( Serial.available() )       {  Serial3.write( Serial.read() );  }
}

// To verify the event from ESP
void serialEvent3() {
  int i =0;
  while (Serial3.available()) {
    temp2[i] = Serial3.read();
    Serial.write(temp2[i]);
    i++;
  }

}

//void serialEvent() {
//while(Serial.available()) {
//    Serial3.write( Serial.read());
//  }
//}


mock code at ESP8266


byte temp[] ={10,20,30};

void setup() {
  // transfer packet
  Serial.begin(115200);
  // recieved packet
  Serial1.begin(115200,SERIAL_8E1);
  


}

void loop() {

   Serial.println(temp[0]);
   Serial.println(temp[1]);
   Serial.println(temp[2]);


    //if ( Serial1.available() )   {  Serial.write( Serial1.read() );  }

   delay(2000);

}

void serialEvent() {
while(Serial1.available()) {
    Serial.write( Serial1.read());
  }
}

O/P
it only prints 10,20,30

Expected O/P
10,20,30 and '0'

Try the following sketch (yours one slightly modified):

byte temp[] ={10,20,30};
volatile char y;
volatile bool flag = false;

void setup() {
  // transfer packet
  Serial.begin(115200);
  // recieved packet
  Serial1.begin(115200,SERIAL_8E1);
  


}

void loop() 
{
   Serial.println(temp[0]);
   Serial.println(temp[1]);
   Serial.println(temp[2]);
   if(flag == true)
   {
        Serial.println(y);
        flag = false;
   }

    //if ( Serial1.available() )   {  Serial.write( Serial1.read() );  }

   delay(2000);

}

void serialEvent() 
{
     while(Serial1.available()) 
     {
        y = Serial1.read();
        flag = true; //Serial.write( Serial1.read());
     }
}

I did try this but i still see the same results. It is only printing the packets from ESP to Atmega but it does not work from Atmega to ESP.

Are you using the following Boards? And you are sending '0' (numeral 0) from MEGA to ESP8266 using UART3 Port -- correct?

Arduino MEGA2560
megaPic

ESP8266 Based NodeMCU

1 Like

the serialEvent on esp8266 is an event for Serial, but you read Serial1

Hi,

i am using similar board - the only difference is both of them are integrated in a single chip.

The objective is to pass temp[] packets from Atmega board to ESP and from ESP to Atmega.

P.S -> i also have the boards which you have in your pic. If you believe that module works fine with the code shared i am fine with that too. Kindly let me know on what would be the pin out connections.

if i read it in the serial port of ESP it would create garbled messages and would not serve the purpose of differentiating incoming and outgoing messages.

If you want I can provide you the hardware setup and test sketches for UART communication beteen MEGA and Node.

1 Like

That would be cool.

But it would be awesome if it would be at same board.

1. make connection as per Fig-1 using Serial3 Port of MEGA and Software Serial Port of NodeMCU.


Figure-1:

2. Upload the following sketches and check that SM of Node shows A that is coming form MEGA at 1-sec interval.

Sketch foe MEGA:

byte temp[] = {5, 15, 25};
byte temp2[] = {};

//HardwareSerial *ESPComm = (HardwareSerial *)&Serial3;

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

void loop()
{
  Serial3.println('A');
  delay(1000);
}

Sketch foe NodeMCU:

#include<SoftwareSerial.h>
SoftwareSerial SUART(D2, D1);//SRX = D2, STX = D1
byte temp[] = {10, 20, 30};

void setup()
{
  // transfer packet
  Serial.begin(115200);
  SUART.begin(9600);
}

void loop()
{
  byte n = SUART.available();
  if (n != 0)
  {
    char y = SUART.read();
    Serial.print(y);
  }
  /*else
  {
    Serial.println(temp[0]);
    Serial.println(temp[1]);
    Serial.println(temp[2]);
  }*/
}

I don't own that board.

Sweet will try - what about packets from ESP to mega.

i found an alternate way which is simple and will work in both modes.

mode 1-> Serial communication between ESP and Mega (code which i shared 1st)
mode 2-> JSON communication between Mega and ESP

ESP code (Mock)

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <ESP8266mDNS.h>
MDNSResponder mdns;

ESP8266WebServer server (80);
const char* ssid = "Rahul-Chandrashekar-WiFi";
const char* password = "pwd";

byte temp[] ={10,20,30};

void setup()
{
  WiFi.begin(ssid,password);
  Serial.begin(9600);
  Serial1.begin(9600);
  while(WiFi.status()!=WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

if (mdns.begin("esp8266", WiFi.localIP())) {
    Serial.println("MDNS responder started");
  }
     

  server.on("/",handleIndex);
  server.begin();
}

void loop()
{
     Serial.println(temp[0]);
   Serial.println(temp[1]);
   Serial.println(temp[2]);
  server.handleClient();
}

void handleIndex()
{
  // Send a JSON-formatted request with key "type" and value "request"
  // then parse the JSON-formatted response with keys "gas" and "distance"
  DynamicJsonDocument doc(1024);
  double gas = 0, distance = 0;
  // Sending the request
  doc["type"] = "request";
  serializeJson(doc,Serial);
  // Reading the response
  boolean messageReady = false;
  String message = "";
  while(messageReady == false) { // blocking but that's ok
    if(Serial.available()) {
      message = Serial.readString();
      messageReady = true;
    }
  }
  // Attempt to deserialize the JSON-formatted message
  DeserializationError error = deserializeJson(doc,message);
  if(error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }
  distance = doc["distance"];
  gas = doc["gas"];
  // Prepare the data for serving it over HTTP
  String output = "distance: " + String(distance) + "\n";
  output += "CO level: " + String(gas);
  // Serve the data as plain text, for example
  server.send(200,"text/plain",output);
}

Mega code

#include <ArduinoJson.h>

String message = "";
bool messageReady = false;
byte temp[] ={5,15,25};
byte temp2[] ={};

void setup() {
Serial.begin(9600);
//recieved pacakage
Serial3.begin(9600);
}

void loop() {
// Monitor serial communication
while(Serial.available()) {
message = Serial.readString();
messageReady = true;
}
// Only process message if there's one
if(messageReady) {
// The only messages we'll parse will be formatted in JSON
DynamicJsonDocument doc(1024); // ArduinoJson version 6+
// Attempt to deserialize the message
DeserializationError error = deserializeJson(doc,message);
if(error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
messageReady = false;
return;
}
if(doc["type"] == "request") {
doc["type"] = "response";
// Get data from analog sensors
doc["distance"] = 20;
doc["gas"] = 10;
serializeJson(doc,Serial);
}
messageReady = false;
}
}

// To verify the event from ESP
void serialEvent3() {
int i =0;
while (Serial3.available()) {
temp2[i] = Serial3.read();
Serial.write(temp2[i]);
i++;
}
}

i did try this with Wemos D1 R1 board and Mega but i am getting the same results as earlier.

able to send data from Wemos to Mega but not vice versa.

Connections

Mega | Wemos

15 -> D1
14 -> D2

only data from Wemos is received by Atmega :(.

Is Wemos D1R1 board a 3.3V board? I mean if the logic levels of the IO pins are 3.3V?

yes Wemos is 3.3 V board similar to any ESP8266 board.

Then connect TX line of MEGA as follows and try:
TXofMEGA -- 2.2k -------- 4.7k--------GND
RXofWemos to the junction point of 2.2k and 4.7k.

will do -> if you look Wemos also can have 5V supply. Does it really need the pull up/down resistors?

DPin-14 (TX3) of MEGA maintains 0 to 5V logic.
D2 (RX) pin of Wemos maintains 0 to 3.3V logic.
so, you need logic sifter and that is what I have provided you using passive components.

//-----------------------------------------------
D1 (TX) pin of Wemos maintains 0 to 3.3V logic.
DPin-15 (RX3) of MEGA will accept 3V to 5V as HIGH. So, you don't need logic sifter here.

so based on your feedback -> i would need RX Wemos to the junction point of 2.2k and 4.7k.

Try as I have suggested; there is a good chance that it will work as the other line is already working.