Arduino mega to esp8266 communication via TX RX

Hello,

I’m trying to send data from Arduino Mega to a Wemos D1 ESP8266 board, could you please help? Something is wrong with the code but I can’t figure out what.


//Transmitter code
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#define SAMPLES 20 //Number of samples you want to take everytime you loop

SoftwareSerial toESP(15,14);
int voltageValue = analogRead(A0); //From Sunnybuddy output
int ADCValue = analogRead(A1); // From Sensor output
int Vr_value = analogRead(A2); // From solar panel
int sensorValue = analogRead(A3); // From solar panel
float R1 = 470000; // These 2 resistors build up a Voltage divider to bring down PV voltage down to Arduino operating voltage
float R2 = 100000;
float Vcharg = 3.8;
String data = “”;

// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:

Serial.begin(115200);
while (!Serial) continue;

// Initialize the “link” serial port
// Use the lowest possible data rate to reduce error ratio
toESP.begin(4800);
toESP.print("From Arduino Mega 2560 Hello :wink: ");
}

// the loop routine runs over and over again forever:
void loop() {

//Reading PV module input status
// reading current from A2/supply voltage and calcultating average value

int Vr_valueavg = 0;
for (int i=0; i < SAMPLES; i++) {
Vr_valueavg = Vr_valueavg + analogRead(A2);
}
Vr_valueavg = Vr_valueavg /SAMPLES;
float Vr = Vr_valueavg * (5.0 / 1023.0);
float Vin = Vr * ((R1+R2)/R2);

// reading current from A3/supply current and calcultating average value
int sensorValueavg = 0;
for (int i=0; i < SAMPLES; i++) {
sensorValueavg = sensorValueavg + analogRead(A3);
}
sensorValueavg = sensorValueavg /SAMPLES;
float voltage_sensor = sensorValueavg * (5.0 / 1023.0);
float Iin = (voltage_sensor - 2.5)/ 0.185;

float Pin = Vin * Iin;

Serial.print(“PV module : Supply V=”);
Serial.print(Vin,3);
Serial.print(“V Supply I=”);
Serial.print(Iin,3);
Serial.print(“A P=”);
Serial.print(Pin,3);
Serial.print(“W”);

// reading voltage from A0/output voltage and calcultating average value,
// we are interested in value above 3.8V as it is our rated battery charging voltage

int VoltageValueavg = 0;
for (int i=0; i < SAMPLES; i++) {
VoltageValueavg = VoltageValueavg + analogRead(A0);
}
VoltageValueavg = VoltageValueavg /SAMPLES;
float Vout = VoltageValueavg * (5.0 / 1023.0);

// reading current from A1/output current and calcultating average value

int ADCValueavg = 0;
for (int i=0; i < SAMPLES; i++) {
ADCValueavg = ADCValueavg + analogRead(A1);
}
ADCValueavg = ADCValueavg /SAMPLES;
float voltage_ADC = ADCValueavg * (5.0 / 1023.0);
float Iout = (voltage_ADC - 2.5)/ 0.1;

float Pout = Vout * Iout;

if (Vout > Vcharg){
Serial.print(" || Battery charging : Output V=");
Serial.print(Vout,3);
Serial.print(“V Ouput I =”);
Serial.print(Iout,3);
Serial.print(“A P=”);
Serial.print(Pout,3);
Serial.println(“W”);
}else if (Vout < Vcharg){
Serial.print(" Output V=");
Serial.print(Vout,3);
Serial.println(" || Status: Battery not charging; Note: V needs to be at least 3.8V to match battery rating");
}
delay(2000);

while(Serial.available()){
data = Serial.readString();
// Create the JSON document
StaticJsonDocument<3000> doc;

//getting data from sensors
doc[“Vin”] = Vin;
doc[“Iin”] = Iin;
doc[“Pin”] = Pin;
doc[“Vout”] = Vout;
doc[“Iout”] = Iout;
doc[“Pout”] = Pout;
serializeJson(doc,Serial);
toESP.write(toESP.read());
delay(2000);
}

}

ESP Code

/*
This code includes a part that is in the public domain and includes own inputs.
Voltage V, Unit V
Current I, Unit A
Power P, Unit W
*/

//Receiver code

#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#include “PageIndex.h”
SoftwareSerial toESP(0,1);
const char* ssid = “iPhone de Jelka”;
const char* password = “123456789”;
//
//const char* ssid = “WSG-Mobilna pracownia”;
//const char* password = “M0b1lnaPracown1a”;

ESP8266WebServer server(80);

void handle_Root() {
server.send(200, “text/html”, MAIN_page); //Send web page

}

void handle_NotFound() {
server.send(404,“text/plain”,“Page not found”);
}

// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:

Serial.begin(115200);
Serial.println(“Jelka Bisa MPPT Project V, I and P measurements”);

WiFi.begin(ssid,password);
Serial.print(“Connecting network .”);
while(WiFi.status()!=WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println(" done");
Serial.print("Successfully connected to: ");
Serial.println(ssid);
Serial.print("IP adress: ");
Serial.print(WiFi.localIP());

server.on("/", handle_Root); //–> This is to display web page.
server.begin(); //–> Start server
Serial.println(" HTTP server started");
}

// the loop routine runs over and over again forever:
void loop() {

StaticJsonDocument<3000> doc;
float Vin;
float Iin;
float Pin;
float Vout;
float Iout;
float Pout;

serializeJson(doc, Serial);
String data = “”;
if (Serial.available() > 0){
DeserializationError error = deserializeJson(doc, Serial);
if(error){
Serial.print(F((“deserializeJson() failed with code”)));
Serial.println(error.c_str());
messageReady = false;
return;
}
//Fetching values
Vin = doc["Vin"];
Iin = doc["Iin"];
Pin = doc["Pin"];
Vout = doc["Vout"];
Iout = doc["Iout"];
Pout = doc["Pout"];

Serial.print(“PV module : Supply V=”);
Serial.print(Vin,3);
Serial.print(“V Supply I=”);
Serial.print(Iin,3);
Serial.print(“A P=”);
Serial.print(Pin,3);
Serial.print(“W”);
Serial.print(" Battery charging : Output V=");
Serial.print(Vout,3);
Serial.print(“V Ouput I =”);
Serial.print(Iout,3);
Serial.print(“A P=”);
Serial.print(Pout,3);
Serial.println(“W”);
}
delay(2000);
server.handleClient();
}

Please edit it and Paste it in Code tags </> it is a button in the toolbar.

That is not very helpful, what does the code do that it is not supposed to?, what does the code not do that it is supposed to?

Please format it in the Arduino IDE (use ctrl T) it makes it much easier to read and to spot errors such as a curly brace in the wrong place. As already requested post the reformatted code within a code bock (use the </> button).

Your duplicate post was DELETED.
Please do NOT crosspost, hijack other peoples topics.

Please read this post

thanks

Hello,

it is supposed to send sensor data from Arduino mega to ESP8266 Wemos D1. I added coments for explanation. The data is uploading on Arduino but nothing comes through on ESP.

First try one of my complete sample sketches and circuits for Serial Coms between Arduino/ESP
If you are using a Mega then use one of the hardware serials instead of Software Serial (although I have sketches the work for SoftwareSerial as well)

You could start with Uno-SoftwareSerial to ESP8266-SoftwareSerial

Then replace the UNO-SoftwareSerial with Mega SerialComsPair_HardwareSerial1.ino.

Not one side must be set as the Controller, you will need to set the Mega as the Controller, see the tutorial for details.
I am currently working on a much simpler set of code for this so watch that page for updates.

But as stated before, it is even harder for us to figure that out without extra information.
Please provide a connection diagram

#include <SoftwareSerial.h>
#include “PageIndex.h”
SoftwareSerial toESP(0,1);

Using swSerial on pins 0 & 1 (GPIO nrs) is not going to work very well, since GPIO1 is the hwTX pin.
I would not use swSerial at all on the wemos side, but rather use swap() to switch to the alternate pins for hwSerial (13 & 15)
Remember you will need a voltage divider on to divide the incoming voltage on the Wemos RX pin.

server.on("/", handle_Root); //–> This is to display web page.

And your ‘handleNotFound’ page ? no callback for that ?

}
delay(2000);
server.handleClient();
}

handleClient() should be called more often than every 2 seconds. If there is something else that needs to be called at 2 second interval, you should use millis() elapsed time to do that.

Your swSerial in the ESP code is never even started, but then again you never seem to be reading from it, but your hwSerial is used for passing information to the user.

Hello,

the connection is okay, I also reduced the voltage from 5V to 3.3V. What I’m puzzled with is the code for transmitting and receiving the data. Is there something missing in the Json serialization or deserialization?

while(Serial.available()){
   // Create the JSON document
  StaticJsonDocument<50> doc;
    
  //getting data from sensors
          doc["Vin"] = Vin;
          doc["Iin"] = Iin;
          doc["Pin"] = Pin;
          doc["Vout"] = Vout;
          doc["Iout"] = Iout;
          doc["Pout"] = Pout;
          serializeJson(doc, toESP); //Send data to ESP module
          delay(2000);
  }   
type or paste code   
StaticJsonDocument<200> doc;
float Vin;  
float Iin;  
float Pin; 
float Vout;
float Iout;
float Pout;    
DeserializationError error = deserializeJson(doc, toESP);
     if (error) {
  Serial.print(F("deserializeJson() failed: "));
  Serial.println(error.f_str());
  return;
}

    //Fetching values
    Vin = doc["Vin"];
    Iin = doc["Iin"];
    Pin = doc["Pin"];
    Vout = doc["Vout"];
    Iout = doc["Iout"];
    Pout = doc["Pout"];
here

Hello,

thanks but I would like to use ArduinoJson

You can send whatever text you want, just any embedded \n are replaced by spaces, which should not be a problem for JSON unless you have \n in some of your data fields
Being JSON you should be able to send it chunks at a time and put them back together at the receiver.

does that mean the code is okay and should be working?

Hi,
I managed to get some code working using my revised SerialComs class.
Currently I have the code running between ESP32 Serial2 and Mega2560 Serial1.
Since you are using a Mega on one side, any reason you cannot use the HardwareSerial Serial1,2 or 3 instead of the SoftwareSerial?

I will have look at setting the code up on ESP8266 tomorrow,
in the mean time here is some output
Still have a little trouble with the code I need to sort out.

on the ESP32

19:00:00.755 ->  Made Connection.
19:00:00.755 -> PV module : Supply V = 6.826V Supply I = -7.490A P = -51.122W
19:00:02.756 -> Lost Connection
19:00:02.756 -> Send Data '{"Vin":7.717009,"Iin":-6.010409,"Pin":-46.38238,"Vout":1.324536,"Iout":-13.75855,"Pout":-18.2237}'
19:00:02.859 -> PV module : Supply V = 7.438V Supply I = -6.116A P = -45.494W
19:00:04.861 -> Prompt other side to connect

on the Mega

18:51:54.282 ->  Made Connection.
18:51:54.282 -> {"Vin":6.491202,"Iin":-7.014345,"Pin":-45.53153,"Vout":1.402737,"Iout":-10.87488,"Pout":-15.25459}
18:51:54.282 -> Deserialized to -> PV module : Supply V = 6.491V Supply I = -7.014A P = -45.532W Battery charging : Output V=1.403V Ouput I = -10.875A P = -15.255W
18:51:58.262 -> Lost Connection
18:52:00.292 ->  Made Connection.
18:52:00.292 -> {"Vin":6.602639,"Iin":-6.882248,"Pin":-45.441,"Vout":1.4174,"Iout":-10.97263,"Pout":-15.5526}
18:52:00.292 -> Deserialized to -> PV module : Supply V = 6.603V Supply I = -6.882A P = -45.441W Battery charging : Output V=1.417V Ouput I = -10.973A P = -15.553W

Since you are only sending in one direction it may be simpler to just add unique start and end chars.
Like < > to the json output and then use
code like startEndCharInput.ino
see Arduino Software Solutions

So start with stripping out the web stuff and just get the json to go from board to board.

Edit: - On second thought not that easy due to the delays on both sides and the RX buffer overflow problem. You need a small sync char the gets things lined up, which is what SerialComs does. It uses \n (empty line) as a sync

lovely! Could you please share the code you use? it seems I’m missing sth. sending data but only receiving zeros.

also about the comment, “On second thought not that easy due to the delays on both sides and the RX buffer overflow problem. You need a small sync char the gets things lined up, which is what SerialComs does. It uses \n (empty line) as a sync”

how do I do that?

I fixed the software problem. The sync is built into my SerialComs class.

What sort of ESP8266 do you have (how many pins)?
Still OK with using Mega HardwareSerial Serial1?

Should have something you can download in 24hrs.

Hello,

I have a Wemos D1 ESP8266 module with 1 serial port.
image

Ok Have ESP8266 package V2.7.4 (I am testing with Adafruit Hazzah ESP8266) with Software Serial on

const int RX_pin = 15; // for ESP8266 use 15  D10 on wemos-d1-esp8266
const int TX_pin = 13; // for ESP8266 use 13  D7  on wemos-d1-esp8266

with a 256 byte RX buffer

and a Mega2560 using Hardware Serial Serial1 Tx = 18, Rx = 19 (default 64byte RX buffer)

Seems to work well even with >5sec delays in each loop.
I will finish up tomorrow and give you a download link for the library and sketches.

Lovely thank you very much

Hi jelka_bisa try this out and see how you get on.
Here is the circuit I used.

Download V4.1.0 of the SafeString library from the SafeString tutorial

Here are the two sketches I used for testing. I removed all the web code and sample averaging.
The ESP8266 did not like having the static json processor in the loop(), so I made it global and reduced the size.
The ESP8266 SoftwareSerial is set up with a 256byte RX buffer. Because of the long delays in both loops, the RX buffer needs to be able to hold the entire json message. The current json msg length is <100 chars so there is plenty of room the add more. I increased the baud rate to 9600. Comments on-line suggest upto 115200 is OK, but I did not try any faster than 9600.
A note about

SafeString::setOutput(Serial);

That statement enables SafeString error msgs and debugging. You can comment it out once you are clear everything is working.

For the ESP8266

//ESP8266 Code
//https://forum.arduino.cc/t/arduino-mega-to-esp8266-communication-via-tx-rx/857016/2

//Receiver code
// download SafeString V4.1.0+ library from the
// https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
//
#include "SerialComs.h"
#include <ArduinoJson.h>
#include "SoftwareSerial.h"
const int RX_pin = 15; // for ESP8266 use 15  D10 on wemos-d1-esp8266
const int TX_pin = 13; // for ESP8266 use 13  D7  on wemos-d1-esp8266
SoftwareSerial toESP(RX_pin, TX_pin);
//#define toESP Serial2

// sendLineLength, receiveLineLength
SerialComs coms(10, 250); // send 10 (nothing sent), receive 250 chars
// receiveLineLength must match other sides sendLineLength
// sendLineLength must match other sides receiveLineLength

StaticJsonDocument<1000> doc;

void setup() {
  Serial.begin(115200);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();  Serial.println("Jelka Bisa MPPT Project V, I and P measurements");
  SafeString::setOutput(Serial); // enable error messages and debugging

  toESP.begin(9600, SWSERIAL_8N1, -1, -1, false, 256); // use previous rxPin, txPin and set 256 RX buffer
  coms.setAsController(); // need to do this on one side
  // Always choose the SoftwareSerial Side as the controller

  if (!coms.connect(toESP)) {
    while (1) {
      Serial.println(F("Out of memory"));
      delay(3000);
    }
  }
  Serial.println(F("ESP8266 Setup finished."));
}

void loop() {
  coms.sendAndReceive(); // must do this every loop

  if (!coms.textReceived.isEmpty()) { // got some data
    float Vin;    float Iin;    float Pin;    float Vout;    float Iout;    float Pout;

    DeserializationError error = deserializeJson(doc, coms.textReceived.c_str());
    if (error) {
      Serial.print(F(("deserializeJson() failed with code - "))); Serial.println(error.c_str());
    } else {
      //Fetching values
      Vin = doc["Vin"];
      Iin = doc["Iin"];
      Pin = doc["Pin"];
      Vout = doc["Vout"];
      Iout = doc["Iout"];
      Pout = doc["Pout"];

      Serial.print("Deserialized to -> PV module : Supply V = ");  Serial.print(Vin, 3);
      Serial.print("V Supply I = "); Serial.print(Iin, 3);
      Serial.print("A P = ");  Serial.print(Pin, 3); Serial.print("W");
      Serial.print(" Battery charging : Output V="); Serial.print(Vout, 3);
      Serial.print("V Ouput I = "); Serial.print(Iout, 3);
      Serial.print("A P = "); Serial.print(Pout, 3); Serial.println("W");
    }
  }
  delay(3000);// web stuff delay
}

And for the Mega2560 (hardware serial Serial1)

//https://forum.arduino.cc/t/arduino-mega-to-esp8266-communication-via-tx-rx/857016/2

// download SafeString V4.1.0+ library from the
// https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html

// Mega2560 Transmitter code
#include <ArduinoJson.h>
#include "SerialComs.h"

// use Mega HardwareSerial Serial1
#define toESP Serial1

// do the reads in setup if you need to do initial reads
int voltageValue;// = analogRead(A0); //From Sunnybuddy output
int ADCValue;// = analogRead(A1); // From Sensor output
int Vr_value;// = analogRead(A2); // From solar panel
int sensorValue;// = analogRead(A3); // From solar panel
float R1 = 470000; // These 2 resistors build up a Voltage divider to bring down PV voltage down to Arduino operating voltage
float R2 = 100000;

// sendLineLength, receiveLineLength  
SerialComs coms(250, 10);  // 250 sendlength, 10 receive (nothing recieved)
// sendLineLength must be > json string
// but must be < 250 so whole line fits in Serial RX buffer
// receiveLineLength must match other sides sendLineLength
// sendLineLength must match other sides receiveLineLength

StaticJsonDocument<1000> doc; // allocates on stack

void setup() {
  Serial.begin(115200);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  SafeString::setOutput(Serial); // enable error msgs and debug

  toESP.begin(9600);   // Initialize the "link" serial port

  if (!coms.connect(toESP)) {
    while (1) {
      Serial.println(F("Out of memory"));
      delay(3000);
    }
  }
  Serial.println(F("Mega Setup finished."));
}

void loop() {
  coms.sendAndReceive(); // must do this ever loop

  //Reading PV module input status
  // reading current from A2/supply voltage and calcultating average value
  int Vr_valueavg = analogRead(A2);
  float Vr = Vr_valueavg * (5.0 / 1023.0);
  float Vin = Vr * ((R1 + R2) / R2);

  // reading current from A3/supply current and calcultating average value
  int sensorValueavg = analogRead(A3);
  float voltage_sensor = sensorValueavg * (5.0 / 1023.0);
  float Iin = (voltage_sensor - 2.5) / 0.185;

  float Pin = Vin * Iin;

  Serial.print("PV module : Supply V = ");  Serial.print(Vin, 3);
  Serial.print("V Supply I = ");  Serial.print(Iin, 3);
  Serial.print("A P = ");  Serial.print(Pin, 3);  Serial.print("W");
  Serial.println();

  delay(2000);

  // reading voltage from A0/output voltage and calcultating average value,
  // we are interested in value above 3.8V as it is our rated battery charging voltage
  int VoltageValueavg = analogRead(A0);
  float Vout = VoltageValueavg * (5.0 / 1023.0);

  // reading current from A1/output current and calcultating average value
  int ADCValueavg = analogRead(A1);
  float voltage_ADC = ADCValueavg * (5.0 / 1023.0);
  float Iout = (voltage_ADC - 2.5) / 0.1;

  float Pout = Vout * Iout;

  delay(2000);
  //getting data from sensors
  doc["Vin"] = Vin;
  doc["Iin"] = Iin;
  doc["Pin"] = Pin;
  doc["Vout"] = Vout;
  doc["Iout"] = Iout;
  doc["Pout"] = Pout;
  if (coms.textToSend.isEmpty()) {
    serializeJson(doc, coms.textToSend);
  }
  delay(2000);
}