Problems with serial communication between ESP32 with Arduino Mega


I set up hardware and software to communicate between an Arduino Mega and an ESP32. I am using the Arduino to read temperatures from a max6675 thermocouple and then want to send the temperature data to the ESP32 from where I want to read in the data.

At the moment I have managed to write the temperature however I cannot manage to read the data. I have tried baud rates of both 9600 and 115200 and have used both sets of RX/TX pins on the ESP32 (1/3 and 16/17) however at best the serial monitor displays -1. Which I realize means that the data is not available. I have attached the code for both the Arduino Mega and ESP32.

Kind Regards

Arduino Mega.JPG


My guess is that you connected the ESP32, a 3.3V device, directly to the MEGA, a 5.0V device? If you have, get a new ESP32 and do some research into “Level Shifters”.

Next, after auto formatting your code, post it here between code tags.

I’ve not looked at those image files.

The ESP32 has 3 serial ports that you can use, the ports are: (0), (1), (2).

Unless you really know what is going on you should NOT use serial port (0), GPIO1 and GPIO3. The programing port that the Arduino IDE is going to use to send and receive data.

That leaves (1) and (2). (2) is the easy one to use on GPIO17 (TXD), and GPIO16 (RXD).

You will need to have declared: #include <HardwareSerial.h>.

To use (2) you will need to have instantiated a port; like this: HardwareSerial LIDARSerial ( 2 );.

Here is a serial receive concept that I have used for the UNO, Mega, Mini-Pro, Due, STM32 Bluepill, and ESP32:

void fReceiveSerial_LIDAR( void * parameters  )
  bool BeginSentence = false; // used to determine that the beginning of a sentence has been received and to prevent the begin process of a sentence in the middle of the sentence
  sSerial.reserve ( StringBufferSize300 ); // this is the String buffer to hold the received sentence
  char OneChar; // this is to hold the received character
  for ( ;; ) // this loop runs forever
    EventBits_t xbit = xEventGroupWaitBits (eg, evtReceiveSerial_LIDAR, pdTRUE, pdTRUE, portMAX_DELAY); // this causes a wait till an event trigger
    // vTaskDelayUntil( &xLastWakeTime, xFrequency ); // not used here
    if ( LIDARSerial.available() >= 1 ) //The DUE, STM32 and ESP32 work better if there is at least a full byte in the receive buffer.
      while ( LIDARSerial.available() ) // as long as there is something to receive the receive loop will run
        OneChar =;
        if ( BeginSentence )
          if ( OneChar == '>') // the end of a sentence
            if ( xSemaphoreTake( sema_ParseLIDAR_ReceivedSerial, xSemaphoreTicksToWait10 ) == pdTRUE ) // take a semaphore
              xQueueOverwrite( xQ_LIDAR_Display_INFO, ( void * ) &sSerial ); // write the new value to a single queue.
              xEventGroupSetBits( eg, evtParseLIDAR_ReceivedSerial ); // run the parser task on the other core
            BeginSentence = false;
          sSerial.concat ( OneChar );
          if ( OneChar == '<' ) // this is the beginning of a sentence
            sSerial = ""; // clear string buffer
            BeginSentence = true; // found begining of sentence
      } //  while ( LIDARSerial.available() )
    } //if ( LIDARSerial.available() >= 1 )
    xSemaphoreGive( sema_ReceiveSerial_LIDAR );
    //            Serial.print( "fReceiveSerial_LIDAR " );
    //        Serial.print(uxTaskGetStackHighWaterMark( NULL ));
    //            Serial.println();
    //        Serial.flush();
  vTaskDelete( NULL ); // if the for loop is somehow exited then kill this task and regain all its in use assets
} //void fParseSerial( void * parameters  )

The above code is what I use on the ESP32 running freeRTOS. The code commented out near the bottom is used to get a handle on how much ram the code is using so I can set the task proper stack setting. I know that code works up to being ran once every .25uS; faster than that, your on your own.

About serial (1).

The natural pinout on the ESP32 module for serial (1) is GPIO10 and GPIO11. If you do not know how/why do not use GPIO 6, 7, 8, 9, 10, 11. If, during programming the ESP32 any of those pins change state, your programming will fail. Like using a module which just starts spitting stuff out at its power on. That means that to use serial port (1), you will need to, in setup, set the pin matrix; easy to do.

So you’d do the HardwareSerial GPSSerial ( 1 ); thing and in setup you’d define the pin matrix for (1) like so: GPSSerial.begin ( GPS_DataBits, SERIAL_8N1, 2, 15 ); // begin GPS hardware serial

In the above I used GPIO 2 and 15 for rx and tx.

Remember that the GPIO pins 0 to 32 can be inputs and outputs and all the pins above 32 are input only.

Note, The ESP does not have Serial1 or Serial2 or Serial3 or Serial79.

But first, if you connected the ESP directly to the Mega, get a new ESP.

Thanks for the reply.

I connected the ESP32 and the Arduino Mega RX and TX pins and they share common ground. I did not connect the ESP32 to the 5V of the Arduino Mega if that is what you mean?

I have tried initiating the port by using HardwareSerial MySerial(2) before, but unfortunately did not work.
I think my problem might be that I tried to receive the entire string written to the serial as a single character instead of accepting one char at a time if that makes any sense.

Thanks for the code I will try to modify it for my purpose and hopefully it will work.

No what he means is that the Arduino Mega sends out signals at 5V. The ESP32 can only handle 3.3V and setting 5V signals on it might damage the pins.

That's why he said that you should get a new esp32.

It could however be that the pins are not damaged and they still work normally. Even if they pins are broken you might still try some other pins to see if it works.

Yup, what he wrote ^^^^.

The ESP32 is very sensitive to having the Mega or any other device putting more then 3.3V on its GPIO pins. My experience, when that happens, is that the ESP32 is fried.