diff --git a/nightlight/nightlight.ino b/nightlight/nightlight.ino index a0bb2e6..bd5339b 100644 --- a/nightlight/nightlight.ino +++ b/nightlight/nightlight.ino @@ -1,140 +1,256 @@ +// https://lastminuteengineers.com/rotary-encoder-arduino-tutorial/ + #include -#define COLORSTEPS 24 -#define PIN D2 #define NUMPIXELS 12 +#define LEDPIN D1 + +Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800); + +// Rotary Encoder Inputs +#define CLK D5 +#define DT D6 +#define SW D7 + +#define CLK2 D2 +#define DT2 D3 +#define SW2 D4 + +int currentStateCLK; +int currentStateCLK2; +int lastStateCLK; +int lastStateCLK2; +String currentDir = ""; +int btnState = 1; +int btnState2 = 1; +int lastBtnState = 1; +int lastBtnState2 = 1; +bool pressed = false; +bool isOn = false; +bool rotated = false; +//unsigned long lastButtonPress = 0; + + + +#define HUE_STEP 1200 +#define VAL_STEP 10 + +long hue = 0; // 0-65535 https://adafruit.github.io/Adafruit_NeoPixel/html/class_adafruit___neo_pixel.html#a1f16aee5b96e16e62598f826e292b23b +int saturation = 0; // 0-255 +int value = 0; // 0-255 -Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); -int ledstate[NUMPIXELS]; void setup() { Serial.begin(115200); - delay(150); - Serial.println("PIXELS"); + + pinMode(CLK,INPUT); + pinMode(DT,INPUT); + pinMode(SW, INPUT_PULLUP); + // Read the initial state of CLK + lastStateCLK = digitalRead(CLK); + + Serial.println("PIXELS"); pixels.begin(); // initialize NeoPixel library. - pixels.setBrightness(40); - for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) { - pixels.rainbow(firstPixelHue); + fade(200); + + hue = 4800; + saturation = 255; + value = 60; + pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, 0)), 0, NUMPIXELS); + pixels.show(); +} + +void fade(int maxValue) { + for (int fval = 0; fval <= maxValue; fval++) { + pixels.fill(pixels.gamma32(pixels.ColorHSV(0, 0, fval)), 0, NUMPIXELS); pixels.show(); delay(10); } - - //rainbow(); + for (int fval = maxValue; fval >= 0; fval--) { + pixels.fill(pixels.gamma32(pixels.ColorHSV(0, 0, fval)), 0, NUMPIXELS); + pixels.show(); + delay(10); + } + pixels.clear(); + pixels.show(); } -void rainbow() { - pixels.setBrightness(10); - - for (int i = 0; i < NUMPIXELS; i++) { - ledstate[i] = 0; - } - - int increment = 65536 / COLORSTEPS; - - while (ledstate[NUMPIXELS-1] < 65536) { - - // find first inactive pixel, if any - int ix = NUMPIXELS-1; - while (ix > 0 and ledstate[ix-1] == 0) { - ix--; - } - - for (int iy = ix; iy >= 0; iy--) { - ledstate[iy] = ledstate[iy] + increment; - } - - for (int i = 0; i < NUMPIXELS; i++) { - if (ledstate[i] < 65536 and i <= ix) { - pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(ledstate[i]))); - } - else { - pixels.setPixelColor(i, 0, 0, 0); - } - } - - pixels.show(); - - delay(50); - } - - delay(1000); - - pixels.setPixelColor(1, pixels.Color(1, 1, 1)); - pixels.setPixelColor(2, pixels.Color(31, 31, 31)); - pixels.setPixelColor(3, pixels.Color(63, 63, 63)); - pixels.setPixelColor(4, pixels.Color(95, 95, 95)); - pixels.setPixelColor(5, pixels.Color(127, 127, 127)); - pixels.setPixelColor(6, pixels.Color(159, 159, 159)); - pixels.setPixelColor(7, pixels.Color(191, 191, 191)); - pixels.setPixelColor(8, pixels.Color(223, 223, 223)); - pixels.setPixelColor(9, pixels.Color(255, 255, 255)); - pixels.show(); - - delay(3000); - - for (int i = 30; i < 256; i++) { - for (int j = 0; j < NUMPIXELS; j++) { - pixels.setPixelColor(j, pixels.Color(i, i, i)); +/*void rainbow(int wait) { + for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) { + for(int i=0; i 65535) { + hue = 65535; + saturation = 0; + } + else { + saturation = 255; + } + } + else { + value += VAL_STEP; + if (value > 255) { + value = 255; + } + } + } else { + currentDir ="CCW"; + if (btnState == LOW) { + hue -= HUE_STEP; + if (hue < 0) { + hue = 0; + saturation = 0; + } + else { + saturation = 255; + } + } + else { + value -= VAL_STEP; + if (value < 30) { + value = 0; + } + } + } + + if (value > 0) { + isOn = true; + } + else { + isOn = false; + } + + pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, value)), 0, NUMPIXELS); + pixels.show(); + + Serial.print("Direction: "); + Serial.print(currentDir); + Serial.print(" | Hue: "); + Serial.print(hue); + Serial.print(" | Sat: "); + Serial.print(saturation); + Serial.print(" | Val: "); + Serial.println(value); + } + else if (currentStateCLK2 != lastStateCLK2 && currentStateCLK2 == 1) { + rotated = true; + btnState2 = digitalRead(SW2); + + if (digitalRead(DT2) != currentStateCLK2) { + currentDir ="CW"; + if (btnState2 == LOW && isOn) { + hue += HUE_STEP; + if (hue > 65535) { + hue = 65535; + saturation = 0; + } + else { + saturation = 255; + } + } + else { + value += VAL_STEP; + if (value > 255) { + value = 255; + } + } + } else { + currentDir ="CCW"; + if (btnState2 == LOW) { + hue -= HUE_STEP; + if (hue < 0) { + hue = 0; + saturation = 0; + } + else { + saturation = 255; + } + } + else { + value -= VAL_STEP; + if (value < 30) { + value = 0; + } + } + } + + if (value > 0) { + isOn = true; + } + else { + isOn = false; + } + + pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, value)), 0, NUMPIXELS); + pixels.show(); + + Serial.print("Direction 2: "); + Serial.print(currentDir); + Serial.print(" | Button State: "); + Serial.print(btnState2); + Serial.print(" | Hue: "); + Serial.print(hue); + Serial.print(" | Sat: "); + Serial.print(saturation); + Serial.print(" | Val: "); + Serial.println(value); + } + else { + btnState = digitalRead(SW); + btnState2 = digitalRead(SW2); + + if (btnState == 0 || btnState2 == 0) { + pressed = true; + } + else { + if (rotated) { + rotated = false; + pressed = false; + } + else if (pressed) { + if (isOn) { + pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, 0)), 0, NUMPIXELS); + pixels.show(); + isOn = false; + Serial.println("off"); + } + else { + pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, value)), 0, NUMPIXELS); + pixels.show(); + isOn = true; + Serial.println("on"); + } + pressed = false; + } + } + } + + lastStateCLK = currentStateCLK; + lastStateCLK2 = currentStateCLK2; + + // Put in a slight delay to help debounce the reading + delay(1); }