LED strips and fast communication via Serial

Hello Arduino friends,
as the title says or you might expect, I’m looking for some help.

What do I want to do?
My idea was to backlight some of my furniture according to music or my tv (like philips ambilight). So, basically I’m controlling a bunch of LED strips with a TLC5940 and an Arduino Nano board. My Computer processes the music or data I retrieve from the TV and should send it via USB / Serial to the Arduino.

Where do I need help?
I’ve got no problems with the TLC or other coding stuff for the computer part. But the connection between my computer and Arduino isn’t just working right. It works somehow most of the time, the LED strips light up in the correct colors, but sometimes there’s a clearly distortion and the LEDs just flash in random colors.

My approach after some research on Google:
The computer sends a string each “frame”, which consists of 15 bytes. Each byte controls one color of one of the 5 LED strips. So it’s like: ‘rgbrgbrgbrgbrgb’ (Hopefully, I’m not sounding like an idiot)
I guess the data I’m sending has an offset or something. That’s why I’ve put a byte (255) in front of every new data sequence, but still no improvement. While debugging a bit, there were some bytes which got lost during Serial transmission, but I have no idea why.

I appreciate any help or even a completely new approach on how to send data fast via Serial.

Oh, and here’s my code and a video, which hopefully shows my problem (sometimes random flashing colors)

#include "Tlc5940.h"

void setup() {

  Serial.begin(115200);
  
  Tlc.init();
  Tlc.clear();
  for (int i = 0; i < 16; i++) {
    Tlc.set(i, 4095);
  }
  Tlc.update();

  serialFlush();
  
}
  
}

void loop() {
  
  if (Serial.available() > 0) {

    if (((int) Serial.read()) == 255) {

      byte input[15];
      Serial.readBytes(input, 15);
  
      for (int i = 0; i < 5; i++) {
        
          updateStrip( i + 1, (int) input[i * 3], (int) input[i * 3 + 1], (int) input[i * 3 + 2] );
          Tlc.update();

          delay(5);
          
      }
      
    }
    
  }

}

void updateStrip(int strip, int r, int g, int b) {
  Tlc.set(strip * 3 - 3, 4095 - map(r, 0, 255, 0, 4095));
  Tlc.set(strip * 3 - 2, 4095 - map(g, 0, 255, 0, 4095));
  Tlc.set(strip * 3 - 1, 4095 - map(b, 0, 255, 0, 4095));
}

void serialFlush(){
  while (Serial.available() > 0) {
    Serial.read();
  }
}

One potential problem is that when you read the first "255", you assume that the next 15 bytes are already there in the buffer. This might not be true - the Arduino can operate a lot faster than the serial port can.

I would change your code to loop until you have 15 bytes or a certain amount of time has passed (timeout).

If you want to quickly test if this is causing the problem, put a small delay into your code after you receive the "255" and before you read the next 15 bytes. This is definitely not the long term solution, but it will quickly prove if this is causing the problem.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

An Atmega 328 will happily work at 500,000 baud.

...R

Apologies, readBytes will wait for that number of bytes or a timeout (default 1000 milliseconds).