Arduino Nano ESP32 - Serial Communication fundemental issue

Hello everyone,

This is a quite basic question that has challenged me so far. I read the Nano ESP32 documentation and also posts related to that in this forum; But nothing led to an answer (solution) for me.

I am trying migrate from Arduino UNO to Nano, and a piece of the firmware, which is the serial communication, is not working. Simply explanation: I have a CO2 Data logger and I am trying to send a command to it to read it's values. ( It works perfectly with Arduino UNO)

Here is the simplified code : ( IT accepts two pins for Tx, Rx and then configure them in setup, and then send communication function send the command to device and tries to read values from it.) (this code with the usage of softwareSerial.h is working with no issue on UNO)



// Define software serial pins
const byte SOFT_RX = 44;  // RX on Arduino to TX on device
const byte SOFT_TX = 43;  // TX on Arduino to RX on device



bool checkConnection() {
    const char* testCommand = "I\r";
    Serial1.print(testCommand);

    delay(1000);

    if (Serial1.available()) {
        while (Serial1.available()) {
            Serial1.read();
        }
        Serial.println("Connection check successful.");
        return true;
    } else {
        Serial.println("Connection check failed.");
        return false;
    }
}

// commands : D, I, M
void sendCommand(const char* command) {
    Serial.print("Sending command: ");
    Serial.println(command);

    int attempts = 0;
    const int maxAttempts = 10;
    bool receivedResponse = false;

    while (attempts < maxAttempts && !receivedResponse) {
        // Clear any previous data
        while (Serial1.available()) {
            Serial1.read();
        }

        delay(50 + attempts);  // Small delay before sending command + change the frequency

        Serial1.print(command);

        delay(1500);  // Wait for response

        // Read and print the response
        String response = "";
        while (Serial1.available()) {
            char incomingByte = Serial1.read();
            response += incomingByte;
            Serial.print("Received byte: ");
            Serial.println(incomingByte, HEX);
        }

        if (response.length() > 0) {
            receivedResponse = true;
            Serial.print("Response for command ");
            Serial.print(command);
            Serial.println(":");
            Serial.println(response);
            Serial.print("Response for command ");
            Serial.print(command);
            Serial.println(":");
              for (int i = 0; i < response.length(); i++) {
              Serial.print("0x");
              Serial.print(response[i], HEX);  // Print each character in hex
              Serial.print(" ");  // Add space for readability
            }
            Serial.println();  // Move to the next line after printing all characters

        } else {
            Serial.println("No response received, retrying...");
            attempts++;
        }
    }

    if (!receivedResponse) {
        Serial.println("Failed to receive a response after 10 attempts.");
    }
}



void setup() {
    Serial.begin(9600);
    Serial1.begin(9600, SERIAL_8N1, SOFT_RX, SOFT_TX);
    while (!Serial) {
        ; // Wait for serial port to connect
    }

    delay(2000);


    Serial.println("Enter commands to send to the device:");
}

void loop() {
    if (Serial.available()) {
        String command = Serial.readStringUntil('\n');  // Read the command from the Serial Monitor
        command.trim();  // Remove any leading/trailing whitespace
        command += "\r";  // Add carriage return to the command

        delay(50);  // Small delay before sending command

        sendCommand(command.c_str());  // Send the command

        delay(50);  // Small delay after sending command
    }
}

For the

const byte SOFT_RX = 44;  // RX on Arduino to TX on device
const byte SOFT_TX = 43;  // TX on Arduino to RX on device

part, I've already tried other pins such as 5, 6 (D2, D3) - 0,1 - 1,2 - etc. But I guess that I am doing something wrong more that pin specification.

ALSO, I've notice that this Arduino has voltage of 3.3v on its pins, and since UNO has 5v, can it be the reason? The SERIAL wire from the device as Tx, Rx, and GND.

Thanks in advance for your help :slight_smile:

The Nano ESP32 is a powerful microcontroller board that combines the compact form factor of the Arduino Nano with the advanced capabilities of the ESP32 chip. For serial communication, you have several options:

1. Hardware Serial Ports

The ESP32 chip has multiple hardware serial ports (UARTs). The Nano ESP32 typically exposes two of them:

  • Serial: This is connected to the USB-to-serial converter and is used for uploading code and serial communication with the host computer. It's commonly used for debugging.
  • Serial1: This is available for use with external devices.

Example for using Serial1:

void setup() {
  // Initialize the default serial port (Serial) for debugging
  Serial.begin(115200);

  // Initialize Serial1 for communication with external devices
  Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); // Replace RX_PIN and TX_PIN with the pins you're using
}

void loop() {
  // Send data to Serial1
  Serial1.println("Hello, Serial1!");

  // Check for incoming data on Serial1 and print it to the default Serial
  if (Serial1.available()) {
    String data = Serial1.readString();
    Serial.println("Received on Serial1: " + data);
  }
}

2. Software Serial

If you need additional serial ports beyond what the hardware provides, you can use the SoftwareSerial library, but be aware that it's less efficient and not always reliable at higher baud rates.

Note: The SoftwareSerial library is not native to the ESP32 platform, so you might need to use alternative libraries like ESP32SoftwareSerial.

3. Serial Communication Settings

  • Baud Rate: You can set different baud rates for different serial ports. The default baud rate is usually 115200, but you can change it as needed.
  • Serial Monitor: When using the Arduino IDE, ensure that the baud rate in the Serial Monitor matches the baud rate set in your code.

4. Common Use Cases

  • Debugging: Use the primary Serial for printing debug information to the Serial Monitor.
  • External Devices: Use Serial1 or additional hardware/software serial ports to communicate with other devices like sensors, GPS modules, or other microcontrollers.

5. Pin Configuration

  • Check the specific pinout of your Nano ESP32 board to identify which pins are assigned to the UARTs. You can usually find this information in the board documentation or by looking up the board's schematic.

If you have a specific use case or issue related to serial communication on the Nano ESP32, feel free to share more details, and I can provide a more tailored solution!

This is false. Serial is the USB CDC serial port. The Nano ESP32 doesn't have a USB-to-serial converter. Its ESP32-S3 microcontroller has native USB capabilities so it is connected directly to the USB socket on the board.

1 Like

his reply looks like ChatGPT output to be honest

The "CO2 datalogger" - is it a 5V device?
The NanoESP32 is 3V.
Maybe that's a 'thing' ?

Hello @runaway_pancake . As I checked CO2 datalogger works with 3.3 V too and that's interesting that Arduino Uno can read the value with different voltages easily and accurately.
Anyway as I was reading through the different posts here in the forum, I saw this: you answer to someone I would like to know if #include <HardwareSerial.h> has solved your problem there or you could achieve the communication without it too?

Thanks for your reply and help

I posted that, a couple of years ago - because it worked.
There may have been an update to the core making that unnecessary (?) I thought I had maybe read.
Anyway - did you try it ?

I'm certain that this worked too --

//  ESP32dfmini01
//
//#include "Arduino.h"
#include "HardwareSerial.h"
#include "DFRobotDFPlayerMini.h"

//
const byte RXD2 = 16;
const byte TXD2 = 17; 

HardwareSerial dfSD(1); // Use UART channel 1
DFRobotDFPlayerMini player;
   
void setup() 
{
  Serial.begin(19200);
  dfSD.begin(9600, SERIAL_8N1, RXD2, TXD2);  // 16,17
  delay(5000);

  if (player.begin(dfSD)) 
  {
    Serial.println("OK");

    // Set volume to maximum (0 to 30).
    player.volume(17); //30 is very loud
  } 
  else 
  {
    Serial.println("Connecting to DFPlayer Mini failed!");
  }
}

void loop() 
{
  Serial.println("Playing #1");
  player.play(1);
  Serial.println("play start");
  delay(5000);
  Serial.println("played");
  delay(1000);

  Serial.println("Playing #2");
  player.play(2);
  Serial.println("play start");
  delay(10000);
  Serial.println("played");
  delay(1000);
}
1 Like

ESP32 UART Hardware Serial Ports Help - Using Arduino / Programming Questions - Arduino Forum

See posts 44, 46

And - I'll throw in --
Nano ESP32 and Serials - Nano Family / Nano ESP32 - Arduino Forum

@babak-abdzadeh the Nano ESP32 does not have (D)44 or (D)43 but it does have GPIO44 and GPIO43 which equate to (D)0 and (D)1 respectively which is Serial0.

The Nano ESP32 cheat sheet suggests you may not want to use Serial0, further reading here https://docs.arduino.cc/tutorials/nano-esp32/cheat-sheet/#usb-serial--uart

In my opinion @runaway_pancake Hardware Serial example in post #8 would be a good one to work with try assigning your pins like the following

// Define software serial pins
const byte SOFT_RX =  2;  // RX  to TX on device
const byte SOFT_TX =  3;  // TX   to RX on device

BTW you can choose an alternate way in which the pins are numbered from Arduino pin to GPIO pin, this is selected under tools on the menu

1 Like
1 Like

With Hardware h

#include "HardwareSerial.h"

const byte RXD2 = 2;
const byte TXD2 = 3; 

HardwareSerial SerialPort(1); // Use UART channel 1

void setup() 
{
  Serial.begin(9600);
  Serial1.begin(9600, SERIAL_8N1, RXD2, TXD2);  // 2,3
}

Without Hardware h

const byte RXD2 = 2;
const byte TXD2 = 3; 

void setup() 
{
  Serial.begin(9600);
  Serial1.begin(9600, SERIAL_8N1, RXD2, TXD2);  // 2,3
}

Yes both of the above examples work providing you use the correct pin numbering from the Tools menu, I chose D2 and D3 using Arduino numbering which is the default but if it is inconvenient to use pins 2 & 3 it's ok to select two different pins, as said it is not advised to use pins 0 & 1

1 Like

Very interesting that it is working only with "HardwareSerial.h" !
Thanks for your help