PaulStoffregen / AltSoftSerial

Software emulated serial using hardware timers for improved compatibility
http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
328 stars 131 forks source link

The last two bytes reappear after flushing #54

Open szotsaki opened 5 years ago

szotsaki commented 5 years ago
  1. Connect two Arduino Nanos in the following way: D9 with D9 and D8 with D8.
  2. Upload a sketch (see below) to the first Arduino which continuously transmits a 10 byte long sequence via SoftwareSerial on 9600 baud.
  3. Upload a sketch to the second Arduino which receives the sequence (with 16 MHz) and prints it. Printing is done on a higher speed to avoid clogging the hardware serial.
  4. Modify RX buffer size to a big enough value (let's say 250). Since the buffer is filling up quicker than I could read it, in this case, I want to drop it in a controlled manner with flushInput() when the size is equal to 228 (an arbitrary value).
  5. The problem is, that after dropping the whole buffer the last two received characters reappear on screen.

Code for the first Arduino which just sends out characters:

#include <SoftwareSerial.h>
SoftwareSerial sSerial(9, 8); // RX, TX

void setup() {
  Serial.begin(38400);
  sSerial.begin(9600);
}

void loop() {
  const uint8_t testArray[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x06, 0x00, 0x0E, 0x37};
  for (size_t i = 0; i < sizeof(testArray); ++i) {
    Serial.print(F("0x"));
    Serial.println(testArray[i], HEX);
    sSerial.write(testArray[i]);
  }
}

Code for the second Arduino which receives characters, prints them out and flushes buffer regularly:

#include <AltSoftSerial.h>
AltSoftSerial altSerial;

void setup() {
  Serial.begin(38400);
  altSerial.begin(9600);
}

void loop() {
  uint8_t c = 0;
  if (altSerial.available() == 228) {
    altSerial.flushInput();
  }

  if (altSerial.available()) {
    Serial.print(altSerial.available()); // Print out buffer state
    c = altSerial.read();
    Serial.print(F(" - 0x"));
    Serial.println(c, HEX);
  }
}

The result after clearing the correctly received sequences:

[2018-12-10 19:03:16.251] 223 - 0xB5
[2018-12-10 19:03:16.251] 224 - 0x62
[2018-12-10 19:03:16.251] 225 - 0x5
[2018-12-10 19:03:16.259] 226 - 0x1
[2018-12-10 19:03:16.259] 226 - 0x2
[2018-12-10 19:03:16.260] 226 - 0x0
[2018-12-10 19:03:16.268] 227 - 0x6
[2018-12-10 19:03:16.268] 1 - 0x0
[2018-12-10 19:03:16.268] 1 - 0x6
[2018-12-10 19:03:16.276] 1 - 0x0
[2018-12-10 19:03:16.276] 1 - 0xE
[2018-12-10 19:03:16.276] 1 - 0x37
[2018-12-10 19:03:17.450] 223 - 0xB5
[2018-12-10 19:03:17.459] 223 - 0x62
[2018-12-10 19:03:17.459] 224 - 0x5
[2018-12-10 19:03:17.459] 225 - 0x1
[2018-12-10 19:03:17.467] 225 - 0x2
[2018-12-10 19:03:17.467] 226 - 0x0
[2018-12-10 19:03:17.467] 226 - 0x6
[2018-12-10 19:03:17.475] 227 - 0x0
[2018-12-10 19:03:17.475] 1 - 0x6
[2018-12-10 19:03:17.475] 1 - 0x0
[2018-12-10 19:03:17.483] 1 - 0xE
[2018-12-10 19:03:17.483] 1 - 0x37
[2018-12-10 19:03:18.683] 1 - 0xE   // Here only the last two repeated bytes are displayed, the correct full sequence is deleted before
[2018-12-10 19:03:18.691] 1 - 0x37
[2018-12-10 19:03:19.890] 1 - 0xE   // Here only the last two repeated bytes are displayed, the correct full sequence is deleted before
[2018-12-10 19:03:19.891] 1 - 0x37
[2018-12-10 19:03:21.097] 1 - 0xE   // Here only the last two repeated bytes are displayed, the correct full sequence is deleted before
[2018-12-10 19:03:21.097] 1 - 0x37
[2018-12-10 19:03:27.117] 226 - 0xB5
[2018-12-10 19:03:27.117] 227 - 0x62
[2018-12-10 19:03:27.126] 227 - 0x5
[2018-12-10 19:03:27.126] 1 - 0x62
[2018-12-10 19:03:27.126] 1 - 0x5
[2018-12-10 19:03:27.134] 1 - 0x1
[2018-12-10 19:03:27.134] 1 - 0x2
[2018-12-10 19:03:27.134] 1 - 0x0

As you can see the last two bytes before flushing reappear after flushing.

I tried to put the flushInput() function into an ATOMIC_BLOCK, but unfortunately it didn't work, the problem lies in an other place.

What I additionally observed if with this 10-byte-long sequence I use a flushing constant divisible by ten (instead of 228), this bug disappears. Same with a 9-byte-long sequence and a number divisible by nine.