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

Very high error rate with 115200 receive on ESP32 #326

Open
Frogmore42 opened this issue Nov 17, 2024 · 1 comment
Open

Very high error rate with 115200 receive on ESP32 #326

Frogmore42 opened this issue Nov 17, 2024 · 1 comment

Comments

@Frogmore42
Copy link

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?

@Frogmore42
Copy link
Author

Using PlatformIO and an M5 Stack Atom (which is a gen1 ESP32 pico):

[env:m5stack-atom]
platform = espressif32
board = m5stack-atom
framework = arduino
monitor_speed = 115200

; Library options
lib_deps =
    plerup/EspSoftwareSerial@^8.2.0

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

No branches or pull requests

1 participant