Issue trying to arrange 3 bytes of data for a FastLED CRGB colour variable

Hi all,

I'm trying to get my WS2811 programmable LEDs talking via serial to some software called "Direct Output Framework" which is part of a pinball emulator. It allows (when it works!!) the LEDs to mimic the lights that are happening on the 'playfield' of the pinball machine.

I'm new to Arduino programming and I managed to find some code that referenced the Adafruit_NeoPixel library but I've been converting it over to FastLED over the last couple of hours and I'm nearly there.

My problem seems to be that I'm only interpreting the Green and Blue and not the Red values. I have a test pinball table so I'm almost positive that the correct values are being sent.

I've also set up a "Test" function in my software and can successfully get all the LEDs to go Red / Green and Blue in the correct order.

That led me to think it might be the function that receives the three bytes of colour from the pinball machine at fault?

The original code I came across used this function:

//Receives 3 bytes of color data.
int ReceiveColorData() {
  while(!Serial.available()) {};
  int colorValue=Serial.read(); 
  while(!Serial.available()) {};
  colorValue=(colorValue<<8)|Serial.read();
  while(!Serial.available()) {};
  colorValue=(colorValue<<8)|Serial.read();
  
  return colorValue;
}

I wondered if an "int" wasn't big enough to fit in 3 bytes and some data was dropping off the edge (so to speak?). In my previous experience programming PLCs a byte is 8 bits and an INT only holds 16 bits? Not sure if that's the same for an Arduino??

I've been playing around with something like this:

//Receives 3 bytes of color data.
int ReceiveColorData() {
  unsigned long rxdColor;
  while(!Serial.available()) {};
  rxdColor = Serial.read();
  rxdColor = rxdColor<<8;

  while(!Serial.available()) {};
  rxdColor = Serial.read();
  rxdColor = rxdColor<<8;

  while(!Serial.available()) {};
  rxdColor = Serial.read();

  return rxdColor;

}

But I might be completely off-piste here and I don't seem to be getting closer to a solution so I thought I would put up the white flag for assistance?

In case it's pertinent and the fault doesn't lie there - I've attached my code to this post (I tried to copy it into the post but went over the 9000 char limit so just attached it instead).

Thanks for any help you can give me :slight_smile:

pinballCode.ino (9.07 KB)

You ultimately use the return value as a CRGB, so why not return one of those?

CRGB ReceiveColorData() {
  CRGB colorValue;
  while (!Serial.available()) {};
  colorValue.red = Serial.read();
  while (!Serial.available()) {};
  colorValue.green = Serial.read();
  while (!Serial.available()) {};
  colorValue.blue = Serial.read();

  return colorValue;
}

See the pixel reference for full info.

That's excellent Blue Eyes, thank you for the information! I didn't realise that it was possible to address the individual parts of a CRGB object.

Just for my own interest regarding my points about using an INTeger in the first example. Am I right that it would never work because an INT only has 16 bits and so can't be 'shifted' by 8 bits to the left twice in order to store the 24 bits needed for the 3 bytes?

Or does the arduino work differently than that?

Again, a big thanks for all your help. Your solution is excellent.

uptown47:
Just for my own interest regarding my points about using an INTeger in the first example. Am I right that it would never work because an INT only has 16 bits and so can't be 'shifted' by 8 bits to the left twice in order to store the 24 bits needed for the 3 bytes?

Yeah on the 8-bit AVR Arduinos, an int is 16 bits.

GypsumFantastic:
Yeah on the 8-bit AVR Arduinos, an int is 16 bits.

That's great. Thanks for the confirmation. Glad I don't have to start "re-learning" things for the platform.

I'm loving the Arduino it's a superb bit of kit and I'm enjoying learning how to program it. My problem now is that I want to keep thinking of new projects to start. :slight_smile:

Thanks again :slight_smile: