UART Communication between two NodeMCU

Hello Everyone!

I'm attempting to establish UART communication between two NodeMCUs. I have connected the RX and TX pins of the first NodeMCU to the TX and RX pins of the second NodeMCU respectively.

Sender code:

void setup() {
  Serial.begin(9600); // Initialize serial communication
}

void loop() {
  // Read input from serial monitor
  if (Serial.available()) {
    char data = Serial.read();
    if (data == '0' || data == '1') { // Check if received data is '0' or '1'
      Serial.println("Sending command: " + String(data));
      Serial1.write(data); // Send data to receiver
    }
  }
  delay(100); // Small delay
}

The Serial monitor output works fine for the sender. which is bellowed:

But the problem is in the output of the receiver side Serial Monitor. The code for the receiver is:

const int ledPin = 13; // Define the pin connected to the LED

void setup() {
  Serial1.begin(9600); // Initialize serial communication
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
}

void loop() {
  if (Serial1.available()) {
    char data = Serial1.read(); // Read data from sender
    if (data == '0') {
      digitalWrite(ledPin, LOW); // Turn off LED
      Serial1.println("LED OFF");
    } else if (data == '1') {
      digitalWrite(ledPin, HIGH); // Turn on LED
      Serial1.println("LED ON");
    }
  }
  delay(100); // Small delay
}

And the output I received consists only of '1' and '0'. I'm unsure why it doesn't trigger the if-else conditions when it receives '0' or '1' respectively, and it fails to display the corresponding output in the serial monitor. Below is the output from the serial monitor on the receiver side:

Could someone please guide me to sort out this problem?

Thank you!
Ali

which Rx and Tx pins? are you attempting to use the same pins as the serial monitor uses?

are you using ESP32 or ESP8266 devices?
if ESP32 use hardware serial ports Serial1 or Serial2
if ESP8266 use EspSoftwareSerial

Thank you, Horace, for your prompt response.

I'm using an ESP8266 and have connected the same pins for RX and TX as those used by the serial monitor. However, I'm still not getting the expected results. Could you please provide further explanation? I'm a bit confused by the results I'm seeing, but I trust your guidance will help clarify things for me.

You cannot use those pins because they are used for serial monitor. They cannot perform both functions at the same time.

You cannot change which pins are used for serial monitor, so you must change which pins are used for Comms with the other ESP.

I would like to ask the question: why are you attempting this? Why do the ESP8266 need to communicate?

as @PaulRB states you cannot use the same pins as the serial monitor

using the library manager install EspSoftwareSerial and try the following program on both ESP8266 devices

// ESP8266 Software Serial test

// using library manager download and instal EspSoftwareSerial or instal ZIP
// https://github.com/plerup/espsoftwareserial

#include <SoftwareSerial.h>

// pins Rx GPIO14 (D5) and Tx GPIO 12 (D6) 
 SoftwareSerial swSer(14, 12);  

 // for loopback test connect pin D5 to pin D6

// for RS232 shield connect
// ESP8266 pin D6 TXD to TTL/RS232 Tx
// ESP8266 pin D5 RXD to TTL/RS232 Rx
// for loopback test connect 9-pin D_type connector pins 2 Tx to 3 Rx (pin 5 is GND)
// connect GND pins together and VCC to 5V

void setup() {
  Serial.begin(115200);   //Initialize hardware serial with baudrate of 115200
  swSer.begin(9600);      //Initialize software serial with baudrate of 9600
  Serial.println("\nESP8266 Software serial test started");
  Serial.println("-  for loopback test connect pin D5 to pin D6\n");
 }

void loop() {
  while (swSer.available() > 0) {  //wait for data at software serial
    Serial.write(swSer.read()); //Send data recived from software serial to hardware serial    
  }
  while (Serial.available() > 0) { //wait for data at hardware serial
    swSer.write(Serial.read());     //send data recived from hardware serial to software serial
  }
}

cross connect D5 and D6 on the two ESP8266 devices, e.g. D5 on first device to D6 on the other
text entered on serial monitor of one device should appear on the serial monitor of the other

Thank you, @horace and @PaulRB , for your invaluable guidance. With your help, I've finally found the solution. I now realize that I cannot use the same pins for communication as those used by the serial monitor.

ESP8266 does have a second hardware serial port called Serial1. That is why your code did not give an error. But the second hardware serial port on ESP8266 has limited use. It can transmit but it cannot receive (it's receive pin is used for another function). So, on ESP8266, Serial1.available() will not work.

Here is the Solution:

Hardware connections:
NodeMCU-01 ----> NodeMCU-02
RX(D5) -------------->TX(D6)
TX(D6) --------------> RX(D5)

Code for Sender:

#include <SoftwareSerial.h>

// Define the software serial pins for the sender
#define SENDER_RX_PIN 12 // D6
#define SENDER_TX_PIN 14 // D5

// Create a SoftwareSerial object for the sender
SoftwareSerial senderSerial(SENDER_RX_PIN, SENDER_TX_PIN);

void setup() {
  Serial.begin(9600); // Initialize hardware serial communication
  senderSerial.begin(9600); // Initialize software serial communication
  Serial.println("Sender is ready.");
}

void loop() {
  // Read input from serial monitor
  if (Serial.available() > 0) {
    char data = Serial.read();
    if (data == '0' || data == '1') { // Check if received data is '0' or '1'
      Serial.println("Sending command: " + String(data));
      senderSerial.write(data); // Send data to receiver
    }
  }
  delay(100); // Small delay
}

Code for Reciever:

#include <SoftwareSerial.h>

// Define the software serial pins for the receiver
#define RECEIVER_RX_PIN 12 // D6
#define RECEIVER_TX_PIN 14 // D5

// Create a SoftwareSerial object for the receiver
SoftwareSerial receiverSerial(RECEIVER_RX_PIN, RECEIVER_TX_PIN);

const int ledPin = 4; // Define the pin connected to the LED

void setup() {
  Serial.begin(9600); // Initialize hardware serial communication
  receiverSerial.begin(9600); // Initialize software serial communication
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
}

void loop() {
  if (receiverSerial.available() > 0) {
    char data = receiverSerial.read(); // Read data from sender
    if (data == '0') {
      digitalWrite(ledPin, LOW); // Turn off LED
      Serial.println("LED OFF");
    } else if (data == '1') {
      digitalWrite(ledPin, HIGH); // Turn on LED
      Serial.println("LED ON");
    }
  }
  delay(100); // Small delay
}

Congratulations for getting the code working.

Can you please answer my question?

This is just an academic task for me I've had to build UART communication between two NodeMCUs and now with the help of you guys, I got the solution.