Skip to content

Instantly share code, notes, and snippets.

@probonopd
Created July 13, 2015 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save probonopd/7f9c8fe785ba52600a99 to your computer and use it in GitHub Desktop.
Save probonopd/7f9c8fe785ba52600a99 to your computer and use it in GitHub Desktop.
// https://github.com/kayno/arduinolifx
#include <math.h>
struct rgb {
double r; // percent
double g; // percent
double b; // percent
};
rgb kelvinToRGB(long kelvin) {
rgb kelvin_rgb;
long temperature = kelvin / 100;
if(temperature <= 66) {
kelvin_rgb.r = 255;
}
else {
kelvin_rgb.r = temperature - 60;
kelvin_rgb.r = 329.698727446 * pow(kelvin_rgb.r, -0.1332047592);
if(kelvin_rgb.r < 0) kelvin_rgb.r = 0;
if(kelvin_rgb.r > 255) kelvin_rgb.r = 255;
}
if(temperature <= 66) {
kelvin_rgb.g = temperature;
kelvin_rgb.g = 99.4708025861 * log(kelvin_rgb.g) - 161.1195681661;
if(kelvin_rgb.g < 0) kelvin_rgb.g = 0;
if(kelvin_rgb.g > 255) kelvin_rgb.g = 255;
}
else {
kelvin_rgb.g = temperature - 60;
kelvin_rgb.g = 288.1221695283 * pow(kelvin_rgb.g, -0.0755148492);
if(kelvin_rgb.g < 0) kelvin_rgb.g = 0;
if(kelvin_rgb.g > 255) kelvin_rgb.g = 255;
}
if(temperature >= 66) {
kelvin_rgb.b = 255;
}
else {
if(temperature <= 19) {
kelvin_rgb.b = 0;
}
else {
kelvin_rgb.b = temperature - 10;
kelvin_rgb.b = 138.5177312231 * log(kelvin_rgb.b) - 305.0447927307;
if(kelvin_rgb.b < 0) kelvin_rgb.b = 0;
if(kelvin_rgb.b > 255) kelvin_rgb.b = 255;
}
}
return kelvin_rgb;
}
#include "kelvin.h"
#include <NeoPixelBus.h> // INPORTANT_ Use the normal branch not the animator branch!
// Cycle through different Kelvin color temperatures
// his works on ESP2866
// TODO: Calibrate and automate over daytime
#define pixelCount 30
NeoPixelBus strip = NeoPixelBus(pixelCount, 2); // GPIO2
unsigned int transitionTime = 400; // by default there is a transition time to the new state of 400 milliseconds
unsigned long previousMillis = 0;
const long interval = 2000;
int kelvin;
void setup() {
// this resets all the neopixels to an off state
strip.Begin();
strip.Show();
long kelvin;
Serial.begin(115200);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (kelvin < 2200) kelvin = 2200;
if (kelvin > 3200) kelvin = 2200;
setToKelvin(kelvin);
kelvin = kelvin + 200;
}
// Start animating the NeoPixels
strip.StartAnimating();
// Wait until no more animations are running
// FIXME: This seems to block everything while a transition is running
// Can we run this in a separate thread, in "the background"?
while (strip.IsAnimating())
{
strip.UpdateAnimations();
strip.Show();
delay(31); // ~30hz change cycle
}
}
void setToKelvin(int kelvin)
{
Serial.print("Kelvin: ");
Serial.println(kelvin);
uint8_t r = kelvinToRGB(kelvin).r;
uint8_t g = kelvinToRGB(kelvin).g;
uint8_t b = kelvinToRGB(kelvin).b;
// I need to correct for too much reddish (FIXME; calibrate)
// g = g + 25;
// g = constrain(g, 0, 255);
Serial.print("RGB: ");
Serial.print(r);
Serial.print(", ");
Serial.print(g);
Serial.print(", ");
Serial.println(b);
Serial.println();
RgbColor converted = RgbColor(r, g, b);
for (int i = 0; i < pixelCount ; i++)
{
strip.LinearFadePixelColor(transitionTime, i, converted);
}
strip.Show();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment