Skip to content

Instantly share code, notes, and snippets.

@ghstwhl
Forked from devries/rainbling.ino
Last active May 10, 2016 04:23
Show Gist options
  • Save ghstwhl/7e3fc4265685ba570e672fe907939f98 to your computer and use it in GitHub Desktop.
Save ghstwhl/7e3fc4265685ba570e672fe907939f98 to your computer and use it in GitHub Desktop.
Rainbling: A Total Control Lighting Arduino Sketch for rainbows with flashes.
/**************************************************************
* rainbling.ino
*
* An idea for having rainbow colors appear in groups (totems)
* with occasional flashes.
***************************************************************/
#include <SPI.h>
#include <TCL.h>
const int REPEATS = 24;
const int TOTEMS = 25;
const int LEDS_PER_TOTEM = 2;
byte gamma_table[256];
const float gamma = 2.2;
const float hinterval_max = 10.0;
const float v_max = 0.99;
const float sat_max = 1.0;
const int flash_prob_max=20480;
byte totem_color[TOTEMS][3];
float totem_interval;
float hval;
void setup() {
int i;
totem_interval = 360.0/TOTEMS;
hval = 0.0;
TCL.begin();
TCL.setupDeveloperShield();
for(i=0;i<TOTEMS;i++) {
totem_color[i][0]=0x00;
totem_color[i][1]=0x00;
totem_color[i][2]=0x00;
}
update_strand();
for(i=0;i<256;i++) {
gamma_table[i] = (byte)(pow(i/255.0,gamma)*255.0+0.5);
}
}
void loop() {
int i;
float local_h;
int speed_pot;
int brightness_pot;
int saturation_pot;
int flash_pot;
float hinterval;
float sat;
float v;
float flash_prob;
speed_pot = analogRead(TCL_POT1);
brightness_pot = analogRead(TCL_POT2);
saturation_pot = analogRead(TCL_POT3);
flash_pot = analogRead(TCL_POT4);
v = v_max/1023.0*brightness_pot;
sat = sat_max/1023.0*saturation_pot;
for(i=0;i<TOTEMS;i++) {
local_h = hval+i*totem_interval;
while(local_h>=360.0) {
local_h-=360.0;
}
if(random(flash_prob_max)<flash_pot) {
totem_color[i][0]=255;
totem_color[i][1]=255;
totem_color[i][2]=255;
}
else {
HSVtoRGB(local_h,sat,v,&totem_color[i][0],&totem_color[i][1],&totem_color[i][2]);
}
}
update_strand();
delay(25);
hinterval = hinterval_max/1023.0*speed_pot;
hval+=hinterval;
while(hval>=360.0) {
hval-=360.0;
}
}
void update_strand() {
int i;
int j;
int k;
TCL.sendEmptyFrame();
for(k=0;k<REPEATS;k++) {
for(i=0;i<TOTEMS;i++) {
for(j=0;j<LEDS_PER_TOTEM;j++) {
TCL.sendColor(gamma_table[totem_color[i][0]],gamma_table[totem_color[i][1]],gamma_table[totem_color[i][2]]);
}
}
}
TCL.sendEmptyFrame();
TCL.sendEmptyFrame();
}
/* Convert hsv values (0<=h<360, 0<=s<=1, 0<=v<=1) to rgb values (0<=r<=255, etc) */
void HSVtoRGB(float h, float s, float v, byte *r, byte *g, byte *b) {
int i;
float f, p, q, t;
float r_f, g_f, b_f;
if( s < 1.0e-6 ) {
/* grey */
r_f = g_f = b_f = v;
}
else {
h /= 60.0; /* Divide into 6 regions (0-5) */
i = (int)floor( h );
f = h - (float)i; /* fractional part of h */
p = v * ( 1.0 - s );
q = v * ( 1.0 - s * f );
t = v * ( 1.0 - s * ( 1.0 - f ) );
switch( i ) {
case 0:
r_f = v;
g_f = t;
b_f = p;
break;
case 1:
r_f = q;
g_f = v;
b_f = p;
break;
case 2:
r_f = p;
g_f = v;
b_f = t;
break;
case 3:
r_f = p;
g_f = q;
b_f = v;
break;
case 4:
r_f = t;
g_f = p;
b_f = v;
break;
default: // case 5:
r_f = v;
g_f = p;
b_f = q;
break;
}
}
*r = (byte)floor(r_f*255.99);
*g = (byte)floor(g_f*255.99);
*b = (byte)floor(b_f*255.99);
}
@ghstwhl
Copy link
Author

ghstwhl commented May 10, 2016

This version fixes an off-by-one bug with the gamma_table array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment