#include <FastLED.h>
#define NUM_LEDS 100
#define TOTAL_LEDS 500
#define SWITCH_LEFT 4
#define SWITCH_RIGHT 6
#define ARM_1_LED_PIN 9
#define ARM_2_LED_PIN 10
#define ARM_3_LED_PIN 11
#define RING_LED_PIN 12
#define PULSE_LED_PIN 13
#define BRIGHTNESS 200
#define POTENTIOMETER_PIN_WIND A0
#define POTENTIOMETER_PIN_BRIGHTNESS A2
#define POTENTIOMETER_PIN_FADE A3
#define POTENTIOMETER_PIN_BOTTOM A4
#define POTENTIOMETER_PIN_TOP A5
CRGB armLeds1[NUM_LEDS];
CRGB armLeds2[NUM_LEDS];
CRGB armLeds3[NUM_LEDS];
CRGB pulseLeds[200];
CRGB ringLeds[12];
uint8_t maxBrightness = BRIGHTNESS;
uint8_t currentBrightness = maxBrightness;
uint8_t windNoise = 120;
uint16_t windX = 0;
uint16_t x = 0;
uint16_t y = 0; // Position along the noise function
// Define a palette.
DEFINE_GRADIENT_PALETTE(NorthernLightsPalette) {
0, 0, 207, 82, // Colder colors
62, 3, 46, 62,
143, 25, 100, 106,
192, 0, 198, 144,
255, 0, 223, 150
};
DEFINE_GRADIENT_PALETTE(WarmNorthernLightsPalette) {
0, 255, 40, 5, // Warmer reds and oranges
62, 255, 60, 5,
143, 255, 80, 0,
180, 255, 100, 0,
200, 255, 0, 0,
255, 255, 0, 0
};
CRGBPalette16 currentPalette = CRGBPalette16(NorthernLightsPalette);
CRGBPalette16 warmPalette = CRGBPalette16(WarmNorthernLightsPalette);
void setup() {
FastLED.addLeds<WS2811, ARM_1_LED_PIN, BRG>(armLeds1, NUM_LEDS);
FastLED.addLeds<WS2811, ARM_2_LED_PIN, BRG>(armLeds2, NUM_LEDS);
FastLED.addLeds<WS2811, ARM_3_LED_PIN, BRG>(armLeds3, NUM_LEDS);
/* FastLED.addLeds<WS2811, PULSE_LED_PIN, BRG>(pulseLeds, NUM_LEDS); */
FastLED.setBrightness(BRIGHTNESS);
Serial.begin(57600);
pinMode(POTENTIOMETER_PIN_WIND, INPUT);
pinMode(POTENTIOMETER_PIN_FADE, INPUT);
pinMode(POTENTIOMETER_PIN_BOTTOM, INPUT);
pinMode(POTENTIOMETER_PIN_TOP, INPUT);
pinMode(SWITCH_LEFT, INPUT_PULLUP);
pinMode(SWITCH_RIGHT, INPUT_PULLUP);
}
void loop() {
// Read the potentiometer values
int potValueFade = map(analogRead(POTENTIOMETER_PIN_FADE), 0, 1023, 0, 50);
int potValueBottom = map(analogRead(POTENTIOMETER_PIN_BOTTOM), 0, 1023, 0, NUM_LEDS - 1);
int potValueTop = map(analogRead(POTENTIOMETER_PIN_TOP), 0, 1023, 0, NUM_LEDS - 1);
int potValueWind = map(analogRead(POTENTIOMETER_PIN_WIND), 0, 1023, 120, 250);
maxBrightness = map(analogRead(POTENTIOMETER_PIN_BRIGHTNESS), 0, 1023, 0, BRIGHTNESS);
currentBrightness = maxBrightness;
FastLED.setBrightness(currentBrightness);
int switchLeft = digitalRead(SWITCH_LEFT) == 0 ? true : false;
int switchRight = digitalRead(SWITCH_RIGHT) == 0 ? true : false;
if (switchRight) {
windNoise = inoise8(windX * 0.5, 0, 0);
windX++;
} else {
windNoise = potValueWind;
}
// Ensure top is always above bottom
if (potValueTop < potValueBottom) {
potValueTop = potValueBottom;
}
EVERY_N_MILLISECONDS(20) {
int windSpeed;
int hueValue;
if (windNoise <= 120) {
hueValue = 0;
windSpeed = 3;
} else if (windNoise > 120 && windNoise <= 175) {
hueValue = map(windNoise, 121, 176, 0, 255);
windSpeed = map(windNoise, 121, 176, 3, 10);
} else {
windSpeed = 10;
hueValue = 255;
}
fill_noise(hueValue, potValueFade);
x += windSpeed;
}
FastLED.show();
}
// Function for generating a nothern light effect
void fill_noise(int valueHue, int fade) {
uint8_t blendFactor = valueHue;
int fadeLength = fade; // Number of LEDs to fade in and out
for (int i = 0; i < NUM_LEDS; i++) {
uint8_t noise = inoise8(i * 15 + x, 0, i * 15 + x);
CRGB color1 = ColorFromPalette(currentPalette, noise);
CRGB color2 = ColorFromPalette(warmPalette, noise);
CRGB blendedColor = blend(color1, color2, blendFactor);
// Linear fade logic
int linearFadeFactor = 255;
if (i < fadeLength) { // Fade in logic
linearFadeFactor = map(i, 0, fadeLength - 1, 0, 255);
uint8_t noiseFade = inoise8(i * 125 + x + x, 0, i * 125 + x + x);
int noiseFadeFactor = map(noiseFade, 0, 255, 0, 255);
linearFadeFactor = (noiseFadeFactor * linearFadeFactor) / 255;
}
blendedColor.nscale8(linearFadeFactor);
armLeds1[i] = blendedColor;
armLeds2[i] = blendedColor;
}
}