Hi all, first of all thanks to the creators of FastSPI_LED2 and for creating this community!
I’m trying to send one line at a time of RGB data over serial and have it displayed on my WS2811. I have this working, but it’s much slower than I hoped. It takes nearly 10 seconds to get through 256 lines. The demos are much faster and smoother than that.
I think the problem is in the Arduino code that reads the serial data and updates the led array. My Python code runs very fast when not writing to serial, and writing to the leds is fast on its own.
Is there a way to bulk-write by RGBRGB… byte array directly in FastSPI_LED2? I already have the bytes, so creating CRGB seems inefficient.
Here’s my code currently:
char bytes[USE_LEDS * 3];
void loop() {
// signal read to receive data
Serial.println(“x”);
if (Serial.readBytes(bytes, USE_LEDS * 3) == USE_LEDS * 3) {
//Serial.println(“read full line”);
for (int i = 0; i < USE_LEDS; i++) {
// leds[i].r = bytes[i*3];
// leds[i].g = bytes[i*3+1];
// leds[i].b = bytes[i*3+2];
leds[i] = CRGB(bytes[i*3], bytes[i*3+1], bytes[i*3+1]);
}
LEDS.show();
} else {
//Serial.println(“did not get enough data”);
}
}
Thanks!
You can read bytes directly from serial into the led array; no need to read and then copy; a CRGB is nothing more than one byte for red, one byte for green, and one byte for blue.
That said, I suspect your problem is the serial port speed that the Arduino is talking at. What speed are you initializing it with, and have you confirmed that you’re able to read that fast?
Arduino docs specify a maximum data rate of 115,200 bps – that’s BITS per second, and in serial communication you should estimate TEN bits per byte transmitted, due to stop bits etc…, so I suspect that you should estimate that the Arduino serial code can receive a maximum of 11,520 bytes per second, or a little less than 4,000 full RGB pixels per second.
Please let us all know what you find out about the serial speed – I think a lot of people would be interested in doing exactly what you’re trying here.
Serial() by itself is dog slow. You have an ‘x’ being printed out at the top of the loop(), take it out. Blink an LED instead if you need some kind of indication. And you may want to do a while loop instead of an if/else.
while (Serial.readBytes(…) < …) {}
This puts it in a loop waiting for data and not continue on to check the if/else constantly. Once it has the required amount of data, it automatically jumps out of the while loop and moved on.
With Arduino you can also, if you want to get up to DMX (250kbps) speeds, do some hacks to HardwareSerial.cpp (dirty)… In researching I found that the fastest way to get the data from serial was re-defining the interrupt for serial. I have some examples if you wanted to go that route.
Thanks for the CRGB info, I thought I could possibly just read directly into the struct array but wasn’t sure of the struct contents.
I forgot to mention my baud rate is 57600. I figured this was about 6kb/s. I’m currently just using 30 leds so the data size is 90 bytes. So I should be able to do at least 60 lines per second.
I’m receiving a bluetooth module soon and am not sure of its maximum speed, maybe I can go faster especially if it uses SPI/i2c.
the ‘x’ is a sync, it tells the host it’s ready for the next line. I tried taking it out but I don’t think the arduino can keep up since it only has a 64 byte buffer. I can’t use a LED since it’s computerised.
I don’t need a while loop since readBytes will read the whole input or nothing (as long as the number of bytes sent by the host and expected is in sync). If the host sends a line, this if statement will only execute once per line. If no data is sent or not enough within 1 second timeout, the data is discarded, the loop ends and another x is printed every second - it’s actually quite elegant to use.
Greg, thanks. I wasn’t sure messing with interrupts would be a good idea since the WS2811 timings are so tight. You don’t want the stream interrupted to service some serial data
Would your examples be compatible?
They assume you are using a dedicated connection on a single purpose device. I’m using it as a transmitter option. A FTDI com port receiving a 250kbps stream and Sending it out over wireless (RF). Serial isn’t being used for anything else on that device, it’s pretty busy 
I just tried reading directly into the leds array, it ran about twice as fast! But I think we could make it better 
I wasn’t able to ensure it actually worked properly since I don’t have the LEDs with me at the moment, just the Arduino. Will test when I get home.
Another better way to signal ready for data would be the built in serial pins like RTS etc, but I’ve never seen a library that actually uses those despite them being on the FTDI connector!
Looks like the bluetooth device I have ordered is designed purely as a serial bridge, which can support 3Mbps, but the Arduino is still limited to 115200. So now my attention has shifted to being able to access data faster via SPI or I2C. It’s possible the module supports this but I can’t find a pinout. Does anyone know of such a module, ideally already with a library?
I have written a simple library for talking to a UART module over SPI, which originally was to add a serial port to an Arduino (in the end it would have saved more time to just buy a mega, but oh well). That should support Mbps. So I guess I could talk to bluetooth serial via the UART. Just sounds more complicated than it needs to be.
I just had a thought - as a test I’m cycling red from 0 to 255. However, my global brightness is set to 64 (25%), so the value only actually increases every 4 cycles! It’s actually 4 times faster than I thought!
Funny, I was just looking today for bluetooth modules with the same goal. Most of them are async serial only, and while some go to 460 Kbps, 921 Kbps, or 1381 Kbps, the Arduino with a 16 MHz crystal can’t match close enough to any of their stock baud rates higher than 115,200 or maybe 230,400 bps. (With other crystals it could match the higher rates).
However, there are some bluetooth modules which have SPI ports, for an example see the Bluetooth Bee ,http://www.dfrobot.com/index.php?route=product/product&product_id=193#.UblQwUBOQs9
In the time I had, I did not find any documentation for any module for using the SPI port, much less a library. The next step was going to be looking at the chip manufacturer’s website for their documentation, mainly CSR for their BlueCore4 product.
I ran out of time for now, but am still interested, If you find out more about using SPI mode with a bluetooth module, please report back.
I got my bluetooth modules, and discovered they DO have SPI pins, and also AIO, DIO and USB pins! However that doesn’t mean that the firmware uses them. I found that you can use the SPI pins to flash another firmware on them, and there’s even a pay-for program (might have been BlueCore?) for developing firmwares and writing to the chip.
I haven’t yet tried connecting the SPI pins or USB pins to see if anything happens there. It also remains to be shown that the Arduino can actually communicate over SPI any faster than serial.