ESP8266-01 Serial Communication

Hi,

My project is a swing gate opener system. It should be controlled utilizing an ESP8266-01 Module via Wi-Fi. The ESP8266 is supposed to communicate with an Arduino MEGA using Serial. My idea is to have two button - OPEN and CLOSE respectively. If OPEN is pressed the ESP8266 sends a 1 on the Serial and the MEGA is supposed to receive the data on Serial1 port. If CLOSE is pressed the ESp8266 sends a 2 on the Serial. The Arduino MEGA is supposed to react according to the number received on Serial1 port.

The problem is that it receives the correct number along with other random numbers which is not very stable. Another thing is that the routine after receiving the correct number is not executing exatly as it should be.

Here is my ESP8266-01 sketch:
I am not sure if I should use Serial.write(1) or Serial.write(“1”) or Seria.write(‘1’).

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

ESP8266WebServer Webserver(81);

// Replace with your network credentials
const char* ssid = "";
const char* password = "";

String HTMLpage = "";

void setup(void)
{
  HTMLpage += "<head><title>Name</title></head><h3>Welcome!</h3><p>DOOR <a href=\"DOOROPENING\"><button>OPEN</button></a>&nbsp;<a href=\"DOORCLOSING\"><button>CLOSE</button></a></p>";

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

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

  Webserver.on("/", [](){
    Webserver.send(200, "text/html", HTMLpage);
  });
  
  Webserver.on("/DOOROPENING", [](){
    Webserver.send(200, "text/html", HTMLpage+"<p>DOOR OPENING</p>");
    Serial.write(1);
  });
  
  Webserver.on("/DOORCLOSING", [](){
    Webserver.send(200, "text/html", HTMLpage+"<p>DOOR CLOSING</p>");
    Serial.write(2);
  });

  Webserver.begin();
  Serial.println("HTTP Webserver started");
}

void loop(void)
{
  Webserver.handleClient();
}

Here is the Arduino MEGA sketch:

#include <DS3231.h>

int relay1 = 22;
int relay2 = 23;
int relay3 = 52;
int relay4 = 40;
int relay5 = 41;

DS3231  rtc(SDA, SCL);

void sensors_for_open();
void sensors_for_close();
void door_open_detect();
void manual_mode();
void dooropen(void);
void doorclose(void);
void doorstop(void);

int received = 0;
int lastreceived = 0;
int PasswordGood = -1;
bool q = false; // Detects the time when the door has been opened
int x_detect;  // Detects the hours
int y;  // Detects the minutes
Time det; // Отчитане на времето
Time t; //Time now, always refreshed in the loop
bool print_Time = false;
Time i;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  pinMode(relay5, OUTPUT);
  pinMode(32, INPUT);
  pinMode(44, INPUT);
  pinMode(53, INPUT);
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
  digitalWrite(relay5, HIGH);

  rtc.begin();
  
  // The following lines can be uncommented to set the date and time
  rtc.setDOW(SATURDAY);     // Set Day-of-Week to SUNDAY
  rtc.setTime(16, 38, 30);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(6, 3, 2019);   // Set the date to January 1st, 2014

}

void loop()
{
  Serial.print(received);
  Serial.println("\n");

  t = rtc.getTime();

  while(!Serial1) // Wait for the Serial1
  {
    
  };
  if(Serial1.available())
  {
    received = Serial1.read(); // Save the value of the Serial1
    if(received > 0 && received < 3) // Limit the range of that value
    {
      lastreceived = received;
    }
  }
  switch (lastreceived)
  {
  case 1: // If OPEN button is pressed
    dooropen();
    sensors_for_open();
    door_open_detect();
    sensors_for_close();
    break;

  case 2: // If CLOSE button is pressed
    doorclose();
    sensors_for_close();
    break;
  }

  /* // Another version of the switch statement above
  if(lastreceived == 1)
  {
    dooropen();
    sensors_for_open();
    door_open_detect();
    sensors_for_close();
  }
  
  if(lastreceived == 2)
  {
    doorclose();
    sensors_for_close();
  }
  */

  manual_mode();
}


void dooropen(void)
{
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, LOW);
  digitalWrite(relay4, HIGH);
  digitalWrite(relay5, LOW);
}

void doorclose(void)
{
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW);
  digitalWrite(relay4, LOW);
  digitalWrite(relay5, HIGH);
}

void doorstop(void)
{
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
  digitalWrite(relay5, HIGH);
}

void sensors_for_open()
{
  // Check if the inductive sensor is activated (presence of a metal object in front)
  if(digitalRead(32) == HIGH)
  {
    doorstop();   
    do
    {
       doorclose(); 
    }while(digitalRead(32) == HIGH);

    if(digitalRead(32) == LOW)
    {
      doorstop();
      q = true;
      delay(1);
    }
  }
}

void manual_mode()
{
  // Button for manual mode (physical(real) button)
  if(digitalRead(53) == HIGH)
  {
    print_Time = false;
    x_detect=0;
    y=0;
    while(received != 2)
    {
      
    };
  }
}

void door_open_detect()
{
  // Detect the exact time when the door is in open position
  if(q == true)
  {
    det = rtc.getTime();
    x_detect = det.hour;
    y = det.min;
    y = y+1;
    Serial.print("det");
    Serial.print(" \n ");
    Serial.print(x_detect);
    Serial.print(" -- ");
    Serial.print(y);
    Serial.print(" -- ");
    Serial.print(det.sec);
    Serial.print(" \n ");
    Serial.print(t.hour);
    Serial.print(" -- ");
    Serial.print(t.min);
    Serial.print(" -- ");
    Serial.print(t.sec);
    Serial.print(" \n ");
    Serial.print(" \n ");
    Serial.print(" \n ");
    
    q = false;
  }
// Wait a certain amount of time before initiating automaically sequence for closing(in this case wait 1 minute)
  if( x_detect == t.hour && y == t.min && det.sec == t.sec )
  {
    Serial.print("Time match");
    Serial.print(" \n ");
    Serial.print(t.hour);
    Serial.print(" -- ");
    Serial.print(t.min);
    Serial.print(" -- ");
    Serial.print(t.sec);
    Serial.print(" \n ");
    
    doorclose();
    x_detect = 0;
    y = 0;
  }
}  

void sensors_for_close()
{
  if(digitalRead(44) == HIGH) // Check the close sensor(on the other side of the door)
  {
    doorstop();
    do
    {
       dooropen();
    }while(digitalRead(44) == HIGH);
    
    if(digitalRead(44) == LOW)
    {
      doorstop();
      delay_ON = false;
      print_Time = false;
      delay(1);
    }
  }
}

What am I doing wrong? Basically what is being executed is just the doopopen() function in the switch statement or perhaps a part of the next one and then the MEGA gets confused.

How is the ESP connected to the Mega? Can you post a diagram?

You can't connect the ESP serial to the Mega and serial monitor at same time.

The serial input basics tutorial will show how to do reliable serial communication.

Schematic is needed indeed.

Remember RX/TX are crossed when connecting the ESP to the Arduino.

Have the Mega echo the values it receives on Serial1 to the Serial monitor (beware of the unprintable nature of the values 1 and 2).

void loop(void)
{
  Webserver.handleClient();
}

Maybe I'm missing something but where in there do you send anything to the serial port of the ESP8266?

PerryBebbington: Maybe I'm missing something but where in there do you send anything to the serial port of the ESP8266?

You obviously missed the server.on() function calls.

wvmarle: You obviously missed the server.on() function calls.

I'm out of my depth here as I don't know the webserver library, are you saying that:

void loop(void)
{
  Webserver.handleClient();
}

Is enough to get information from a web page, process it and send the result to the serial port?

Yes.

The respective server.on() functions are called based on the URL, and that’s where the Serial.write() is done as well.

Here a more detailed explanation.

Thank you wvmarle, much appreciated.

groundFungus:
How is the ESP connected to the Mega? Can you post a diagram?

You can’t connect the ESP serial to the Mega and serial monitor at same time.

The serial input basics tutorial will show how to do reliable serial communication.

wvmarle:
Schematic is needed indeed.

Remember RX/TX are crossed when connecting the ESP to the Arduino.

Have the Mega echo the values it receives on Serial1 to the Serial monitor (beware of the unprintable nature of the values 1 and 2).

I have attached the schematic.

Basically, what I do is - first I connect the RX and TX of the ESP8266 to the RX0 and TX0 of the MEGA respectively when I upload a new sketch to the ESP8266. Then I disconnect the power of the MEGA respcectively of the ESP8266(the ESP8266 is powered from the MEGA(I read that this is not correct but I am not sure why) and connect the TX and RX of the EPS8266 to the Serial1 pins of the MEGA. RX of the ESP8266 to the RX1 of the MEGA and TX of the ESP8266 to the TX1 of the MEGA.

I tried to print the received values from the ESP8266 on the Serial Monitor and it works to some extent. For a certain amount of the time it prints to correct number but then it prints some other number like 103 for example.

PerryBebbington:

void loop(void)

{
 Webserver.handleClient();
}




Maybe I'm missing something but where in there do you send anything to the serial port of the ESP8266?

It is in the setup() function.

  Webserver.on("/DOOROPENING", [](){
    Webserver.send(200, "text/html", HTMLpage+"<p>DOOR OPENING</p>");
    Serial.write(1); // Serial write function is here sending data to the MEGA
  });
  
  Webserver.on("/DOORCLOSING", [](){
    Webserver.send(200, "text/html", HTMLpage+"<p>DOOR CLOSING</p>");
    Serial.write(2); // Serial write function is here sending data to the MEGA
  });

wvmarle:
You obviously missed the server.on() function calls.

I think this is the server.on() function you mean.

  Webserver.on("/", [](){
    Webserver.send(200, "text/html", HTMLpage);
  });

wvmarle:
Yes.

The respective server.on() functions are called based on the URL, and that’s where the Serial.write() is done as well.

Here a more detailed explanation.

I think did understand where the server.on() function is.

I am sorely puzzled as to why you are using an Arduino Mega 2560. :astonished:

A WeMOS D1 Mini has nine available I/O as well as the serial interface. Two for the DS3231, three for the TPIC6B595 to directly switch eight relays or a 74HC595 if you wish to use a relay module, three for the limit switches and proximity sensor. That's eight I/O, one to spare - what else have I missed? :roll_eyes:

Why the DS3231. The WeMos D1 mini keeps perfect time by itself between occasional NTP updates. Leo..

KonstantinBG: Basically, what I do is - first I connect the RX and TX of the ESP8266 to the RX0 and TX0 of the MEGA respectively when I upload a new sketch to the ESP8266. Then I disconnect the power of the MEGA respcectively of the ESP8266(the ESP8266 is powered from the MEGA(I read that this is not correct but I am not sure why) and connect the TX and RX of the EPS8266 to the Serial1 pins of the MEGA. RX of the ESP8266 to the RX1 of the MEGA and TX of the ESP8266 to the TX1 of the MEGA.

You're mixing up things. RX0 to RX of the ESP, TX0 to TX of the ESP when uploading sketches (as you just pass on the Serial signal and use the Mega as Serial/TTL converter).

RX1 to TX of the ESP, TX1 to RX of the ESP in normal operation.

You also need a voltage divider in the TX1-RX connection, or you risk killing your ESP.

Paul__B:
I am sorely puzzled as to why you are using an Arduino Mega 2560. :astonished:

A WeMOS D1 Mini has nine available I/O as well as the serial interface. Two for the DS3231, three for the TPIC6B595 to directly switch eight relays or a 74HC595 if you wish to use a relay module, three for the limit switches and proximity sensor. That’s eight I/O, one to spare - what else have I missed? :roll_eyes:

I know what you mean, but fristly my idea was to use a TFT Display having an input keyboard on it. Since the TFT Display needs many pins I bought an Arduino MEGA. In my opinion having a MEGA or any other board with a lot of pins is better since if you want an upgrade or if you start a new project you have a certain margin to extent you project. Then I was thinking how can I protect the TFT Display from the weather conditions and could not think of a secure way to protect the Display. Therefore I decided to use an ESP8266 which will be in an electrical cabinet.

You are right I can you a WeMOS D1 Mini board but I have to wait a lot ot time for the delivery.

wvmarle:
You’re mixing up things.
RX0 to RX of the ESP, TX0 to TX of the ESP when uploading sketches (as you just pass on the Serial signal and use the Mega as Serial/TTL converter).

RX1 to TX of the ESP, TX1 to RX of the ESP in normal operation.

You also need a voltage divider in the TX1-RX connection, or you risk killing your ESP.

Do you mean the this kind of connections and voltage divider?

I have attached a picture showing the wiring.

That module draws ~80mA, with short ~400mA transmit peaks. Not very wise to power that from a 3.3volt pin that can only deliver 150mA absolute max. Use at least some capacitance (>=470uF) on that supply, to bridge those peaks. A separate 3.3volt supply for the ESP would be safer for the Mega. There are special daughter boards for those modules, with 3.3volt regulator. Leo..

wvmarle: You're mixing up things. RX0 to RX of the ESP, TX0 to TX of the ESP when uploading sketches (as you just pass on the Serial signal and use the Mega as Serial/TTL converter).

RX1 to TX of the ESP, TX1 to RX of the ESP in normal operation.

You also need a voltage divider in the TX1-RX connection, or you risk killing your ESP.

I did what you suggested but unfortunately I do not receive anything now. I am printing the received value and it is always 0 even though I am pressing the buttons on the web server page.

I connected RX1 to the TX of the ESp8266 and TX1 to RX of the ESP8266 and a voltage divider as in the picture in my previous post.

Wawa: That module draws ~80mA, with short ~400mA transmit peaks. Not very wise to power that from a 3.3volt pin that can only deliver 150mA absolute max. Use at least some capacitance (>=470uF) on that supply, to bridge those peaks. A separate 3.3volt supply for the ESP would be safer for the Mega. There are special daughter boards for those modules, with 3.3volt regulator. Leo..

I have connected the ESP8266 to an external 3.3V power supply having a common ground between the external supply and the Arduino.

KonstantinBG: I did what you suggested but unfortunately I do not receive anything now. I am printing the received value and it is always 0 even though I am pressing the buttons on the web server page.

First you say you don't receive anything; then you say you receive zeros. Now do you receive anything or not? Receiving nothing is very different from receiving something unexpected.

Wawa: That module draws ~80mA, with short ~400mA transmit peaks.

That bad? I thought the numbers are about 1/3 that. 100 uF is what I always use for an ESP12 module; working great.

wvmarle: First you say you don't receive anything; then you say you receive zeros. Now do you receive anything or not? Receiving nothing is very different from receiving something unexpected.

That bad? I thought the numbers are about 1/3 that. 100 uF is what I always use for an ESP12 module; working great.

Actually I am receiving only zeroes even though I am pressing the buttons on the web server. This is very weird for me since, before when I had TX1 to TX of the ESP8266 and RX1 to the RX of the ESP8266 I was receveing the correct number when the corresponding button on the web server had been pressed. But as I described in the first post only a part of the routine was executed and after the correct value some random values were received.

I am not sure if that is of any improtance but my RX LED on the Arduino MEGA is always lighting up and it does not blink when I press the button on the web server.

One more thing to add is that I did not upload the sketch again when I connect the ESP8266 as you suggested with the voltage divider.

I am powering the ESP8266 from a ATX power supply which has a sufficient current rating therefore I guess I do not need capacitor.

Did you amend the Mega sketch for the new Serial connection you use?

That wiring diagram shows connections to TX2 and RX2. Not TX1 and RX1.

wvmarle: Did you amend the Mega sketch for the new Serial connection you use?

That wiring diagram shows connections to TX2 and RX2. Not TX1 and RX1.

The picture is just for reference, I took the picture from the Internet. In my setup I have the Esp8266 connected to TX1 and RX1.

In the Arduino MEGA sketch I only changed the ways of how the logic should be executed. For example, I changed the if statement with a swtich and case statement(you can see in the sketch, the if statements is commented), I tried to put the switch and case statemnt into the if statement for the Serial1.read(). This what I have amended.

KonstantinBG:
The picture is just for reference, I took the picture from the Internet. In my setup I have the Esp8266 connected to TX1 and RX1.

Thank you for wasting our time with irrelevant images.