#define DEBUG
#include "INHK_Pot3.h"
#include "ButtonControl.h"
#include <FastLED.h>
FASTLED_USING_NAMESPACE
#define NUM_LEDS 120
#define LED_PIN 11
#define ENVELOPE_PIN A0 // Envelope Pin of the Sparkfun Sound Detector Module
#define LED_TYPE WS2812B // WS2801, WS2811, WS2812B, LPD8806, TM1809, etc...
#define COLOR_ORDER GRB // Default Color Order
#define HUE_INIT 10 // < 25
#define HUE_CHANGE 2 // < 255
int minVal = 20; // Min: 0, Max: 75
int maxVal = 300; // Min: 75, Max: 750
/////////////////////////////////////////////////////////////////// LED ////////////
uint8_t style = 0;
/*============= SELECT STYLE =============*/
/* */
/* 0 --> LinearFlowing (BEST) */
/* 1 --> LinearReactive */
/* 2 --> BrightnessReactive */
/* 3 --> CentreProgressive */
/* 4 --> EdgeProgressive */
CRGB leds[NUM_LEDS];
uint8_t brightness = 50;
uint8_t hue = 100;
uint8_t changingHue = 100;
uint8_t saturation = 255;
uint8_t value = 255;
uint8_t red;
uint8_t green;
uint8_t blue;
byte dynamicHue = HUE_INIT;
int analogVal = 0; // variable that captures loudness CRGB::LavenderBlush
int val = 0; // variable used to scale analogVal above
/////////////////////////////////////////////////////////////////// CONTROLS ////////////
Potentiometer slider(A1,2); // brightness control
Potentiometer pot1(A2,2); // red/hue control
Potentiometer pot2(A3,2); // green/saturation control
Potentiometer pot3(A4,2); // blue/vlaue control
ButtonControl button1(10);
ButtonControl button2(8);
ButtonControl button3(7);
ButtonControl button4(6);
ButtonControl button5(5);
/////////////////////////////////////////////////////////////////// MODE LISTS ////////////
enum Mode {
FIXED,
CHANGING,
MUSIC
};
Mode currentMode = FIXED;
enum ColourControl{
RGB_MODE,
HSV_MODE
};
ColourControl currentColourControl = HSV_MODE;
enum DJMode{
NORMAL,
RANDOM
};
DJMode currentDJMode = NORMAL;
unsigned long previousMillis = 0; // tracks the last music effect change
/////////////////////////////////////////////////////////////////// SETUP ////////////
void setup() {
Serial.begin(115200);
//LEDs
pinMode(ENVELOPE_PIN, INPUT);
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER> (leds, NUM_LEDS);
FastLED.clear();
FastLED.show();
delay(1000);
FastLED.setBrightness(brightness);
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED.show();
delay(1000);
readableColourControl(currentColourControl);
readableMode(currentMode);
}
/////////////////////////////////////////////////////////////////// LOOP ////////////
void loop() {
if (button1.click()) {
nextColourControl(currentColourControl);
readableColourControl(currentColourControl);
}
if (button2.click()){
Serial.println("button 2 pressed");
}
if (button3.click()){
nextDJMode(currentDJMode);
}
if (button4.click()){
style = (style +1) % 5;
Serial.print("STYLE: "); Serial.println(style);
}
if (button5.click()) {
nextMode(currentMode);
readableMode(currentMode);
}
brightness = slider.readValue();
switch (currentColourControl){
case RGB_MODE:
red = pot1.readValue();
green = pot2.readValue();
blue = pot3.readValue();
break;
case HSV_MODE:
hue = pot1.readValue();
saturation = pot2.readValue();
value = pot3.readValue();
break;
}
if (currentMode == FIXED) {
StaticHue();
}
if (currentMode == CHANGING) {
ChangingHue ();
}
if (currentMode == MUSIC) {
MusicMode();
}
}
/////////////////////////////////////////////////////////////////// MODES switching and debugginG ////////////
void nextDJMode(DJMode &in) {
switch (in) {
case NORMAL: in = RANDOM; Serial.println(F("Random")); break;
case RANDOM: in = NORMAL; Serial.println(F("Normal")); break;
}
}
void nextColourControl(ColourControl &in) {
switch (in) {
case RGB_MODE: in = HSV_MODE; break;
case HSV_MODE: in = RGB_MODE; break;
}
}
void readableColourControl(ColourControl in) {
switch (in) {
case RGB_MODE: Serial.println(F("RGB_MODE")); colourControlFlash(1); break;
case HSV_MODE: Serial.println(F("HSV_MODE")); colourControlFlash(2); break;
}
}
void colourControlFlash(int repeat){
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED.show();
delay(500);
for (int i = 0; i < repeat; i++) {
fill_rainbow_circular(leds, NUM_LEDS, CRGB::Red); FastLED.show();
delay(500);
fill_solid(leds, NUM_LEDS, CRGB::Black);FastLED.show();
delay(300);
}
delay(500);
}
void nextMode(Mode &in) {
switch (in) {
case FIXED: in = CHANGING; break;
case CHANGING: in = MUSIC; break;
case MUSIC: in = FIXED; break;
}
}
void readableMode(Mode in) {
switch (in) {
case FIXED: Serial.println(F("FIXED")); modeFlash(1); break;
case CHANGING: Serial.println(F("CHANGING")); modeFlash(2); break;
case MUSIC : Serial.println(F("MUSIC"));modeFlash(3); break;
}
}
void modeFlash(int repeat){
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED.show();
delay(500);
for (int i = 0; i < repeat; i++) {
fill_solid(leds, NUM_LEDS, CRGB::White); FastLED.show();
delay(500);
fill_solid(leds, NUM_LEDS, CRGB::Black);FastLED.show();
delay(300);
}
delay(500);
}
/////////////////////////////////////////////////////////////////// STATIC ////////////
void StaticHue(){
for(int i = 0;i < NUM_LEDS; i++){
if(currentColourControl == HSV_MODE){
leds[i] = CHSV(hue, saturation, value); // also: leds[i] = CHSV(hue + (i * 5), 255,255);
}
else if(currentColourControl == RGB_MODE){
leds[i] = CRGB( red, green, blue);
}
}
FastLED.setBrightness(brightness);
FastLED.show();
}
/////////////////////////////////////////////////////////////////// CHANGING ////////////
void ChangingHue(){
for(int i = 0;i < NUM_LEDS; i++){
leds[i] = CHSV(changingHue, 255, 255); // also: leds[i] = CHSV(hue + (i * 5), 255,255);
}
EVERY_N_MILLISECONDS (200){
changingHue++;
}
FastLED.show();
}
/////////////////////////////////////////////////////////////////// MUSIC ////////////
void MusicMode(){
analogVal = analogRead(ENVELOPE_PIN);
if(analogVal > maxVal)
analogVal = maxVal;
if(analogVal < minVal)
analogVal = minVal;
if(currentDJMode == RANDOM){
uint32_t interval = random(1,15); // seconds between music effects change
unsigned long now = millis();
if ((now - previousMillis) > interval*500){
style = random(1,6);
previousMillis = now;
}
}
switch (style) {
case 1:
LinearReactive();
break;
case 2:
BrightnessReactive();
break;
case 3:
CentreProgressive();
break;
case 4:
EdgeProgressive();
break;
default:
LinearFlowing();
break;
}
// Update the LED Strip
FastLED.show();
}
/////////////////////////////////////////////////////////////////// MUSIC MODES ////////////
void LinearFlowing() {
val = map(analogVal, minVal, maxVal, 0, brightness);
int dynamicDelay = map(analogVal, minVal, maxVal, 20, 1);
for (int i = 0; i < NUM_LEDS-1; i++) {
leds[i] = leds[i+1];
}
leds[NUM_LEDS-1] = CHSV(dynamicHue += HUE_CHANGE, saturation, val);
delay(dynamicDelay);
}
void LinearReactive() {
val = map(analogVal, 0, maxVal + 1, 0, NUM_LEDS);
for(int i = 0; i < NUM_LEDS; i++) {
if (i <= val)
leds[i] = CHSV(HUE_INIT+(HUE_CHANGE*i), saturation, brightness);
else
leds[i].nscale8(10);
}
}
void BrightnessReactive() {
val = map(analogVal, minVal, maxVal, 0, brightness);
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(HUE_INIT+(HUE_CHANGE*i), saturation, val);
}
}
void CentreProgressive() {
val = map(analogVal, minVal, maxVal, 0, NUM_LEDS/2);
for(int i = 0; i < NUM_LEDS/2; i++) {
if (i <= val) {
leds[(NUM_LEDS/2)+i] = CHSV(HUE_INIT+(HUE_CHANGE*i), saturation, brightness);
leds[(NUM_LEDS/2)-i] = CHSV(HUE_INIT+(HUE_CHANGE*i), saturation, brightness);
} else {
leds[(NUM_LEDS/2)+i].nscale8(10);
leds[(NUM_LEDS/2)-i].nscale8(10);
}
}
}
void EdgeProgressive() {
val = map(analogVal, 0, maxVal, 0, NUM_LEDS/2);
for(int i = 0; i < NUM_LEDS/2; i++) {
if (i <= val) {
leds[i] = CHSV(HUE_INIT+(HUE_CHANGE*i), saturation, brightness);
leds[NUM_LEDS-i] = CHSV(HUE_INIT+(HUE_CHANGE*i), saturation, brightness);
} else {
leds[i].nscale8(10);
leds[NUM_LEDS-i].nscale8(10);
}
}
}