espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.3k stars 7.35k forks source link

String object's remove() function is only called once when firstly call of onRecieve() UART Interrupt #10166

Open skyswordx opened 3 weeks ago

skyswordx commented 3 weeks ago

Board

ESP32wroom

Device Description

Devkit

Hardware Configuration

arduino frame default Serial

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

WSL2

Flash frequency

40MHz

PSRAM enabled

yes

Upload speed

115200

Description

In serial communication, within the serial interrupt where the onReceive method is set, the remove() method of the String object inside this interrupt function is only called the first time the interrupt function is triggered (that is, the first time data is received on this serial port).

In this serial communication, the remove method of the String object can only be used once, unless the USB-to-TTL module and the serial port connection are disconnected. However, even after disconnecting and reconnecting, the same issue will occur again.

However, it seems that manually clearing the String object with the clear method after each use may resolve the issue.

Sketch

OnReceiveCb call_back(){
  String receivedData = Serial.readStringUntil('!'); // Read the data until '!' is encountered
  Serial.println(receivedData);// oooo

  receivedData.remove(0,1); // Remove the '#' character from the beginning

  Serial.println("removed receivedData first item: #");// oooo
  Serial.println(receivedData);  // oooo
  // receivedData.clear(); // oooo

}

Debug Message

uart messages are below:
------------------------
#P0=500.000
removed receivedData first item: #
#P0=500.000

Other Steps to Reproduce

No response

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

me-no-dev commented 3 weeks ago

Here are my results:

void setup() {
  Serial.begin(115200);
  delay(2000);

  String receivedData = "#P0=500.000";
  Serial.println(receivedData);
  receivedData.remove(0,1);
  Serial.println("removed receivedData first item: #");
  Serial.println(receivedData);

}

void loop() {
  // put your main code here, to run repeatedly:
}

Output:

#P0=500.000
removed receivedData first item: #
P0=500.000

I'm guessing that the string starts with invisible char, like \r and that is what you are actually removing, so # stays as second char.