Serial2 read error but available>0

saibot83
Posts: 4
Joined: Mon Feb 01, 2021 1:04 pm

Serial2 read error but available>0

Postby saibot83 » Wed Mar 31, 2021 8:35 am

Hi there,

I'm using a ESP32 DevKitC with Wroom32 on PlatformIO with Arduino framework.
I used the Uart0 at the beginning of my project, but wanted to separate now USB and RS232.
So I moved my serial protocol handling to Serial2 and was faced with some problems.
After trying and searching for some days, I found the reason for the problem.

The serial2.available() is returning values>0, but directly afterwards (same CPU cycle), the Serial2.read() function fails and retuns -1.
I really do not understand this behaviour, because the read() functions internally also does a call to available() and returns -1 if it is 0. So how can it be different?

The following function is called in every loop() cycle (~1ms):

Code: Select all

void RS232_RECEIVE()
{
    int ReceivedByte;

    int bytesToReceive = Serial2.available();
    int TempAvailable;
    
    if (bytesToReceive > 0) 
    {
        while (Serial2.available() > 0)
        {
            TempAvailable = Serial2.available();

            ReceivedByte = Serial2.read();
            
            if (ReceivedByte > -1)  //-1 if nothing to read
            {
                switch ( ReceivedByte )
                {
                    // find <CR><LF>
                    case 0x0D:  // <CR>
                        //Ignore
                    break;

                    case 0x0A:  // <LF>
                        pSerialStream = &ucRxData[0];
                        ucSerialSize  = ucRxDataIdx;

                        ParseReceivedString();

                        // reset Index
                        ucRxDataIdx = 0;
                    break;

                    default:
                        ucRxData[ucRxDataIdx] = (uint8_t) ReceivedByte;
                        ucRxDataIdx++;
                    break;
                }
            }
            else
            {
                Serial.printf("Serial2.available() == %d\n", TempAvailable);
                Serial.println("Serial2.read() == -1");
            }
        }
    }
}
After some minutes with RS232 communication, I get this Debug output on Serial Terminal:

Serial2.available() == 1
Serial2.read() == -1
Serial2.available() == 2
Serial2.read() == -1
Serial2.available() == 2
Serial2.read() == -1
Serial2.available() == 2
Serial2.read() == -1
Serial2.available() == 3
Serial2.read() == -1
Serial2.available() == 2
Serial2.read() == -1
Serial2.available() == 3
Serial2.read() == -1


Does anyone have an idea, how this is possible?
Why is Serial2.read() returning -1 while Serial2.available is not 0?

shuptuu
Posts: 4
Joined: Thu Sep 30, 2021 2:02 pm

Re: Serial2 read error but available>0

Postby shuptuu » Thu Sep 30, 2021 2:44 pm

Hi,
I confirm: After long long long investigations, I arrived to the same conclusion.
Serial2.available() sometimes returns wrongly values>0, so with no data available.
I'm using Serial2 between 2 esp32.
I also have the case when Serial2.available() returns values>0 and the next Serial2.read() returns 255, which is a value I'm not sending.
Still searching for the solution too. I thought it could come from parasites on the line. I tried to add pull up resistors, but it doesn't change anything. (my 2 esps are on the same board with only maybe 2cm between them. You can't really do closer!)
In my case, I'm doing a bidirectionnal communication between the 2 esps: the master sends a question to the slave and then waits for the answer. I discovered this problem cause I was receiving bad answers sometimes...
A workaround I found: double check for Serial2.available().
But Serial2 is not reliable and that's a problem.
Could somebody find a real fix for that?

christophe de poly
Posts: 1
Joined: Fri Nov 22, 2024 6:36 am

Re: Serial2 read error but available>0

Postby christophe de poly » Fri Nov 22, 2024 7:30 am

Hello,

I am facing the same issue with a WT32-SC01 Plus board (ESP32s3) . Serial2.available is always >0 but read() generates an error.

The issue is that the read() function is designed in such a way that when it returns false (-1) you cannot distinguish that from a legitimate 0xFF :

int HardwareSerial::read(void)
{
uint8_t c = 0;
if (uartReadBytes(_uart, &c, 1, 0) == 1) {
return c;
} else {
return -1;
}
}

To solve this issue, I ended up creating a new function in HardwareSerial with a uint8_T parameter read(uint8_t *c) so that the function
returning true of false to filter out the false reading. On true, you know that c contains valid data :

bool HardwareSerial::read(uint8_t* c){
if (uartReadBytes(_uart, c, 1, 0) == 1) {
return true;
} else {
return false;
}
}

You can replace available() by this read(uint8_T *c) function and use c when it returns true :
while (read(uint8_t *c)){
xyz = c
}

Who is online

Users browsing this forum: No registered users and 40 guests