Missing serial data bytes

adrianpang

New member
I have written a code for Teensy 3.2 to utilise all 3 serial ports.

Serial1 will receive a set of commands and will send Serial2 and Serial3 data based on these commands. Serial1 will receive a set of response from Serial2 and Serial3. This is somewhat like a serial multiplexer.

There is an inquiry command that Serial1 receives every 100ms, and the code copies the data and send it to Serial3 directly.

There is a set of response from Serial2 sends to Serial1 every 1s.

What is happening is that Serial1 can receive a ad-hoc, asynchronous set of commands to drive an LED. However, it is observed that Serial1 will not receive these commands all the time.

Serial1 seems to be dropping data.

Can anyone suggest how I can debug this further? I did some printf and noticed that the ad-hoc set of commands only gets captured and decoded very rarely, even if they are sent to Serial1 quite often.
 
I suspect this is a case that you should follow the forum rule and post code. Perhaps whatever is sending the data is buffering it, and not sending it immediately. Perhaps you have interrupts disabled for periods of time, and it is not seeing that there are characters available to be read. Perhaps you are reading in larger chunks, and the library routine is waiting until it has a full buffer. You might want to mention what device is writing to the serial port and what baud rate you are using.

FWIW, Serial1 and Serial2 have 8 byte FIFOs on Teensy 3.1/3.2. There is no FIFO on Serial3 on the Teensy 3.1/3.2, and none on any serial device on the LC.

Starting with 1.26 of teensydunio, you can enable hardware flow control on Serial1 (RTS can be on pins 6 or 19, and CTS can be on 18 or 20) if your remote device supports it.
 
Hi, thanks for the reply. I will attempt to post code once I am back to the workstation where the code resides.

Another embedded platform with a MAX14830 Quad UART chip is writing to Serial1. Data is not being buffered when sent to Serial1 as I can check using a serial terminal program like Realterm. No interrupts were used, except those in the built in serial libraries. Data is written in small chunks of no more than 18 bytes per message to Serial1. Baud rate is 115200 on Serial1, 115200 on Serial2 and 9600 on Serial3.

What effect does the 8 byte FIFO have on data coming into Serial1 and Serial2? Which I know how many bytes are in the buffer using Serial1.available()?

I suspect this is a case that you should follow the forum rule and post code. Perhaps whatever is sending the data is buffering it, and not sending it immediately. Perhaps you have interrupts disabled for periods of time, and it is not seeing that there are characters available to be read. Perhaps you are reading in larger chunks, and the library routine is waiting until it has a full buffer. You might want to mention what device is writing to the serial port and what baud rate you are using.

FWIW, Serial1 and Serial2 have 8 byte FIFOs on Teensy 3.1/3.2. There is no FIFO on Serial3 on the Teensy 3.1/3.2, and none on any serial device on the LC.

Starting with 1.26 of teensydunio, you can enable hardware flow control on Serial1 (RTS can be on pins 6 or 19, and CTS can be on 18 or 20) if your remote device supports it.
 
I believe the fifo helps if interrupts are disabled when a character comes in so that it isn't lost (it just gets put into the fifo queue).
 
In the loop code, I wrote 3 routines. Each of them will check the available number of bytes and then check each byte for a header. Once the header is found, it will continue reading the message length and the message code to determine how to decode the message. In the messages to Serial1, I constantly see missing messages and data received looks like they are at half the output rate of the MAX14830 device. I checked that when the MAX14830 device is connected to the PC I could get around 110 bytes per second on average. But when it send it to Serial1 of teensy and do a Serial.print count every second, I get like 55 or less. This is not normal. I check with 2 teensy and the behavior is the same with the same loaded code. I am beginning to suspect it is hardware but I want to be sure I am not doing something wrong in code. Unfortunately the project I am working on is paid, and code cannot be published readily.

I believe the fifo helps if interrupts are disabled when a character comes in so that it isn't lost (it just gets put into the fifo queue).
 
In the loop code, I wrote 3 routines. Each of them will check the available number of bytes and then check each byte for a header. Once the header is found, it will continue reading the message length and the message code to determine how to decode the message. In the messages to Serial1, I constantly see missing messages and data received looks like they are at half the output rate of the MAX14830 device. I checked that when the MAX14830 device is connected to the PC I could get around 110 bytes per second on average. But when it send it to Serial1 of teensy and do a Serial.print count every second, I get like 55 or less. This is not normal. I check with 2 teensy and the behavior is the same with the same loaded code. I am beginning to suspect it is hardware but I want to be sure I am not doing something wrong in code. Unfortunately the project I am working on is paid, and code cannot be published readily.

110/2 = 55 exactly the half, sounds a bit suspicious.
But withwouth seeing code, it's hard to help! All i can say is, that i used the Serial1 for receiving data from an ESP8266 with rates between 2 and 4Mbit/s without losses. But i used larger buffers and hardware-handshake.
Can't you show at least a stripped-down example which helps to understand what's going wrong ?
 
What happens if you edit serial1.c and change this line :
Code:
#define RX_BUFFER_SIZE     64

to

Code:
#define RX_BUFFER_SIZE     256

? Still losses ?
 
The T_3 Serial1 and Serial2 hardware can run at over 4,000,000 baud - so 115,000 baud should not be stressing the Teensy.

If you wanted to make sure all bytes are read as they are received you can use: serialEvent()

That link shows a general USB Serial example - this link shows it in context of Serial# which T_3 supports: http://www.arduino.cc/en/Reference/SerialEvent

If you don't exit loop() often enough the data won't be pulled out - you can add yield() to allow the SerialEvent processing.

These functions are called by 'the system' when data arrives - your code would need to process the incoming bytes and exit without delay or extensive processing as it will hold up other buffer reading. That is read the characters to a local buffer detecting message boundaries - perhaps an array of messages where the last may not yet be complete stored by the SerialEvent code. Then main code can process only complete messages and mark that entry as free in some fashion.
 
Back
Top