ninja2
Well-known member
My hardware:
Sparkfun Main Double board, fitted with:
Processor board : Micromod Teensy
Function board 0: Micromod ZED-F9P GNSS
Function board 1: Micromod ESP-32 WiFi/Bluetooth
My recent interest has been developing a reliable feed of an RTCM3 correction data to the ZED-F9P, so it can maintain RTK levels of GPS accuracy (~cms)
I have a pair of programs doing this task reasonably well, one on the ESP32, the other on the Teensy. A public correction data stream is received by the ESP32 and forwarded over Serial into the Teensy, which then forwards it via another Serial port to the ZED-F9P.
A bit more detail: the ESP32 connects via its built-in WiFi (and my router) to a public NTRIP Caster (Networked Transport of RTCM via Internet Protocol) that provides the feed. So this is my data pipeline:
NTRIP Caster -> ESP32 -> Teensy -> ZED-F9P GNSS
The average data rate of the feed is not particularly high, around 2.4kB/s. However it comes in bursts of one, several or many RTCM correction messages. So a burst can be anywhere from a few bytes containing a single short message, to over 16kB in one burst containing as many as 50 messages, on occassion. A typical burst has around 5-8 messages contained in ~2,500 bytes.
To handle the data bursts the ESP32 reads the data into a 16kB buffer. The buffer contents are processed between bursts, dividing the burst into individual messages. The CRC of each message is checked to filter out any duds. Verified messages are forwarded one at a time to the teensy.
The teensy receives each message as a 'package' consisting of 3 header bytes + the message bytes + 3 CRC bytes. These packages are typically between 50 and 600 bytes in length. Unlike on the ESP32, a dedicated buffer is not currently used. Instead the main program loop uses
to process a whole package, including CRC checking (again) before forwarding the package (if healthy) on to the ZED-F9P.
As mentioned I have a working solution, but it was not always so. At first the teensy was dropping about 50% of the packages. At that stage both Serial2 in and Serial1 out were set to 115,200 baud. I thought that would be sufficient since that = 14.4kB/s, comfortably more than the average RTCM data rate of < 2.5kB/s. But it only started working after I inserted
into the ESP32 processing loop, effectively adding a 50ms break between package transmissions. At last, the teensy hardware serial ports could keep up!
But that workaround didn't sit right, so I kept fiddling. I increased the Serial1 & Serial2 to 921600 baud (i.e an 8-fold increase) and found I could reduce
down to
with very few dropped messages. If I increased back up to 10 the dropped packages were almost zilch.
Improved but still not ideal. For now the teensy only has the task of echoing this data stream on to the ZED-F9P, but it will soon have several other major tasks, so I want my solution to add minimal load for the teensy to do the data echo function.
I've started looking into/contemplating how the Serial buffers work. There is helpful info at Teensyduino Hardware Serial Ports, but I could't find any info on the standard buffer sizes. The Arduino Serial reference suggests only 64 bytes but I think it may be 128 bytes since Serial.availableForWrite() always seems to report values < 128.
I guess I'm looking for ideas on how to make the serial data echo more efficient on the teensy, and specifically if I increase the buffer size on the incoming, or outgoing data (or both) is that likely to further free up the serial pipeline? If so, how to do that ... ?
TIA
Sparkfun Main Double board, fitted with:
Processor board : Micromod Teensy
Function board 0: Micromod ZED-F9P GNSS
Function board 1: Micromod ESP-32 WiFi/Bluetooth
My recent interest has been developing a reliable feed of an RTCM3 correction data to the ZED-F9P, so it can maintain RTK levels of GPS accuracy (~cms)
I have a pair of programs doing this task reasonably well, one on the ESP32, the other on the Teensy. A public correction data stream is received by the ESP32 and forwarded over Serial into the Teensy, which then forwards it via another Serial port to the ZED-F9P.
A bit more detail: the ESP32 connects via its built-in WiFi (and my router) to a public NTRIP Caster (Networked Transport of RTCM via Internet Protocol) that provides the feed. So this is my data pipeline:
NTRIP Caster -> ESP32 -> Teensy -> ZED-F9P GNSS
The average data rate of the feed is not particularly high, around 2.4kB/s. However it comes in bursts of one, several or many RTCM correction messages. So a burst can be anywhere from a few bytes containing a single short message, to over 16kB in one burst containing as many as 50 messages, on occassion. A typical burst has around 5-8 messages contained in ~2,500 bytes.
To handle the data bursts the ESP32 reads the data into a 16kB buffer. The buffer contents are processed between bursts, dividing the burst into individual messages. The CRC of each message is checked to filter out any duds. Verified messages are forwarded one at a time to the teensy.
The teensy receives each message as a 'package' consisting of 3 header bytes + the message bytes + 3 CRC bytes. These packages are typically between 50 and 600 bytes in length. Unlike on the ESP32, a dedicated buffer is not currently used. Instead the main program loop uses
Code:
while (Serial2.available())
As mentioned I have a working solution, but it was not always so. At first the teensy was dropping about 50% of the packages. At that stage both Serial2 in and Serial1 out were set to 115,200 baud. I thought that would be sufficient since that = 14.4kB/s, comfortably more than the average RTCM data rate of < 2.5kB/s. But it only started working after I inserted
Code:
delay(50)
But that workaround didn't sit right, so I kept fiddling. I increased the Serial1 & Serial2 to 921600 baud (i.e an 8-fold increase) and found I could reduce
Code:
delay(50)
Code:
delay(5)
Improved but still not ideal. For now the teensy only has the task of echoing this data stream on to the ZED-F9P, but it will soon have several other major tasks, so I want my solution to add minimal load for the teensy to do the data echo function.
I've started looking into/contemplating how the Serial buffers work. There is helpful info at Teensyduino Hardware Serial Ports, but I could't find any info on the standard buffer sizes. The Arduino Serial reference suggests only 64 bytes but I think it may be 128 bytes since Serial.availableForWrite() always seems to report values < 128.
I guess I'm looking for ideas on how to make the serial data echo more efficient on the teensy, and specifically if I increase the buffer size on the incoming, or outgoing data (or both) is that likely to further free up the serial pipeline? If so, how to do that ... ?
TIA
Last edited: