Last active
November 4, 2017 19:10
-
-
Save jameslzhu/2f90b55c2d6d106d839e29c2f8513991 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment