ESP8266 (NodeMCU) does not want to read data from Arduino UNO on UART.

Hi,

There are ESP8266 (NodeMCU) and Arduino UNO. Both devices are connected via the UART bus.

I have problems with the transfer of data from UNO to ESP (data does not come at all).

Wiring:

RX - TX / TX - RX
Since ESP and UNO have different logic (3.3V / 5V). I made a resistive voltage divider on the TX line from UNO, consisting of 3 resistors, with 1k values.

Similar wiring diagram:

Code Arduino UNO:

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
 delay(2500);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("<220>");
  delay(2500);
  Serial.println("<225>");
  delay(2500);
}

Code ESP8266:

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
char Message[numChars] = { 0 };
boolean newData = false;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW); // HIGH
  delay(500);
  digitalWrite(LED_BUILTIN, HIGH); // LOW
}

void loop() {
  // put your main code here, to run repeatedly:
 recvWithStartEndMarkers();
 if (newData == true) {
  digitalWrite(LED_BUILTIN, LOW);
  strcpy(tempChars, receivedChars);
  parseData();
  msgData();
  newData = false;
 }
}

void recvWithStartEndMarkers()
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

// RAPI Message Protocol
void parseData()
{ // split the data into its parts
    char* strtokIndx; // this is used by strtok() as an index
    strtokIndx = strtok(tempChars, ","); // get the first part - the string
    strcpy(Message, strtokIndx); // copy it to messageFromPC
    //Serial.println(Message);
}

// Message Protocol
void msgData()
{
  if(strcmp("220", Message) == 0) {
    digitalWrite(LED_BUILTIN, LOW); // ON
  } else if(strcmp("225", Message) == 0) {
    digitalWrite(LED_BUILTIN, HIGH); // OFF
  }
}

I see that the RX LED flashes on UNO, which means that the data is sent to ESP, but the ESP itself does not respond to them. I also tried to send data from ESP to UNO, everything works fine here because there are no voltage dividers.

I thought the problem was in the code, perhaps ESP does not understand this data.
I tried to just send the numbers without any brackets and respond to any incoming data by igniting the LED.

Arduino UNO:

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
 delay(2500);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("220");
  delay(2500);
  Serial.println("225");
  delay(2500);
}

ESP8266:

int incomingByte = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1500);
}

void loop() {
      if (Serial.available() > 0) {
        incomingByte = Serial.read();
        digitalWrite(LED_BUILTIN, LOW); 
    }  
}

It brought no results. What could be the problem?
P.s boards are not connected to a PC, so the COM port cannot be the cause of the problem.

Have you scoped or measured the levels coming from your 'voltage divider'?

Yes, in the direction of the RX ESP8266 is 3.29V

I see that the RX LED flashes on UNO, which means that the data is sent to ESP

You mean the Tx LED?

  Serial.println("<220>");
  delay(2500);
  Serial.println("<225>");

I’m not familiar with the ESP to know what you’re trying to do here, but if you think you’re sending a byte code, that’s not the way to do it.

If it’s a byte code, you need to use the write statement. So,

byte temp = 220; Serial.write(temp);

which will send the binary data. If you need to send a character string, the use the Serial.print function, but also the itoa() library call that converts an integer into an ASCII string.

At me, while sending data the RX LED blinks. And I noticed it both at UNO and at MEGA. Probably incorrect silk. I tried instead of ESP to use MEGA (Arduino UNO -> Arduino MEGA), everything works here.

These messages are normally sent and read if I make a UART connection between UNO and MEGA. I took it from the manual from Robin2

https://forum.arduino.cc/index.php?topic=288234.0

I would suggest then that it's safe to assume the problem is not with the UNO. Have you established communications with the ESP from any other device?

I tried both with Arduino UNO, and with Arduino MEGA, there are no results. I can only send commands to these devices from ESP, but not from the device to the ESP.

Change to this on ESP

int incomingByte = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  //delay(500);
  //digitalWrite(LED_BUILTIN, HIGH);
  //delay(1500);
}

void loop() {
      if (Serial.available() > 0) {
        //incomingByte = Serial.read();
        //digitalWrite(LED_BUILTIN, LOW);
        digitalWrite(LED_BUILTIN, HIGH);
    }  
}

and see what the LED does.

Check that the Tx and Rx baud rates match

In the code posted you sometimes use 115200 and at other times use 9600

On ESP, LED has reverse logic. LOW - on / HIGH - off. I tried to change, nothing has changed.

About speed, at the moment everywhere is 9600

Can you put up a schematic of your circuit as it stands? Even a hand drawn one is okay, as long as it reflects your project.

Have a look at this. If you're feeling brave, get rid of your divider circuit. I'd put maybe a 1K limiting resistor in place just to be safe.

It's working! :) So the problem is in the divider.

darrob, This is a test circuit. I need to deal with the UART bus. In the future, there will be several devices that will communicate with ESP via the UART to exchange information and send to the cloud. Voltage divider in the lower left corner.

So no problem with the 5V level? Did you use the limiting resistor?

No, I just connected the wire without resistors.

The ESP8266 (NodeMCU1.0-12E Module) could be operated as a simple UNO having Software Serial Port. Here is the schematic and the test codes. There is no need of voltage divider or level shifter circuits; the Node's pins are 5V tolerant (experimentally found).

uartespUNO-2.png
Figure-1: Connection diagram between NodeMCU1.0-12E and UNO using SUART Ports

A: NodeMCU Codes

#include <SoftwareSerial.h>
SoftwareSerial mySUART(4, 5);//SRX, STX = GPIO4(D2), GPIO5(D1)

void setup()
{
  Serial.begin(115200);
  mySUART.begin(115200);
  Serial.println("\nSoftware serial test started");
}

void loop()
{
  if (mySUART.available() > 0)
  {
    byte x = mySUART.read();
    Serial.write(x);
    yield();   //wait for the process to complete
  }
 
  if (Serial.available() > 0)
  {
    mySUART.write(Serial.read());
    yield();
  }
  
}

B: UNO Codes

#include <SoftwareSerial.h>
SoftwareSerial mySUART(4, 5); //(SRX, STX) pins of UNO-1

void setup()
{
  Serial.begin(115200);     //Bd for hardware UART of UNO-1
  mySUART.begin(115200); //Bd for Software Serial Port of UNO-1
}

void loop()
{
  if (Serial.available() > 0)
  {
    byte x = Serial.read();
    mySUART.write(x);
  }
 
  if (mySUART.available() > 0)
  {
    Serial.write(mySUART.read());
  }
}

C: Operating Procedures
(1) Upload the sketches in the respective Kits.

(2) Bring in the Serial Monitors for both Kits with No line ending option.

(3) Enter character(s) from the InputBox of the Serial Monitor of NodeMCU and click on the Send button; observe that the character (s) has appeared on the OutputBox of the UNO's Serial Monitor.

(4) Enter character(s) from the InputBox of the Serial Monitor of UNO and click on the Send button; observe that the character (s) has appeared on the OutputBox of the NodeMCU's Serial Monitor.

uartesp-2.png

You might want to touch your finger to the ESP. The idle state for TTY async is (usually) HIGH.

I read that for many people ESP works fine and without a divider on 5v. But is it safe? I plan to move the ESP to an inaccessible place and not to approach it at all. For me, the reliability of the device is important. If there are any risks, would you recommend a good voltage divider circuit? As I understand it, this is not very good with resistors.