#include<math.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define LED_PIN 0
#define NUM_LEDS 60
#define BRIGHTNESS 127
#define MAX_TEMP 6600
#define MIN_TEMP 1000
#define TIMESTEP 5 // ms
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
double t;
void setup() {
// This is for Trinket 5V 16MHz
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// Clear LED strip
strip.begin();
strip.setBrightness(127);
strip.show();
t = 0.0;
}
void loop() {
double sin_value = sin(t);
int temp = lround(sin_value * sin_value * (MAX_TEMP - MIN_TEMP) + MIN_TEMP);
uint32_t rgb = color(temp);
setAllPixels(rgb);
t += TIMESTEP / 1000.0;
delay(TIMESTEP);
}
void setAllPixels(uint32_t rgb) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, rgb);
}
strip.show();
}
// Kelvin color curve
// based from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
// and http://www.zombieprototypes.com/?p=210
uint32_t color(int temp) {
double red = 0;
if (temp < 6600) {
red = 255;
} else {
// a + b x + c Log[x] /.
// {a -> 351.97690566805693`,
// b -> 0.114206453784165`,
// c -> -40.25366309332127
//x -> (kelvin/100) - 55}
red = temp / 100 - 55;
red = 351.97690566805693 + 0.114206453784165 * red - 40.25366309332127 * log(red);
if (red < 0) {
red = 0;
}
if (red > 255) {
red = 255;
}
}
/* Calculate green */
double green = 0;
if (temp < 6600) {
// a + b x + c Log[x] /.
// {a -> -155.25485562709179`,
// b -> -0.44596950469579133`,
// c -> 104.49216199393888`,
// x -> (kelvin/100) - 2}
green = temp / 100 - 2;
green = -155.25485562709179 - 0.44596950469579133 * green + 104.49216199393888 * log(green);
if (green < 0) green = 0;
if (green > 255) green = 255;
} else {
// a + b x + c Log[x] /.
// {a -> 325.4494125711974`,
// b -> 0.07943456536662342`,
// c -> -28.0852963507957`,
// x -> (kelvin/100) - 50}
green = temp / 100 - 50;
green = 325.4494125711974 + 0.07943456536662342 * green - 28.0852963507957 * log(green);
if (green < 0) green = 0;
if (green > 255) green = 255;
}
/* Calculate blue */
double blue = 0;
if (temp >= 6600) {
blue = 255;
} else {
if (temp <= 2000) {
blue = 0;
} else {
// a + b x + c Log[x] /.
// {a -> -254.76935184120902`,
// b -> 0.8274096064007395`,
// c -> 115.67994401066147`,
// x -> kelvin/100 - 10}
blue = temp / 100 - 10;
blue = -254.76935184120902 + 0.8274096064007395 * blue + 115.67994401066147 * log(blue);
if (blue < 0) blue = 0;
if (blue > 255) blue = 255;
}
}
// Combine colors and return
return strip.Color(lround(red), lround(green), lround(blue));
}