Zápisník experimentátora
I found an interesting article on how to set the gamma correction for LED diodes. The article publishes a known table of 256 values that allow to adjust the brightness of the LED for human eyes. I myself have used the table several times (LED strip dimmer, 1W LED dimmer), but I did not even know the author who created the table. Only when I found this page, I understood what formula was used.
There is a source code for the Processing, that will create this table. I tried to rewrite the code for Arduino and this is the result. I wrote two programs (sketches). The first is an exact copy of the original code. The second code creates the same table in 16-bit resolution.
The exact transcription of the original source code. The result is a table of 8-bit values.
float gamma = 2.8; // Correction factor
uint16_t max_in = 255; // Top end of INPUT range
uint16_t max_out = 255; // Top end of OUTPUT range
char output[10];
void setup() {
Serial.begin(9600);
Serial.print("const uint8_t PROGMEM gamma[] = {");
for (int i = 0; i <= max_in; i++) {
if (i > 0) Serial.print(',');
if ((i % 16) == 0) Serial.print("\n ");
sprintf(output, "%3u", (uint16_t)(pow((float)i / (float)max_in, gamma) * max_out + 0.5));
Serial.print(output);
}
Serial.println("");
Serial.println(" };");
}
void loop() {
}
Result
const uint8_t PROGMEM gamma[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
This program creates a table in 16-bit resolution. I'm planning to improve my code using this table. See the details in the article 16-bit PWM using timer1.
float gamma = 2.8; // Correction factor
uint16_t max_in = 255; // Top end of INPUT range
uint16_t max_out = 65535; // Top end of OUTPUT range
char output[10];
void setup() {
Serial.begin(9600);
Serial.print("const uint16_t PROGMEM gamma[] = {");
for (int i = 0; i <= max_in; i++) {
if (i > 0) Serial.print(',');
if ((i % 16) == 0) Serial.print("\n ");
sprintf(output, "%5u", (uint16_t)(pow((float)i / (float)max_in, gamma) * max_out + 0.5));
Serial.print(output);
}
Serial.println("");
Serial.println(" };");
}
void loop() {
}
Result
const uint16_t PROGMEM gamma[] = { 0, 0, 0, 0, 1, 1, 2, 3, 4, 6, 8, 10, 13, 16, 19, 24, 28, 33, 39, 46, 53, 60, 69, 78, 88, 98, 110, 122, 135, 149, 164, 179, 196, 214, 232, 252, 273, 295, 317, 341, 366, 393, 420, 449, 478, 510, 542, 575, 610, 647, 684, 723, 764, 806, 849, 894, 940, 988, 1037, 1088, 1140, 1194, 1250, 1307, 1366, 1427, 1489, 1553, 1619, 1686, 1756, 1827, 1900, 1975, 2051, 2130, 2210, 2293, 2377, 2463, 2552, 2642, 2734, 2829, 2925, 3024, 3124, 3227, 3332, 3439, 3548, 3660, 3774, 3890, 4008, 4128, 4251, 4376, 4504, 4634, 4766, 4901, 5038, 5177, 5319, 5464, 5611, 5760, 5912, 6067, 6224, 6384, 6546, 6711, 6879, 7049, 7222, 7397, 7576, 7757, 7941, 8128, 8317, 8509, 8704, 8902, 9103, 9307, 9514, 9723, 9936,10151,10370,10591,10816,11043,11274,11507,11744,11984,12227,12473,12722,12975, 13230,13489,13751,14017,14285,14557,14833,15111,15393,15678,15967,16259,16554,16853,17155,17461, 17770,18083,18399,18719,19042,19369,19700,20034,20372,20713,21058,21407,21759,22115,22475,22838, 23206,23577,23952,24330,24713,25099,25489,25884,26282,26683,27089,27499,27913,28330,28752,29178, 29608,30041,30479,30921,31367,31818,32272,32730,33193,33660,34131,34606,35085,35569,36057,36549, 37046,37547,38052,38561,39075,39593,40116,40643,41175,41711,42251,42796,43346,43899,44458,45021, 45588,46161,46737,47319,47905,48495,49091,49691,50295,50905,51519,52138,52761,53390,54023,54661, 55303,55951,56604,57261,57923,58590,59262,59939,60621,61308,62000,62697,63399,64106,64818,65535 };
The source code is located on the GitHub server.
03.08.2017