From 57f5408b5be2d98d74774d23c9a44f9cb5b00d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 2 Apr 2017 00:04:29 +0200 Subject: [PATCH] Added temperature to RGB calculation. Thanks to Sacha Telgenhof --- code/espurna/config/general.h | 1 + code/espurna/light.ino | 43 +++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 06f85a0f..26696471 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -233,6 +233,7 @@ #define LIGHT_DEFAULT_COLOR "#000080" #define LIGHT_SAVE_DELAY 5 +#define LIGHT_MAX_VALUE 255 #define MY9291_DI_PIN 13 #define MY9291_DCKI_PIN 15 diff --git a/code/espurna/light.ino b/code/espurna/light.ino index d99f9c96..2449a923 100644 --- a/code/espurna/light.ino +++ b/code/espurna/light.ino @@ -36,6 +36,13 @@ void color_string2array(const char * rgb, unsigned int * array) { array[1] = (value >> 8) & 0xFF; array[2] = (value) & 0xFF; + // it's a temperature + } else if (p[strlen(p)-1] == 'K') { + + p[strlen(p)-1] = 0; + unsigned int temperature = atoi(p); + color_temperature2array(temperature, array); + // otherwise assume decimal values separated by commas } else { @@ -70,6 +77,32 @@ void color_array2rgb(unsigned int * array, char * rgb) { sprintf(rgb, "#%06X", value); } +// Thanks to Sacha Telgenhof for sharing this code in his AiLight library +// https://github.com/stelgenhof/AiLight +void color_temperature2array(unsigned int temperature, unsigned int * array) { + + // Force boundaries and conversion + temperature = constrain(temperature, 1000, 40000) / 100; + + // Calculate colors + unsigned int red = (temperature <= 66) + ? LIGHT_MAX_VALUE + : 329.698727446 * pow((temperature - 60), -0.1332047592); + unsigned int green = (temperature <= 66) + ? 99.4708025861 * log(temperature) - 161.1195681661 + : 288.1221695283 * pow(temperature, -0.0755148492); + unsigned int blue = (temperature >= 66) + ? LIGHT_MAX_VALUE + : ((temperature <= 19) + ? 0 + : 138.5177312231 * log(temperature - 10) - 305.0447927307); + + // Save values + array[0] = constrain(red, 0, LIGHT_MAX_VALUE); + array[1] = constrain(green, 0, LIGHT_MAX_VALUE); + array[2] = constrain(blue, 0, LIGHT_MAX_VALUE); +} + // ----------------------------------------------------------------------------- // PROVIDER // ----------------------------------------------------------------------------- @@ -104,11 +137,11 @@ void _lightProviderSet(bool state, unsigned int red, unsigned int green, unsigne analogWrite(RGBW_WHITE_PIN, white); #endif } else { - analogWrite(RGBW_RED_PIN, 255 - red); - analogWrite(RGBW_GREEN_PIN, 255 - green); - analogWrite(RGBW_BLUE_PIN, 255 - blue); + analogWrite(RGBW_RED_PIN, LIGHT_MAX_VALUE - red); + analogWrite(RGBW_GREEN_PIN, LIGHT_MAX_VALUE - green); + analogWrite(RGBW_BLUE_PIN, LIGHT_MAX_VALUE - blue); #if (LIGHT_PROVIDER == LIGHT_PROVIDER_RGBW) - analogWrite(RGBW_WHITE_PIN, 255 - white); + analogWrite(RGBW_WHITE_PIN, LIGHT_MAX_VALUE - white); #endif } #endif @@ -203,7 +236,7 @@ void lightSetup() { #endif #if (LIGHT_PROVIDER == LIGHT_PROVIDER_RGB) || (LIGHT_PROVIDER == LIGHT_PROVIDER_RGBW) - analogWriteRange(255); + analogWriteRange(LIGHT_MAX_VALUE); analogWriteFreq(1000); pinMode(RGBW_RED_PIN, OUTPUT); pinMode(RGBW_GREEN_PIN, OUTPUT);