Controlling WS2812B LED-Stripe with Serial - Problems from 22 and more FPS

Hello Guys,

I am not sure if this is the right place because my problem could be caused by Serial or by my stripe.
I want to control my 60 WS2812b RGB-LED-Stripe with my Computer over Serial. I am using a Arduino Uno Rev 1. I send for every led the color (24Bits) and its works fine as long as I stay under 22FPS. I use 115200 baud so it should be possible to transfer 80 FPS (602480 = 115200) over Serial. But if I go over 21FPS it fails.

[ERROR DESCRIPTION] (I can also make a Video if you want)

I just turn on 1 LED in white per frame and after all on I turn them off backwards. On 22 FPS the first lamp which lights up is the 7. instead of the 1. (and the 4. if I use 57600 baud) and its blue, all others are while instead of the last which is yellow. And the last LED which turns on before going backwards is the 6. So its like the start index is moved to 7.

Can somebody help me?

Stripe.ino (670 Bytes)

Main (Java).txt (839 Bytes)

Okay I found the Problem. It looks like the Serial.readBytes() don't isn't blocking. If I make delay(10) all is okay. Is there any way to check if its ready?

Strange, I would expect all the data to be there with this line

if (Serial.available() >= NUM_LEDS * 3) {

so blocking or not it read all the led’s.

Did you try FastLED Animation Library or something like it?

@Riva
jep, same I thought. And also a strange thing is, that delay(1) works perfekt with 60 leds but if I increase it, its worse o.O

And now I use 109 Leds and have the same Problem again and my delay dont fix it.

@Whandall
As you can see in my uploaded code, I am using FastLED.

Jam00:
@Riva
jep, same I thought. And also a strange thing is, that delay(1) works perfekt with 60 leds but if I increase it, its worse o.O

Looking at HardwareSerial.cpp the serial ring buffer size is probably only 64 bytes so ‘NUM_LEDS * 3’ is to big for buffer.

#if (RAMEND < 1000)
  #define SERIAL_BUFFER_SIZE 16
#else
  #define SERIAL_BUFFER_SIZE 64
#endif

You will either need to increase the size of the buffer or alter you code so it trickle fills state and then calls setLeds(). You should also figure out a way to determine the end of data as with your current code (after increasing the buffer size) you have no way of determining if the data is being read in the correct order into the state array. If bytes are lost then the reading becomes out of sync.

yeah sry I forgot to mention, I already increased the Buffer. And I could try mark the end but its working with lower framerate? And the problem is, that I send bytes and I need the whole range for the colors (0-255), there is no free value. And its not possible to send int because it would double the amount of data and this would be more than I can transmit via Serial. So how could I validate the data?

Jam00:
yeah sry I forgot to mention, I already increased the Buffer. And I could try mark the end but its working with lower framerate? And the problem is, that I send bytes and I need the whole range for the colors (0-255), there is no free value. And its not possible to send int because it would double the amount of data and this would be more than I can transmit via Serial. So how could I validate the data?

Would you really notice the difference if the minimum level was 1 instead of 0 or better still maximum value 254 instead of 255? A difference of 1 is only a 0.4% change

For lower frame rates you could use the delay between the frames of data as a marker but as you get to higher frame rates the delay will get smaller and maybe more easy to miss.

Yeah I will give it a try but I am not at home for the weekend so not before Monday.

You could also turn off interrupts while doing the actual send of data to the LEDs. This will delay your read from serial but it will guarantee your LED timing which is very sensitive to pauses.