Skip to content

Serial1 not working with 3.1.2 and 3.1.3 #11076

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

Closed
1 task done
ricardourio opened this issue Mar 12, 2025 · 11 comments
Closed
1 task done

Serial1 not working with 3.1.2 and 3.1.3 #11076

ricardourio opened this issue Mar 12, 2025 · 11 comments
Assignees

Comments

@ricardourio
Copy link

ricardourio commented Mar 12, 2025

Image

Board

ESP32-WROOM-32E

Device Description

It´s a development board using ESP32-WROOM-32E with 01 relay

Hardware Configuration

GPIO 32 and 33 are connected to a distance sensor (TOF) XKC-KL200 with serial output.

Version

latest master (checkout manually)

IDE Name

Arduino IDE

Operating System

Windows 11

Flash frequency

40 MHz

PSRAM enabled

no

Upload speed

1152000

Description

Compiling with 3.1.1 it works fine, but with 3.1.2 and 3.1.3 doesn´t give me any serial output at monitor. When running with WTD, I got a reset related to Core 0 WTD, that is running the serial1 reading instructions. The code doesn´t has a break from serial1 reading loop if no read, but works fine with sensor, unless version is 3.1.2 or greater.

Sketch

unsigned int distancia = 0;
bool Distancia_Lida = false;

int ContaRX;
byte dadosRX[10];

void setup() {
  Serial.begin(115200);
}

byte XORChecksum8(const byte *data) {
  byte value = 0;
  for (byte i = 1; i < 9; i++) {
    value ^= data[i];
  }
  return value;
}

void LeDistancia() { //ToDo : break if no reading

  Distancia_Lida = false;
  ContaRX = 0;
  Serial1.end();
  Serial1.begin(9600, SERIAL_8N1, 33, 32);

  while (Distancia_Lida == false) {
    if (Serial1.available()) {
      byte inByte = Serial1.read();

      if (ContaRX > 0) {
        ContaRX++;
        dadosRX[ContaRX] = inByte;

        if ((ContaRX == 2) && (dadosRX[2] != 51)) {
          ContaRX = 0;
          Serial1.flush();
        }

        if (ContaRX == 9) {
          ContaRX = 0;

          if ((dadosRX[1] == 98) && (dadosRX[2] == 51)) {

            if (XORChecksum8(dadosRX) == dadosRX[9]) {
              distancia = dadosRX[6] << 8;
              distancia |= dadosRX[7];
              distancia = distancia / 10;
              ContaRX = 0;
              Distancia_Lida = true;
              Serial1.end();
              break;
            }
          }
        }
      }

      if (inByte == 98) {  
        dadosRX[1] = inByte;
        ContaRX = 1;
        distancia = 0;
      }
    }
  }
}

void loop() {
  verificarPresenca();

  for (int i = 0; i < 10; i++) {
    delay(1);
  }
}

void verificarPresenca() {

  LeDistancia();

  Serial.print("D = ");
  Serial.println(distancia);

  Serial.println(F(" "));
}

Debug Message

No output

Other Steps to Reproduce

Communication output from sensor can be reproduced sending a message like the picture, every 100ms at 9600 8n1

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@ricardourio ricardourio added the Status: Awaiting triage Issue is waiting for triage label Mar 12, 2025
@ricardourio
Copy link
Author

I made some more tests with oscilloscope and could see that with 3.1.2 and 3.1.3 the RX signal from sensor is dead, like a pull-down, even I set it to input in the Setup section. With version 3.1.1 the RX signal is what the picture above shows.

@SuGlider
Copy link
Collaborator

This is interesting. We have noticed some sort of issue moving from 3.1.1 to 3.1.2.
It seems to be related to some IDF change. It needs more investigation.

@SuGlider SuGlider added Peripheral: UART Status: Needs investigation We need to do some research before taking next steps on this issue and removed Status: Awaiting triage Issue is waiting for triage labels Mar 13, 2025
@Jason2866
Copy link
Collaborator

Is the needed 1k pull up resistor installed?

Image

@SuGlider SuGlider removed the Status: Needs investigation We need to do some research before taking next steps on this issue label Mar 13, 2025
@SuGlider
Copy link
Collaborator

@ricardourio - I have tested this sketch using an ESP32 devkit board and a USB-UART CH340 board to connect to pins 32 and 33.
It works as suposed using Arduino Core 3.1.3.

There were a few changes in IDF 5.4 and 5.3 that seem to have changed the way how UART internal pull ups are set.
That was done to allow UART to use the same pin for RX and TX.

Therefore, as @Jason2866 pointed out, it seems to be related to lack of PULL UP in the RX Line.
You may try to add the 1K ohm resistor as shown in the diagram above in order to make sure that the UART line is pulled up correctly.

@Jason2866
Copy link
Collaborator

Closing since not reproducable. Hardware setup issue.

@ricardourio
Copy link
Author

Adding pinMode(33, INPUT_PULLUP) in the Setup section solved the issue, what probably 3.1.1 did before.

@SuGlider
Copy link
Collaborator

Adding pinMode(33, INPUT_PULLUP) in the Setup section solved the issue, what probably 3.1.1 did before.

Thanks for the feedback!
Yes, newer IDF version has changed to do not set the internal pull-up.
This was done to allow a single pin to be used as RX and TX in a high impedance mode.

pinMode(pin, INPUT_PULLUP) will, indeed, activate the internal pullup of that GPIO.
I'll discuss it internally to check if we should add it to the Arduino Core code to make sure that the RX pin has activated its pull-up.

@Jason2866
Copy link
Collaborator

Honestly imho it is better as it is now. The internal pull up is very high (weak). By enabling it hides wrong hardware designs. Faster speeds longer wires (traces) will result in poor (ugly) signals. This is way more harder to find as when it just does not work completely.
The fact of not working made me think of the hardware part. And this was right. The pull up was missing. From hardware design aspect for this setup, only enabling the intern pull up is not really a solution. It is way out of the recommended set up and is just luck it works. For sure it is not reliable.

@ricardourio
Copy link
Author

Jason2866, I'm working 28 years with electronics and I very rarely saw a pratical device working with active high RX, so for me automatic pull up makes more sense, and disabling it as an option. Maybe the resistor could have a important place when using long distance or high interference fields, but the picture only indicates that the sensor has no pull up circuit internally, and it need to be provided at processor side, what an ESP32 can do internally. The 1k resistor is a guarantee for interferences, but it depends on your ambient and impedances of your circuit. For now, I have more then 1000 devices sold, that I didn't need to install a resistor, working only with pull up, and as you can see in the picture, the impedance of signal is high enough to pull up handle it, as it can reach 3.3v and has a square wave appearance.

@Jason2866
Copy link
Collaborator

My lesson learned in hardware and software development, never assume something.
This is based on electronic hardware experience of over 40 years.

@SuGlider
Copy link
Collaborator

Good discussion and arguments. Thank you both for bringing it. I'll talk about it to the Arduino team.
@me-no-dev - FYI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants