ShadowLight8
Member
I'm using a Teensy 3.2 with the OctoWS2811 Adaptor, connected via USB Serial to a Raspberry Pi 4 running Falcon Player v3.3 (Raspbian based) to control 2378 WS2813 LEDs being updated at 25ms intervals. The Teensy & OctoWS2811 library are configured to run the longest string of 517 LEDs, so it is having to push bits as if there were 4136 LEDs. With this configuration, I'm expecting a 2 byte header plus 12408 bytes of data being sent over USB Serial, in 64 byte packets, from the Pi to the Teensy, every 25ms.
I'm using Serial.readBytes() to get the data, then hand it off to setPixel in the OctoWS2811 library. However, when I try to use Serial.readBytes() for a "large" number of bytes, the Teensy appears to hang or at least never return from the Serial.readBytes(). This is based on my observation that the built-in LED stops blinking with the code below.
Condensed version:
Full code, with comments, is here https://github.com/ShadowLight8/fpp...fpp-to-teensy-serial/fpp-to-teensy-serial.ino
With the default NUM_USB_BUFFERS in usb_desc.h of 12 for USB_SERIAL, attempting 517 byte reads does not work and the built-in LED does not blink.
If I increase the NUM_USB_BUFFERS to 30, 517 byte reads to work. The built-in LED continues to blink and the WS2813 LEDs light up as expected.
Another non-working attempt was to read all 12408 bytes I was expecting by doing:
Ultimately, this single 12408 byte Serial.readBytes() is what I'd like to get working.
I also tried the following code to handle timeouts and use the led to indicate that they were occurring, but it also did not work:
I have looked at the OctoWS2811 VideoDisplay code, which appears to do "large" 7500 byte Serial.readBytes(). https://github.com/PaulStoffregen/OctoWS2811/blob/master/examples/VideoDisplay/VideoDisplay.ino
I've attempted to read through the teensy3/core (usb_serial.h readBytes; usb_serial.c usb_serial_read; usb_dev.c usb_rx & usb_rx_memory; usb_mem.c usb_free) to understand if I'm missing something in my code, but my C/C++ kung-fu might not be up to the task yet.
Any assistance or suggestions of how to dig into this issue is sincerely appreciated. Thank you in advance!
-Nick Anderson
I'm using Serial.readBytes() to get the data, then hand it off to setPixel in the OctoWS2811 library. However, when I try to use Serial.readBytes() for a "large" number of bytes, the Teensy appears to hang or at least never return from the Serial.readBytes(). This is based on my observation that the built-in LED stops blinking with the code below.
Condensed version:
Code:
// Created by Nick Anderson 7/2/2017
#include <OctoWS2811.h>
#define LEDPIN 13 // Teensy 3.2 LED Pin
#define qBlink() {GPIOC_PTOR=32;} // Fast way to toggle LED on and off
#define MAX_PIXELS_PER_STRIP 517
DMAMEM int displayMemory[MAX_PIXELS_PER_STRIP * 6];
int drawingMemory[MAX_PIXELS_PER_STRIP * 6];
OctoWS2811 leds(MAX_PIXELS_PER_STRIP, displayMemory, drawingMemory, WS2811_RGB | WS2813_800kHz);
void setup() {
Serial.begin(115200);
Serial.setTimeout(20);
leds.begin();
leds.show();
pinMode(LEDPIN, OUTPUT);
qBlink();
}
char megaBuffer[MAX_PIXELS_PER_STRIP * 8 * 3]; // 12408 currently
int curItem = 0;
unsigned long millisSinceBlink;
void loop() {
if (Serial.readBytes(megaBuffer, 2) == 2) {
if (megaBuffer[0] == '<' && megaBuffer[1] == '>') {
curItem = 0;
while (curItem < 24) {
Serial.readBytes(&megaBuffer[curItem * MAX_PIXELS_PER_STRIP], MAX_PIXELS_PER_STRIP);
curItem++;
}
if (millis() - millisSinceBlink > 25) {
millisSinceBlink = millis();
qBlink();
}
curItem = 0;
while (curItem < (MAX_PIXELS_PER_STRIP * 8)) {
leds.setPixel(curItem, megaBuffer[curItem * 3], megaBuffer[curItem * 3 + 1], megaBuffer[curItem * 3 + 2]);
curItem++;
}
leds.show();
}
}
}
With the default NUM_USB_BUFFERS in usb_desc.h of 12 for USB_SERIAL, attempting 517 byte reads does not work and the built-in LED does not blink.
If I increase the NUM_USB_BUFFERS to 30, 517 byte reads to work. The built-in LED continues to blink and the WS2813 LEDs light up as expected.
Another non-working attempt was to read all 12408 bytes I was expecting by doing:
Code:
Serial.readBytes(megaBuffer, MAX_PIXELS_PER_STRIP * 8 * 3);
I also tried the following code to handle timeouts and use the led to indicate that they were occurring, but it also did not work:
Code:
curItem = 0;
while (curItem < MAX_PIXELS_PER_STRIP * 8 * 3) {
n = Serial.readBytes(megaBuffer + curItem, MAX_PIXELS_PER_STRIP * 8 * 3 - curItem);
if (millis() - millisSinceBlink > 25) {
millisSinceBlink = millis();
qBlink();
}
curItem += n;
}
I have looked at the OctoWS2811 VideoDisplay code, which appears to do "large" 7500 byte Serial.readBytes(). https://github.com/PaulStoffregen/OctoWS2811/blob/master/examples/VideoDisplay/VideoDisplay.ino
I've attempted to read through the teensy3/core (usb_serial.h readBytes; usb_serial.c usb_serial_read; usb_dev.c usb_rx & usb_rx_memory; usb_mem.c usb_free) to understand if I'm missing something in my code, but my C/C++ kung-fu might not be up to the task yet.
Any assistance or suggestions of how to dig into this issue is sincerely appreciated. Thank you in advance!
-Nick Anderson