#define BUTTON 1 #define RED 9 #define GREEN 11 #define BLUE 13 #define LIGHT A0 //#include void setup() { // put your setup code here, to run once: pinMode(RED, INPUT); pinMode(GREEN, INPUT); pinMode(BLUE, INPUT); pinMode(LIGHT, INPUT); pinMode(BUTTON, INPUT); if(digitalRead(BUTTON) == 1) { delay(500); // go to bootloader? } } //bool enable_light = true; void loop() { processInput(); // sets modes and sets up next steps //huetorgb(); // convert from set hue to RGB render(); // output to RGB led based on mode and other settings /*bool change_wait = false; if(digitalRead(BUTTON) == 1) { if(enable_light) { enable_light = false; } else { enable_light = true; } change_wait = true; } float sensor_voltage = analogRead(LIGHT) * 5 / 1024.0; // turn lamp on if (sensor_voltage <= 2.5 && enable_light) { pinMode(RED, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(BLUE, OUTPUT); analogWrite(RED, 0xFF); analogWrite(GREEN, 0x90); analogWrite(BLUE, 0x90); */ /*for(int i = 0; i < 256; i++) { CRGB color = CHSV(0,0,0); hsv2rgb_rainbow(CHSV(i, 255, 255), color); analogWrite(RED, color.r); analogWrite(GREEN, color.g); analogWrite(BLUE, color.b); } } else { // turn lamp off pinMode(RED, INPUT); pinMode(GREEN, INPUT); pinMode(BLUE, INPUT); } analogWrite(RED, 0xFF); delay(1000); analogWrite(GREEN, 0xFF); delay(1000); analogWrite(BLUE, 0xFF); delay(1000);*/ /*delay(50); if(change_wait) { delay(450); }*/ } int mode = 0; int setmode = 0; // Mode list #define NIGHTLIGHT 0 #define MANUALLIGHT 1 #define RGBSMOOTH 2 #define RGBDEFINED 3 #define SETCOLOR 4 #define DYNAMICLIGHT 5 #define SETTINGSMAIN 6 #define SETTINGSMODE 7 #define SETTINGSTEMP 8 #define SETTINGSCOLOR 9 int nextsetting = SETTINGSMODE; int yellowness = 0; // for modes 0,1,5, color temperature int red = 0xFF; // for mode 4 int green = 0x90; int blue = 0x90; int hue = 0; int sethue = 0; int flickeroffset = 0; bool enabled = true; bool oldpress; bool oldpresstime; int sensor = 0; void processInput() { bool press = digitalRead(BUTTON); if (press != oldpress) { // state change if (press) { // suddenly pressed oldpresstime = millis(); // start timer } else { // button just let go, let's do something if (millis() - oldpresstime < 750) { // short press shortpress(); } // we don't need to check for longpress because that is handled below } } else { if (press && millis() - oldpresstime > 750) { // button held, but not let go yet longpress(); oldpresstime = millis(); // reset timer } } oldpress = press; sensor = (analogRead(LIGHT) * 100) / 1024; } void toggle() { if(enabled) { enabled = false; } else { enabled = true; } } void shortpress() { switch(mode) { case NIGHTLIGHT: toggle(); break; case MANUALLIGHT: toggle(); break; case RGBSMOOTH: toggle(); break; case RGBDEFINED: toggle(); break; case SETCOLOR: toggle(); break; case DYNAMICLIGHT: toggle(); break; case SETTINGSMAIN: nextsetting++; if(nextsetting > SETTINGSCOLOR) { nextsetting = SETTINGSMAIN; // 'exit' } flickeroffset = millis() % 750; break; case SETTINGSMODE: nextsetting++; if(nextsetting > DYNAMICLIGHT) { nextsetting = NIGHTLIGHT; } flickeroffset = millis() % 750; break; case SETTINGSTEMP: yellowness += 8; if (yellowness > 128) { yellowness = 0; } break; case SETTINGSCOLOR: hue += 15; if (hue > 255) { hue = 0; } break; default: mode = 0; // in case of impossible mode, return to mode 0 break; } } void longpress() { switch(mode) { case NIGHTLIGHT: mode = SETTINGSMAIN; break; case MANUALLIGHT: mode = SETTINGSMAIN; nextsetting = SETTINGSMODE; break; case RGBSMOOTH: mode = SETTINGSMAIN; nextsetting = SETTINGSMODE; break; case RGBDEFINED: mode = SETTINGSMAIN; nextsetting = SETTINGSMODE; break; case SETCOLOR: mode = SETTINGSMAIN; nextsetting = SETTINGSMODE; break; case DYNAMICLIGHT: mode = SETTINGSMAIN; nextsetting = SETTINGSMODE; break; case SETTINGSMAIN: if(nextsetting == SETTINGSMAIN) { mode = setmode; // exit settings requested, return to set mode } else { mode = nextsetting; // set new mode to the highlighted settings page if (mode == SETTINGSMODE) { // if it's the set mode page, then nextsetting needs to be prepared nextsetting = 0; } } break; case SETTINGSMODE: setmode = nextsetting; // save set mode mode = setmode; // and go to it break; case SETTINGSTEMP: // yellowness already set directly mode = setmode; // so we just leave break; case SETTINGSCOLOR: // color already set directly mode = setmode; // so we just leave sethue = hue; break; default: mode = 0; // in case of impossible mode, return to mode 0 break; } } void huetorgb(int tmphue, int tmpsat, int tmpval) { // this is the algorithm to convert from RGB to HSV byte redlight; byte greenlight; byte bluelight; byte h = tmphue; byte s = tmpsat; byte v = tmpval; h = (h * 192) / 256; // 0..191 unsigned int i = h / 32; // We want a value of 0 thru 5 unsigned int f = (h % 32) * 8; // 'fractional' part of 'i' 0..248 in jumps unsigned int sInv = 255 - s; // 0 -> 0xff, 0xff -> 0 unsigned int fInv = 255 - f; // 0 -> 0xff, 0xff -> 0 byte pv = v * sInv / 256; // pv will be in range 0 - 255 byte qv = v * (256 - s * f / 256) / 256; byte tv = v * (256 - s * fInv / 256) / 256; switch (i) { case 0: redlight = v; greenlight = tv; bluelight = pv; break; case 1: redlight = qv; greenlight = v; bluelight = pv; break; case 2: redlight = pv; greenlight = v; bluelight = tv; break; case 3: redlight = pv; greenlight = qv; bluelight = v; break; case 4: redlight = tv; greenlight = pv; bluelight = v; break; case 5: redlight = v; greenlight = pv; bluelight = qv; break; } red = redlight; blue = bluelight; green = greenlight; } //analogWrite(RED, 0xFE); //analogWrite(GREEN, 0x30); //analogWrite(BLUE, 0x10); void turnon(int tmpred, int tmpgreen, int tmpblue) { pinMode(RED, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(BLUE, OUTPUT); analogWrite(RED, tmpred); analogWrite(GREEN, tmpgreen); analogWrite(BLUE, tmpblue); } void flicker(int tmpred, int tmpgreen, int tmpblue) { if ((millis() + flickeroffset) % 750 > 700) { turnoff(); } else { turnon(tmpred, tmpgreen, tmpblue); } } void turnoff() { pinMode(RED, INPUT); // the red pin is also used for programming, so there has to be a state when the pin is set to input pinMode(GREEN, INPUT); // so we make the pins input when the light is off pinMode(BLUE, INPUT); } void temperaturize() { } void render() { switch(mode) { case NIGHTLIGHT: if(enabled) { if(sensor > 50) { huetorgb(35, yellowness, 255); // 35: yellow if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; turnon(red, green, blue); } } else { turnoff(); } break; case MANUALLIGHT: if(enabled) { huetorgb(35, yellowness, 255); // 35: yellow if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; turnon(red, green, blue); } else { turnoff(); } break; case RGBSMOOTH: if(enabled) { hue ++; if(hue > 255) { hue = 0; } huetorgb(hue, 255, 255); if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; turnon(red, green, blue); } else { turnoff(); } break; case RGBDEFINED: if(enabled) { hue ++; if(hue > 255) { hue = 0; } int tmphue = (hue % 25) * 10; huetorgb(tmphue, 255, 255); if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; turnon(red, green, blue); } else { turnoff(); } break; case SETCOLOR: if(enabled) { huetorgb(sethue, 255, 255); if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; turnon(red, green, blue); } else { turnoff(); } break; case DYNAMICLIGHT: if(enabled) { float brightness = 1.0 - sensor / 100.0; huetorgb(35, yellowness, 255); // 35: yellow red *= brightness; green *= brightness; blue *= brightness; turnon(red, green, blue); } else { turnoff(); } break; case SETTINGSMAIN: switch(nextsetting) { // colorize based on selected setting case SETTINGSMODE: flicker(255, 0, 0); break; case SETTINGSTEMP: flicker(0, 255, 0); break; case SETTINGSCOLOR: flicker(0, 0, 255); break; case SETTINGSMAIN: flicker(255, 150, 150); break; } break; case SETTINGSMODE: switch(nextsetting) { // animate / colorize based on selected mode case NIGHTLIGHT: flicker(255, 150, 150); break; case MANUALLIGHT: flicker(0, 255, 0); break; case RGBSMOOTH: hue += 5; if(hue > 255) { hue = 0; } huetorgb(hue, 255, 255); if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; flicker(red, green, blue); break; case RGBDEFINED: hue += 2; if(hue > 255) { hue = 0; } int tmphue = (hue % 25) * 10; huetorgb(tmphue, 255, 255); if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; flicker(red, green, blue); break; case SETCOLOR: flicker(255, 0, 0); break; case DYNAMICLIGHT: float brightness = 1.0 - (millis() % 1000) / 1000.0; huetorgb(35, yellowness, 255); // 35: yellow red *= brightness; green *= brightness; blue *= brightness; turnon(red, green, blue); break; } break; case SETTINGSTEMP: huetorgb(35, yellowness, 255); // 35: yellow if (green > 200) green -= 100; // color correction if (blue > 200) blue -= 100; flicker(red, green, blue); break; case SETTINGSCOLOR: huetorgb(hue, 255, 255); flicker(red, green, blue); break; default: mode = 0; // in case of impossible mode, return to mode 0 break; } }