I have this project. A helmet for my DJ gigs with addressable LEDS. There are roughly 700 LEDS on this helmet, all individually addressable and controlled by an ESP32 with an Ethernet shield.
I've managed to get it send a full frame of data at around 24 frames per second. That's 3 bytes per color X 700 LEDs. Any faster and I end up hitting buffering limits. Now I have been advised that I can look into compression or only updating the LEDs that need to be updated but I figured personally it would make more sense to just reduce the resolution of color palette. Instead of 3 Bytes, only send the 1 byte and limit the color palette to 256 colors. I mean we're talking about average LED strips which aren't exactly epitome of sRGB color accuracy so reducing the range of colors to 256 I think would be just fine.
The question is, if I'm sending 1 byte of data, how can I then map that 1 byte to a particular RBG color value on the receiving end?
My current possible vector of attack is to use a table like this: 256 Colors - Cheat Sheet - Xterm, HEX, RGB, HSL
and literally scrape the data off it, format it into a 256 entry array, each index containing a 3 bytes RGB value, and use it as a lookup table on the receiving end. Then, create a color palette within my animation software where I create the animations, to limit the color choice to only these colors and make a corresponding encoding dictionary Red is the top values, within which there's a number of Green values, within which there's a number of Blue values, thus creating basically a 3 level deep lookup table for encoding an RGB color into a single decimal to be sent over the network.
The part I'm iffy about is the creation of the two lookup tables. Perhaps there's a way to use some other Principe for translating the 3 bytes of rgb data into a single byte. Maybe some sort of a known algorithm that is present within both the application sending the data and the MCU receiving the data. To get the sinle color byte, the 3 RGB bytes are fed into the algorythm and on the receiving end, the same algorithmic is performed in reverse, spitting out an RGB value?
Ultimately I want to find a way to reduce the 3 bytes of color data to 1 byte. This would triple my frame data traffic, allowing me to send more frames and achieve smoother animation.
a 'simple' way of compressing 3 bytes into one would be to change the base use ie from base 2 (binary) to some other value that would suit the range of value you expect to use as described in this thread I found.
3x8 but is 24 bits of possible combinations, over 16 million.
But suppose that you only need 256 combos at least for this frame? Then you define a struct of 3 bytes and made a 256 element array of those and name it palette. You can change the palette or sections of it very quickly, 256 is a soft limit.
HSV would still be 3 bytes, each for Hue, Saturation and Value. I was contemplating on splitting into just Hue and Value tho and the Hue would chose from a series of saturated and desaturated Hues so the saturation would be implied.
It's more talking about sending the data only for updated LEDs but you'd still have to supply the LED addresses so it doesn't really help. And yes, ALL leds have to be updated.
From what I figured, the buffering limit is on the Ethernet shield, not the LED strips. So by somehow reducing each color from 3 bytes to 1 byte, I can theoretically triple the throughput (if I don't hit some other bottleneck).
Right now I can top at around 16fps without lag or delay. Anything faster and I can see the helmet fail to keep up. I can stop the animation and see the helmet still playing back buffered frame data.
Start with that idea, but use the last two bits as an intensity for all three. That gives you colour mix, plus intensity control, all in one byte per LED. Unpacking to three bytes, though, will be fiddly. Start with the intensity setting the high two bits of all three bytes, then map in each bit pair as you see fit.
But, a LUT will be much, much faster.
No: because 2 bits per colour is a total of just 6 bits; so just 64 colours - you are "wasting" 2 bits in each byte.
With a lookup table, you don't have to allocate specific numbers of bits to each colour, or have any algorithmic relation between the byte value and the colour - you could just have a "palette" of 256 random colours.
Yeah it's starting to seems like a look up table might be the best option after all.
Before I commit to that, I don't suppose there might exist an algorithmic method of creating a color table? Also someone said that a look up table would be faster? I've seen some doom and quake dev videos where devs always talk about some calculation being too costly and they in turn rely on a lookup table for pre-calculated values.
How can a look up table be faster than calculating on the spot?