I have a quick question. I’m running an Arduino Uno, with a WS2812b strip and Boblight on my XBMC. I originally ran an older RGB strip with no addressing (analog out). I’m using the FastLED 2.1 library now.
After all of my research, it seems that I should be using HSV as opposed to RGB. But I cannot seem to figure out if I’m supposed to convert the boblight serial data to HSV. It seems to me that I indeed should be converting it and then letting FastLED convert it back to RGB on the way out to the WS2812b. This would be good for my project because, I’m now attempting to re-add my original analog strips to my sketch.
Since the new WS2812b is addressable, it has higher resolution, but the original strip is all one color at a time or nothing. So I’m thinking that I could average out the HSV values from a group of LEDs on the new WS2812b strip, adjust the saturation and brightness, convert them back to RGB and then write them out to analog outputs. But I cannot seem to validate this approach and my test sketches have been less than successful at this point.
Is there a common method for scaling RGB values (for brightness) being written analog? My previous attempts to average 10 pixels ended with a very dim output.
Or do I just add a fixed percentage to each R/G/B value (limiting at 255).
My first FastLED project was a boblight addon for my OpenElec media pc. OpenElec is a custom linux xbmc build. The serial data stream can simply be read straight into the CRGB array as the data is RGB. One of the trickiest aspects is getting the boblight.conf file setup correctly.
This is the ‘device’ section of mine:
[device]
name ambilight
type momo
output /dev/ttyACM0
channels 384
prefix 41 64 61 00 7F 2A
interval 20000
rate 115200
debug off
delayafteropen 1000000
if (Serial.available() >= 6)
{
if (Serial.read() == ‘A’)
{
if (Serial.read() == ‘d’)
{
if (Serial.read() == ‘a’)
{
if (Serial.read() == 0x00) // High byte of Last LED Number
{
if (Serial.read() == 0x7f) // Low byte of Last LED Number
{
if (Serial.read() == 0x2a)
{
NumLeds = ((0x00 * 256) + (0x7f + 1));
Serial.readBytes((char *)&leds[0].r, NumLeds * 3);
FastLED.show();
}
}
}
}
}
}
}
}
I have a fully functional setup that works very well. My problem is in try to add in addition my original “non-controllable” strips using the analog output. They’re much lower resolution (channels) than the digitally controlled strip, so I’m attempting to average a collection of pixels/leds and then drive the analog strips. The problem with that is that once averaged, the value out scales down the brightness of the analog driven leds.
Going on Daniels replys, I attempted to look into scaling methods using CRGB, but have yet to figure out how to utilize them considering each analog RGB value is written independently to the serial pins. I did work up some code to scale the output values, but somethings wrong with it as all I get out (after scaled) is pure white (255) or nothing (0).
So, I’m back to wishing that I could convert RGB to HSV so that I can control the HUE and adjust the brightness value based off of my global brightness definition, convert it back to RGB and write it out.
Here is my code:
for (uint8_t i = 0; i < NUMLEDS; i++) { // read the transmitted data
for (uint8_t j = 0; j < 3; j++) {
while(!Serial.available());
arrRGBValues[i][j] = Serial.read();
}
byte red = arrRGBValues[i][0];
byte green = arrRGBValues[i][1];
byte blue = arrRGBValues[i][2];
leds[i] = CRGB(red, green, blue);
}
for (uint8_t i = 0; i < 29; i++) { // sum the 29 leds/pixels representing the right side.
arrAnalogOutRGB[0] += arrRGBValues[i][0];
arrAnalogOutRGB[1] += arrRGBValues[i][1];
arrAnalogOutRGB[2] += arrRGBValues[i][2];
}
for (uint8_t i = 0; i < 3; i++) { // divide the sum and scale it by , then write it out to the analog pins.
byte scaledColor;
arrAnalogOutRGB[i] /= 29;
scaledColor = arrAnalogOutRGB[i] + ANAOUTSCALE; // scale the brightness here
if (scaledColor > 255) { scaledColor = 255; }
arrAnalogOutRGB[i] = scaledColor;
analogWrite(arrAnalogLeft[i], arrAnalogOutRGB[i]);
arrAnalogOutRGB[i] = 0; // clear out the current element
}
Ok, first thing to check is that you are using a 16bit int for the arrAnalogOutRGB array.
Also I do not see you setting the arrAnalogOutRGB to 0 before the summing loop only after, if its defined in your loop function and not static it will contain garbage.
Final question is what value is ANAOUTSCALE
I just tried a different method that I think should work better for finding the average color, but I think it slows everything down too much. My digital strip just blinks red / blue instead of settling in on blue the way it’s supposed to. If I comment out the RGB>HSV function call, then it behaves normally (no blinking).
In the first pastebin line 126 reads “byte arrAnalogOutRGB[3];”
A byte is only 8 bits, you are using this to sum multiple 8 bit values so it will overflow!
try changing the byte to word and see how you get on.
Also of note is that scaledColor is defined as a byte which makes your compare with > 255 impossible. With a byte of 255 adding 1 will wrap it back to 0.
Very good point about the wrap. I totally missed those data types. I haven’t worked in C/C++ in quite a few years. (just did a refresher read on Data Types).
Debugging would be MUCH easier if I could see what things are doing. Just downloaded a simulator so that I can see my vars. Should be easier to debug now!