Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HardwareSerial freezing ESP32 #3563

Closed
maribeiro opened this issue Dec 12, 2019 · 17 comments
Closed

HardwareSerial freezing ESP32 #3563

maribeiro opened this issue Dec 12, 2019 · 17 comments
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@maribeiro
Copy link

Hardware:

Board: ESP32 Custom board
Core Installation version: 1.11.1
IDE name: Platform.io
Flash Frequency: default
PSRAM enabled: default
Upload Speed: 115200
Computer OS: Linux

Description:

I'm using a board with ESP32 and a gps device (GPS TX) connected to ESP32 GPIO_NUM_16.
My basic sketch starts Serial2 with a specific baud rate for communicating with the GPS and reads the serial2 port , printing incoming data and then ends the serial communication. Then the cycle repeats (this is because i then want to use the same Serial Port to communicate with another device)
What happens is that after a random time the ESP just freezes. No more incoming data, if i put some other debug print inside the loop, it just doesnt get printed anymore.

The device doesnt throw any exception, it just freezes completely.

Sketch:

//Change the code below by your sketch
#include "Arduino.h"

void setup()
{
  Serial.begin(115200);
  Serial.println("Starting...");
}

void printFromSerial()
{
  unsigned long start = millis();
  do
  {
    while (Serial2.available()) {
      int r = Serial2.read();
      Serial.print(r);
    }
  } while (millis() - start < 1000);
}

void loop()
{
   Serial2.begin(9600, SERIAL_8N1, GPIO_NUM_16, GPIO_NUM_12, false);
   printFromSerial();
   Serial2.end();
}

Debug Messages:

no messages show , device just freezes.
@Jeroen88
Copy link
Contributor

Maybe you can try to work around by removing Serial2.end() and moving Serial2.begin(...) to setup()

@maribeiro
Copy link
Author

Maybe you can try to work around by removing Serial2.end() and moving Serial2.begin(...) to setup()

But like i said, i need to be able to communicate with one device and then switch to second device using a mux. I am able to communicate with both devices by ending the Serial port (Serial2.end()) and starting again with a new baud rate and pin configuration. The problem is, it doesn't work reliably because of some issue with HardwareSerial.
I showed that simple sketch to demonstrate that by starting and closing the serial port several times freezes the esp32.

@stickbreaker
Copy link
Contributor

@maribeiro

  • try setting Core Debug Level to DEBUG and see what error messages are output on Serial().
  • try waiting until the tx data has exited the hardware
void loop()
{
   Serial2.begin(9600, SERIAL_8N1, GPIO_NUM_16, GPIO_NUM_12, false);
   printFromSerial();
   Serial2.flush(true); // wait until all data has exited the UART 
   Serial2.end();
}

Chuck.

@Jeroen88
Copy link
Contributor

@maribeiro if you indeed need to reuse the serial port the work around of moving begin() to setup() isn't an option indeed. If I recall correctly I came across the same problem long time ago. Now I use Serial1 for one device and Serial2 for the other, without calling begin() in the loop.

@maribeiro
Copy link
Author

Serial2.flush didn't solve problem.
I did managed to work around it by using Serial2.updateBaudRate(new baud rate), instead of ending and starting serial each time.
Did works in this specific case because I use a mux and so the TX/RX pins are the same for the two devices I want to communicate with. In case the TX/RX pins are different, things wont work.
So I guess the problem relies on ending/starting serial communication multiple times.

@lyusupov
Copy link
Contributor

From my experience, the Serial.begin() -> Serial.end() sequence does not work properly on ESP32 since long time ago.
It affects all the UARTs available: Serial, Serial1, Serial2
And the issue is in effect for Cores 1.0.1 -1.0.4 and could be even earlier.

My application is multiplatform - ESP8266, ESP32, CC1310, RPi, STM32,
but the ESP32 Arduino Core is the only one which behaves this way.

For a long term I use a workaround: 1 , 2 , 3 , 4 against that.

I would appreciate if someone with deep ESP32 internals knowledge could take a look into this issue in the Core.

@3s1d
Copy link

3s1d commented Dec 18, 2019

I confirm that end() -> begin() is somehow broken.

In my application I needed to change between 8N1 and 8E1. My solution was to derive a subclass of HardwareSerial in which I added a function which directly manipulates the hardware registers in order to achieved the required protocol change.
Do what ever it takes, but do NOT call .end() followed by .begin() (note: .begin() is internally calling .end() as well.)

Cheers,
Juergen

@stale
Copy link

stale bot commented Feb 16, 2020

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Feb 16, 2020
@stale
Copy link

stale bot commented Mar 1, 2020

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

@enwi
Copy link

enwi commented Jan 24, 2021

This issue is still present on the recent version. What worked for me was to call flush, but having it flush both rx and tx.

Serial1.flush(false);
Serial1.end();

Update: This did not fix the issue

@benfany505
Copy link

i still have the problem, communication stop after a while, anyone fixed it ?

@scottp
Copy link

scottp commented Sep 16, 2021

This problem definitely still exists. But I have worked out a scenario when it does. It is while it is receing data.
I have a AVR outputting a lot of Serial data in bursts. If Serial.begin (or in my case I use Serial1 or Serial2) hits the small gap, it works fine, but if it hits begin while data is coming in - ESP32 freeses at that point. Which means it needs many reboots to work.

There is so many web sites, discussions and reports of this issue, it needs to be opened again.

@TD-er
Copy link
Contributor

TD-er commented Oct 13, 2021

@scottp This may indeed be exactly what is happening on my nodes.
One work-around I use here is to assign the pins to another HW serial and then swap it back.
But this can only be done if you have one of the HW serial ports free.

@Paulie92
Copy link

@TD-er can you please describe, how it works with the "swap back". Because even if I successfully start the Serial2.begin with 9600 baudrate and then I use another Serial2.begin command with 115200 baudrate it also freezes time to time (probably depanding if the incoming data are currently presented in the time of calling Serial2.begin - I use the UART2 for GPS) So If I use Serial2.begin with the different pins and after succesfull start I will swap it to the desired pins (16 and 17), there will be the same rist of freeze in the time of swapping pins.

@TD-er
Copy link
Contributor

TD-er commented Nov 15, 2021

What I did was to assign those pins to another serial port, not assign other pins to the same port.

  • Serial1: begin with pinX, pinY
  • Serial2: begin with pinX, pinY
  • Serial1: begin with pinX, pinY

@DriekdeGadgetfreak
Copy link

Here is the fix:.
In uartBegin the output buffer is flushed:
uartFlush(uart);
Change this to
uartFlushTxOnly(uart,false); // also flush the input buffer:

@isparkes
Copy link

isparkes commented May 2, 2022

Here is the fix:. In uartBegin the output buffer is flushed: uartFlush(uart); Change this to uartFlushTxOnly(uart,false); // also flush the input buffer:

Confirmed: that fixed it for me. My scenario, I have a constant stream of serial data coming in, the UART intialisation was hanging on ESP32 reboot.

Couldn't "uartFlushTxOnly(uart,false);" be the default startup code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests