Skip to content

Strange UART Tx byte timing/buffering, and flush() of 1 byte takes 27ms #4206

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

Closed
stukodotnet opened this issue Jul 26, 2020 · 3 comments
Closed
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@stukodotnet
Copy link

Hardware:

Board: espressif dev board v4 - ESP32-WROVER-IE 8MB FLASH
Core Installation version: 1.0.4
IDE name: Arduino IDE
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 115200
Computer OS: Windows 10

Description:

I need to write serial bytes with 5ms delay between each byte for the SAE KWP2000 protocol. The 5ms delay doesn't work. And even with no delay, there is strange behavior.

With no delay Serial1 works fine, it will send out the burst of 6 bytes immediately. But Serial2 always puts a 27ms delay between the first byte and the subsequent bytes.

Serial1:
https://imgur.com/8GUAsb7

Serial2:
https://imgur.com/P1tUMGo

With a 5ms delay between each call to Serialx.write(), they both look like Serial2 above. ie. there is a 27ms delay between the first byte, and subsequent bytes are in a burst with no inter-byte delay. Also note that a Serialx.flush() takes 27ms on either port. I don't think this 27ms time is a coincidence.

Also changing the INTER_BYTE_DELAYx in my sketch makes no difference to the byte timing on the port. From 1us through to about 19ms, the actual port delay is as shown in the screenshots above, ie no delay - with Serial2 always introducing the 27ms first byte delay. As INTER_BYTE_DELAYx approaches 25ms from 19ms, the port increasingly shows some 27ms delays between bytes. So its either a delay of zero, or a delay of 27ms, there is no in-between.

So in summary there are 3 related issues:

  1. There is something wrong with write() on Serial2. It always puts a 27ms delay between the first byte and subsequent bytes. NOTE that I have swapped between TX port 2 and 19, and the issue follows Serial2, not the port pin.

  2. Serialx.flush() takes 27ms for 1 byte, this is way too long and appears to be related to 1 above.

  3. A delay of 1us to 20ms between tx bytes is not possible, its either a delay of zero, or a delay of 27ms, there is no in-between.

Sketch:

#define PORT1 Serial1
#define RX1   4
#define TX1   19//2
#define BAUD1 9600
#define INTER_BYTE_DELAY1 5000ul // in us

#define PORT2 Serial2
#define RX2   18
#define TX2   2//19
#define BAUD2 9600
#define INTER_BYTE_DELAY2 5000ul // in us

#define VAR_NAME(var) #var

unsigned long start;

void setup()
{
    Serial.begin(115200);
    Serial.println("");
    Serial.println("");
    printf("Starting %s on rx:%d, tx:%d @%d", VAR_NAME(PORT1), RX1, TX1, BAUD1);
    Serial.println("");
    start = micros();
    PORT1.begin(BAUD1, SERIAL_8N1, RX1, TX1);
    printf("%s beginTime = %dus\n", VAR_NAME(PORT1), (int)(micros() - start));
   
    printf("Starting %s on rx:%d, tx:%d @%d", VAR_NAME(PORT2), RX2, TX2, BAUD2);
    Serial.println("");
    start = micros();
    PORT2.begin(BAUD2, SERIAL_8N1, RX2, TX2);
    printf("%s beginTime = %dus\n", VAR_NAME(PORT2), (int)(micros() - start));
    
}
void loop() {
  // put your main code here, to run repeatedly:
    
    Serial.println("");
    Serial.println("");
    Serial.println("loop start in 5s");
    delay(5000);
    
    for (int i = 0; i < 6; i++) {
        start = micros();
        PORT1.write(i);
        //PORT1.flush();
        delayMicroseconds(INTER_BYTE_DELAY1);
        printf("i = %d, %s writeTime = %dus\n", i, VAR_NAME(PORT1), (int)(micros() - start));
    }

    Serial.println("");
    
    for (int i = 0; i < 6; i++) {
        start = micros();
        PORT2.write(i);
        //PORT2.flush();
        delayMicroseconds(INTER_BYTE_DELAY2);
        printf("i = %d, %s writeTime = %dus\n", i, VAR_NAME(PORT2), (int)(micros() - start));
    }    
}

Debug Messages:

@stukodotnet
Copy link
Author

Ok I think I've found the issue, its the same problem as in #3664

The default tx_idle_num of 256 is causing the problem.
(1/9600bps) * 256 = 26.667ms

So this change as per #3664 has fixed my issue:
// tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate) // Setting it to 0 prevents line idle time/delays when sending messages with small intervals uart->dev->idle_conf.tx_idle_num = 0; //
Is this fix going to be in the next release of the library?

@stale
Copy link

stale bot commented Sep 26, 2020

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Sep 26, 2020
@stale
Copy link

stale bot commented Oct 10, 2020

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

@stale stale bot closed this as completed Oct 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

1 participant