#include <FastLED.h>
#define NUM_LEDS 108
#define LED_PIN 3
CRGB leds[NUM_LEDS];
// CONTROLLER LEDS AND BUTTONS
const int ledON = 4;
const int ledOFF = 5;
const int buttPWR = 6;
const int buttDULL = 7;
const int buttBRIGHT = 8;
const int buttCOL = 9;
const int buttMOD = 10;
//POWER VARIABLES
int PWR_State = LOW;
int PWR_Reading;
int PWR_Previous = HIGH;
unsigned long time = 0;
unsigned long debounce = 200UL;
//BRIGHTNESS VARIABLES
int BrightRead;
int DullRead;
int BRIGHTNESS; // This is the overall Brightness level
const int MinBRIGHTNESS = 31; // This defines the lowest brightness setting possible
const int MaxBRIGHTNESS = 255; // This defines the highest brightness setting possible
int BrightIncrement = 32; // This determine how big is the jump when increasing or decreasing brightness. Currently counts a total of 8 steps
float SetBright = 0;
float BrightTarget;
float easing = 0.0015;
// COLOR PALETTEs
// PRIMARY COLOR PALETTE: Warm White, Salmon, Tail, Sun, Sage
int Hue[] = { 35, 9, 135, 26, 106};
int Sat[] = { 24, 120, 151, 120, 46};
int Val[] = { 234, 252, 183, 247, 171};
// SECONDARY COLOR PALETTE: Warm White, Yellow, Pink, Purple, Sage
int Hue2[] = { 35, 30, 239, 187, 106};
int Sat2[] = { 24, 80, 117, 102, 46};
int Val2[] = { 234, 252, 225, 255, 171};
// COLOR VARIABLES
int ColorRead;
int ColorCount;
const int TotColors = 5;
int HueDirection;
int HueShift;
// MODE VARIABLES
int ModeRead;
int ModeCount;
const int TotModes = 3;
// GLOW MODE VARIABLES
int maxGlow = 191; // Value corresponding for maximum brightness in Glow Mode
int minGlow = 63; // Value corresponding for minimum brightness in Glow Mode
uint8_t glowSin; // Sinusoide for glow mode
// LAVA MODE VARIABLES
int speed = 3; // default set to 10. Decreasing the value will increaser the speed of oscillators
int picked = random8(NUM_LEDS);
int picked2 = random8(NUM_LEDS);
int picked3 = random8(NUM_LEDS);
uint8_t Sin1;
uint8_t Sin2;
uint8_t Sin3;
int Noise;
uint8_t Noisemap;
uint8_t LFO_Slow1; // Very slow Oscillator = 1 bpm
uint8_t LFO_Slow2; // Very slow Oscillator = 1.4 bpm
int Noise_Slow;
uint8_t Noise_Slowmap;
uint8_t LFO1; // LFO1 = 5 bpm
uint8_t Half_LFO1; // Half of LFO1 = 2.5 bpm
uint8_t LFO2; // LFO2 = 10 bpm
uint8_t Half_LFO2; // Half of LFO2 = 5 bpm
uint8_t LFO3; // LFO2 = 7.6 bpm
uint8_t Half_LFO3; // Half of LFO2 = 3.8 bpm
void setup() {
// put your setup code here, to run once:
pinMode(ledON, OUTPUT);
pinMode(ledOFF, OUTPUT);
pinMode(buttPWR, INPUT_PULLUP);
pinMode(buttDULL, INPUT_PULLUP);
pinMode(buttBRIGHT, INPUT_PULLUP);
pinMode(buttCOL, INPUT_PULLUP);
pinMode(buttMOD, INPUT_PULLUP);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
// Initialise button states
BrightRead = HIGH;
DullRead = HIGH;
ColorRead = HIGH;
ModeRead = HIGH;
// Initialise LED property settings
BRIGHTNESS = 159;
FastLED.setBrightness(0);
ColorCount = 0;
ModeCount = 0;
}
void loop() {
// put your main code here, to run repeatedly:
// Set all Oscillators
Sin1 = beatsin8(180/speed, 0, 255, 0, 0);
Sin2 = beatsin8(330/speed, 0, 255, 0, 50);
Sin3 = beatsin8(250/speed, 0, 255, 0, 200);
Noise = (Sin1 + Sin2 + Sin3) / 3;
Noisemap = map(Noise, 0 , 255, -30, 30);
LFO_Slow1 = beatsin8(10/speed, 0, 255, 0, 90); // Very slow Oscillator = 1 bpm
LFO_Slow2 = beatsin8(14/speed, 0, 255, 0, 200); // Very slow Oscillator = 1.4 bpm
Noise_Slow = (LFO_Slow1 + LFO_Slow2) /2;
Noise_Slowmap = map(Noise_Slow, 0 , 255, -10, 10);
LFO1 = beatsin16(50/speed, 0, 255, 0, 90); // LFO1 = 5 bpm
Half_LFO1 = beatsin16(25/speed, 0, 255, 0, 180); // Half of LFO1 = 2.5 bpm
LFO2 = beatsin16(100/speed, 0, 255, 0, 270); // LFO2 = 10 bpm
Half_LFO2 = beatsin16(50/speed, 0, 255, 0, 360); // Half of LFO2 = 5 bpm
LFO3 = beatsin16(76/speed, 0, 255, 0, 135); // LFO2 = 7.6 bpm
Half_LFO3 = beatsin16(38/speed, 0, 255, 0, 215); // Half of LFO2 = 3.8 bpm
glowSin = beatsin8(3, minGlow, maxGlow, 0, 0);
// Start Program
CheckPOWER();
TurnLedsON();
CheckCOLOR();
UpdateCOLOR();
CheckMODE();
UpdateMODE();
CheckBRIGHTNESS();
UpdateBRIGHTNESS();
FastLED.show();
}
void CheckPOWER() {
PWR_Reading = digitalRead(buttPWR);
if (PWR_Reading == HIGH && PWR_Previous == LOW && millis() - time > debounce)
{
if (PWR_State == HIGH){
PWR_State = LOW;
easing = 0.0005;
}
else {
PWR_State = HIGH;
easing = 0.0001;
}
time = millis();
}
digitalWrite(ledON, PWR_State);
digitalWrite(ledOFF, !PWR_State);
PWR_Previous = PWR_Reading;
}
void TurnLedsON () {
// Switch LED strip ON and OFF
if (PWR_State == HIGH) {
BrightTarget = BRIGHTNESS;
}
else {
BrightTarget = 0;
}
}
void CheckBRIGHTNESS() {
if (digitalRead(buttBRIGHT) == LOW) {
// easing = 0.015;
BrightRead = LOW;
}
if (digitalRead(buttDULL) == LOW) {
// easing = 0.015;
DullRead = LOW;
}
EVERY_N_MILLISECONDS (300) {
if(BrightRead == LOW && BRIGHTNESS < MaxBRIGHTNESS && PWR_State == HIGH && millis() - time > debounce) {
BRIGHTNESS += BrightIncrement;
BrightRead = HIGH;
} else {
BrightRead = HIGH;
}
if(DullRead == LOW && BRIGHTNESS > MinBRIGHTNESS && PWR_State == HIGH && millis() - time > debounce) {
BRIGHTNESS -= BrightIncrement;
DullRead = HIGH;
} else {
DullRead = HIGH;
}
}
}
void UpdateBRIGHTNESS(){
// Easing Logic
float dBright = BrightTarget-SetBright;
float trackingFactor = map(dBright, 0, 255, 20, 1);
SetBright += dBright * easing * trackingFactor;
FastLED.setBrightness(SetBright);
}
void CheckCOLOR() {
if (digitalRead(buttCOL) == LOW) {
// easing = 0.015;
ColorRead = LOW;
}
EVERY_N_MILLISECONDS (500) {
if(ColorRead == LOW && PWR_State == HIGH && millis() - time > debounce) {
ColorCount++;
if (ColorCount > (TotColors - 1)) {
ColorCount = 0;
}
ColorRead = HIGH;
} else {
ColorRead = HIGH;
}
}
}
void UpdateCOLOR() {
// This checks which color is currently active and assign a false state for instances where the scecondary colour is at the opposite side of the hue spectrum
switch (ColorCount) {
case 0: // Color 1
HueDirection = true;
break;
case 1: // Color 2
HueDirection = true;
break;
case 2: // Color 3
HueDirection = true;
break;
case 3: // Color 4
HueDirection = false;
break;
case 4: // Color 5
HueDirection = false;
break;
}
}
void CheckMODE() {
if (digitalRead(buttMOD) == LOW) {
// easing = 0.015;
ModeRead = LOW;
}
EVERY_N_MILLISECONDS (500) {
if(ModeRead == LOW && PWR_State == HIGH && millis() - time > debounce) {
ModeCount++;
if (ModeCount > (TotModes - 1)) {
ModeCount = 0;
}
ModeRead = HIGH;
} else {
ModeRead = HIGH;
}
}
}
void UpdateMODE() {
if (ModeCount == 0) {
StaticMode();
} else if (ModeCount == 1) {
GlowMode();
} else if (ModeCount == 2) {
LavaMode();
}
}
void StaticMode() {
fill_solid(leds, NUM_LEDS, CHSV(Hue[ColorCount], Sat[ColorCount], Val[ColorCount]));
}
void GlowMode() {
int glowVal = map(glowSin, 0, 255, 0, Val[ColorCount]);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(Hue[ColorCount], Sat[ColorCount], glowVal);
}
}
void LavaMode() {
// Mapping Oscillators
int Blob1Size = map(Half_LFO1, 0, 255, -15, 20);
int Blob2Size = map(Half_LFO2, 0, 255, -20, 50);
int Blob3Size = map(Half_LFO3, 0, 255, -30, 0);
int MoveSlow1 = map(LFO_Slow1, 0, 255, 0, 60);
int MoveSlow2 = map(LFO_Slow2, 0, 255, 0, 60);
int MoveSlow3 = map(Noise_Slowmap, 0, 255, 0, 60);
// Mapping Color Values
if (HueDirection == true) {
HueShift = Hue2[ColorCount];
} else {
HueShift = Hue2[ColorCount] - 255;
}
int FadeH = map(LFO1, 0, 255, HueShift, Hue[ColorCount]);
int FadeS = map(LFO1, 0, 255, Sat2[ColorCount], Sat[ColorCount]);
// Background Color
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(Hue[ColorCount], Sat[ColorCount], constrain((Val[ColorCount]*0.7 + Noisemap), 0, 255));
}
// Creating Blob 1
for (int i = 0; i < (10 - Blob1Size); i++) {
// Create Mirroring of blob. This Determines bith Size and Movement of the Blob
uint8_t position = picked + (i+(Noise_Slow/255)) + Blob1Size + MoveSlow1;
uint8_t position2 = picked - i + Blob1Size + MoveSlow1;
if (position > 255) {
position = position - 255;
}
// Create Fading Out of Bolob edges
int HueEdge;
if (HueShift < Hue[ColorCount]) {
HueEdge = constrain(map(i, (8 - Blob1Size), (10 - Blob1Size), FadeH, Hue[ColorCount]), HueShift, Hue[ColorCount]);
} else {
HueEdge = constrain(map(i, (8 - Blob1Size), (10 - Blob1Size), FadeH, Hue[ColorCount]), Hue[ColorCount], HueShift);
}
if (HueEdge < 0) {
HueEdge + 255;
};
int SatEdge = constrain(map(i, (8 - Blob1Size), (10 - Blob1Size), FadeS, Sat[ColorCount]), Sat2[ColorCount],Sat[ColorCount]);
leds[position] = CHSV(HueEdge, SatEdge, constrain((Val[ColorCount]*0.7 + Noise_Slowmap), 0, 255));
leds[position2] = CHSV(HueEdge, SatEdge, constrain((Val[ColorCount]*0.7 + Noise_Slowmap), 0, 255));
}
// Creating Blob 2
for (int i = 0; i < (5 - Blob2Size); i++) {
// Create Mirroring of blob
uint8_t position = picked2 + i + Blob2Size - (MoveSlow2 + Noise_Slowmap);
uint8_t position2 = picked2 - i + Blob2Size - (MoveSlow2 + Noise_Slowmap);
if (position > 255) {
position = position - 255;
}
// Create Fading Out of Blob edges
int HueEdge;
if (HueShift < Hue[ColorCount]) {
HueEdge = constrain(map(i, (2 - Blob2Size), (5 - Blob2Size), FadeH, Hue[ColorCount]), HueShift, Hue[ColorCount]);
} else {
HueEdge = constrain(map(i, (2 - Blob2Size), (5 - Blob2Size), FadeH, Hue[ColorCount]), Hue[ColorCount], HueShift);
}
if (HueEdge < 0) {
HueEdge + 255;
};
int SatEdge = constrain(map(i, (3 - Blob2Size), (5 - Blob2Size), FadeS, Sat[ColorCount]), Sat2[ColorCount],Sat[ColorCount]);
leds[position] = CHSV(HueEdge, SatEdge, constrain((Val[ColorCount]*0.7 + Noisemap), 0, 255));
leds[position2] = CHSV(HueEdge, SatEdge, constrain((Val[ColorCount]*0.7 + Noisemap), 0, 255));
}
// Creating Blob 3
for (int i = 0; i < (7 - Blob3Size); i++) {
// Create Mirroring of blob
uint8_t position = picked3 + i + Blob3Size - (MoveSlow3 + Noise_Slowmap);
uint8_t position2 = picked3 - i + Blob3Size - (MoveSlow3 + Noise_Slowmap);
if (position > 255) {
position = position - 255;
}
// Create Fading Out of Bolob edges
int HueEdge;
if (HueShift < Hue[ColorCount]) {
HueEdge = constrain(map(i, (2 - Blob3Size), (7 - Blob3Size), FadeH, Hue[ColorCount]), HueShift, Hue[ColorCount]);
} else {
HueEdge = constrain(map(i, (2 - Blob3Size), (7 - Blob3Size), FadeH, Hue[ColorCount]), Hue[ColorCount], HueShift);
}
if (HueEdge < 0) {
HueEdge + 255;
};
int SatEdge = constrain(map(i, (5 - Blob3Size), (7 - Blob3Size), FadeS, Sat[ColorCount]), Sat2[ColorCount],Sat[ColorCount]);
leds[position] = CHSV(HueEdge, SatEdge, constrain((Val[ColorCount]*0.7 + Noisemap), 0, 255));
leds[position2] = CHSV(HueEdge, SatEdge, constrain((Val[ColorCount]*0.7 + Noisemap), 0, 255));
}
blur1d(leds, NUM_LEDS, 172);
if (LFO1 = 0) {
picked = random8(NUM_LEDS);
picked2 = random8(NUM_LEDS);
picked3 = random8(NUM_LEDS);
}
}