Skip to content

Very high error rate with 115200 receive on ESP32 #326

@Frogmore42

Description

@Frogmore42

What should I expect to be able to get? The docs seem to imply that 115,200 is reasonable. My real need is for 9-bit serial (this is for an addressing protocol so not a real 9 bits of data). The source of the data runs at 115,200 and is very chatty, so it puts out a lot of data frequently. I was using an esp8266 and reading whole characters in the ISR (which is a really bad idea, but required to get a reasonable error rate). I figured the esp32 with its dual cores would be better able to handle the load.

I wrote a sample program that outputs random data (only 8bits) using the HW UART and reading it with software serial. It works fine if the amount of data is small (under 30bytes) or I reduce the baud rate significantly.

Here is a sample program that demonstrates it:

#include <Arduino.h>
#include <SoftwareSerial.h>

#define BAUD_RATE 115200
#define UART_TX 23
#define UART_RX 33

HardwareSerial sender(1);
EspSoftwareSerial::UART receiver;
int num = 30;
char dataBlock[150];
char recvBlock[150];


void setup()
{
  Serial.begin(115200);
  sender.begin(BAUD_RATE, SERIAL_8N1, -1, UART_TX);
  receiver.begin(BAUD_RATE, EspSoftwareSerial::SWSERIAL_8N1, UART_RX, -1, false, 1000);
  receiver.setTimeout(1000);
}

void generateRandomBytes(char *dataBlock, int blockSize)
{
  for (int i = 0; i < blockSize; i++)
  {
    dataBlock[i] = random(0, 256); // Generate random byte values between 0 and 255
  }
}

void HexDump(void *pData, int numBytes)
{
  int ii;
  int theValue;
  int byteCount;
  uint8_t *pByte;
  char textString[16];
  char asciiDump[24];

  byteCount = 0;
  pByte = (uint8_t *)pData;
  while (numBytes > 0)
  {
    sprintf(textString, "%04X - ", byteCount);
    Serial.print(textString);

    asciiDump[0] = 0;
    for (ii = 0; ii < 16; ii++)
    {
      if (numBytes > 0)
      {
        theValue = *(pByte++);
        sprintf(textString, "%02X ", theValue);
        Serial.print(textString);
        if ((theValue >= 0x20) && (theValue < 0x7f))
        {
          asciiDump[ii % 16] = theValue;
        }
        else
        {
          asciiDump[ii % 16] = '.';
        }

        numBytes--;
      }
      else
      {
        Serial.print("   ");
        asciiDump[ii % 16] = ' ';
      }
    }
    asciiDump[16] = 0;
    Serial.println(asciiDump);
    byteCount += 16;
  }
}

void loop()
{
  int sentBytes;
  int genBytes = random(10, 100);
  int recvBytes;
  bool error = false;
  Serial.println("starting to send something: " + String(genBytes));
  generateRandomBytes(dataBlock, genBytes);

  sentBytes = sender.write(dataBlock, genBytes);
  Serial.println("available: " + String(sender.availableForWrite()) + " sent: " + String(sentBytes));
  while (sender.availableForWrite() < 128)
  {
    delay(100);
  }
  
  Serial.print(".start wait.");
  delay(2000);
  Serial.println(".done wait.");
  recvBytes = receiver.read(recvBlock, sentBytes);
  Serial.println("got : " + String(recvBytes));
  int missing = sentBytes - recvBytes;
  if (missing != 0)
  {
    Serial.println("ERROR missing: " + String(missing) + " got: " + String(recvBytes) + " != send: " + String(sentBytes));
  }
  
  for (int i = 0; i < recvBytes; i++)
  {
    if (recvBlock[i] != dataBlock[i+missing])
    {
      error = true;
    }
  }
  
  if (error)
  {
    Serial.println("sent:");
    HexDump(dataBlock, genBytes);
    Serial.println("got:");
    HexDump(recvBlock, genBytes);
  }
  delay(2000);
}

There is an example of the output:

starting to send something: 99
available: 31 sent: 99
.start wait..done wait.
got : 94
ERROR missing: 5 got: 94 != send: 99
sent:
0000 - E4 9D 24 ED B1 CC E5 50 9F 10 2C C7 9E 2E 86 85 ..$....P..,.....
0010 - 6E 70 E0 1C AF 35 B0 21 9E 1F 4F 96 55 6A 50 B3 np...5.!..O.UjP.
0020 - 7F 1D 5D 1A 47 14 4B D0 EB C6 DC C8 3A AB 09 D3 ..].G.K.....:...
0030 - 27 06 70 56 C9 8B C1 8C 03 BE 83 8C FB F9 39 7C '.pV..........9|
0040 - 4A 36 EA 5A C7 54 E3 ED 29 23 44 8B 67 08 CA 70 J6.Z.T..)#D.g..p
0050 - BE 92 35 EA 5F 9D BB 24 10 6E E9 BA D4 82 FD 52 ..5._..$.n.....R
0060 - 07 14 30                                        ..0
got:
0000 - 52 E5 50 9F 10 2C C7 9E 2E 86 85 6E 70 E0 1C AF R.P..,.....np...
0010 - 35 B0 21 9E 1F 4F 96 55 6A 50 B3 7F 1D 5D 1A 47 5.!..O.UjP...].G
0020 - 14 4B D0 EB C6 DC C8 3A AB 09 D3 27 06 70 56 C9 .K.....:...'.pV.
0030 - 8B C1 8C 03 BE 83 8C FB F9 39 7C 4A 36 EA 5A C7 .........9|J6.Z.
0040 - 54 E3 ED 29 23 44 8B 67 08 CA 70 BE 92 35 EA 5F T..)#D.g..p..5._
0050 - 9D BB 24 10 6E E9 BA D4 82 FD 52 07 14 30 00 00 ..$.n.....R..0..
0060 - 00 00 00                                        ...

It is missing the first 5 and got the 6th one wrong, but then it did quite well, but again near the end it got a byte or two wrong. I am just expecting too much?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions