#include <Arduino.h>
#include <Ultrasonic.h>
#include <FastLED.h>
#define NUM_LEDS 100
#define COLOR_ORDER GRB
#define DATA_PIN 6
#define LED_TYPE WS2812B
#define VOLTS 12
#define MAX_MA 4000
// Twinkle Rainbow parameters
#define TWINKLE_SPEED 5
#define TWINKLE_DENSITY 6
#define SECONDS_PER_PALETTE 30
#define AUTO_SELECT_BACKGROUND_COLOR 1
#define COOL_LIKE_INCANDESCENT 1
CRGBArray<NUM_LEDS> leds;
CRGBPalette16 gCurrentPalette;
CRGBPalette16 gTargetPalette;
Ultrasonic ultrasonic1(9, 10);
// CRGB leds[NUM_LEDS];
int Pot = A0;
int PotVal = 0;
int OutVal = 0;
uint8_t hue = 0;
CRGB myColours[8] = {
CRGB::Yellow,
CRGB::Blue,
CRGB::Green,
CRGB::Red,
CRGB::Yellow,
CRGB::Blue,
CRGB::Green,
CRGB::Red
};
void setup() {
Serial.begin(9600);
FastLED.setMaxPowerInVoltsAndMilliamps(12, 4000);
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS)
.setCorrection(TypicalLEDStrip);
randomSeed(analogRead(1));
chooseNextColorPalette(gTargetPalette);
}
void loop() {
PotVal = analogRead(Pot);
OutVal = map(PotVal, 0, 1023, 0, 255);
if (ultrasonic1.read() >= 30) {
for (int i = 0; i < NUM_LEDS; i++)
//leds[i] = CHSV(hue, 255, 255);
leds[i] = CHSV(hue + (i * 10), 255, 255);
FastLED.setBrightness(OutVal);
EVERY_N_MILLISECONDS(15)
hue++;
FastLED.show();
delay(1000);
}
else {
byte rand = random(0, 7); //choose random value 0-7
delay(2000);
twinkleRainbow(3000);
drawTwinkles(leds);
FastLED.show();
fill_solid(leds, NUM_LEDS, myColours[rand]);
FastLED.setBrightness(OutVal);
FastLED.show();
delay(10000);
}
}
void showColor(CRGB myColours, int duration) {
fill_solid(leds, NUM_LEDS, myColours);
analogWrite(NUM_LEDS, OutVal);
FastLED.setBrightness(OutVal);
FastLED.show();
delay(duration);
}
void twinkleRainbow(int duration) {
unsigned long start = millis();
while (millis() - start < duration) {
EVERY_N_SECONDS(SECONDS_PER_PALETTE) {
chooseNextColorPalette(gTargetPalette);
}
EVERY_N_MILLISECONDS(10) {
nblendPaletteTowardPalette(gCurrentPalette, gTargetPalette, 12);
}
drawTwinkles(leds);
FastLED.show();
}
}
void drawTwinkles(CRGBSet& L) {
uint16_t PRNG16 = 11337;
uint32_t clock32 = millis();
CRGB bg;
if ((AUTO_SELECT_BACKGROUND_COLOR == 1) && (gCurrentPalette[0] == gCurrentPalette[1])) {
bg = gCurrentPalette[0];
uint8_t bglight = bg.getAverageLight();
if (bglight > 64) {
bg.nscale8_video(16);
} else if (bglight > 16) {
bg.nscale8_video(64);
} else {
bg.nscale8_video(86);
}
} else {
bg = CRGB::BlueViolet;
}
uint8_t backgroundBrightness = bg.getAverageLight();
for (CRGB& pixel : L) {
PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384;
uint16_t myclockoffset16 = PRNG16;
PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384;
uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF) >> 4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
uint8_t myunique8 = PRNG16 >> 8;
CRGB c = computeOneTwinkle(myclock30, myunique8);
uint8_t cbright = c.getAverageLight();
int16_t deltabright = cbright - backgroundBrightness;
if (deltabright >= 32 || (!bg)) {
pixel = c;
} else if (deltabright > 0) {
pixel = blend(bg, c, deltabright * 8);
} else {
pixel = bg;
}
}
}
CRGB computeOneTwinkle(uint32_t ms, uint8_t salt) {
uint16_t ticks = ms >> (8 - TWINKLE_SPEED);
uint8_t fastcycle8 = ticks;
uint16_t slowcycle16 = (ticks >> 8) + salt;
slowcycle16 += sin8(slowcycle16);
slowcycle16 = (slowcycle16 * 2053) + 1384;
uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
uint8_t bright = 0;
if (((slowcycle8 & 0x0E) / 2) < TWINKLE_DENSITY) {
bright = attackDecayWave8(fastcycle8);
}
uint8_t hue = slowcycle8 - salt;
CRGB c;
if (bright > 0) {
c = ColorFromPalette(gCurrentPalette, hue, bright, NOBLEND);
if (COOL_LIKE_INCANDESCENT == 1) {
coolLikeIncandescent(c, fastcycle8);
}
} else {
c = CRGB::Black;
}
return c;
}
uint8_t attackDecayWave8(uint8_t i) {
if (i < 86) {
return i * 3;
} else {
i -= 86;
return 255 - (i + (i / 2));
}
}
void coolLikeIncandescent(CRGB& c, uint8_t phase) {
if (phase < 128) return;
uint8_t cooling = (phase - 128) >> 4;
c.g = qsub8(c.g, cooling);
c.b = qsub8(c.b, cooling * 2);
}
const TProgmemRGBPalette16* ActivePaletteList[] = {
&RainbowColors_p,
&PartyColors_p,
};
void chooseNextColorPalette(CRGBPalette16& pal) {
const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]);
static uint8_t whichPalette = -1;
whichPalette = addmod8(whichPalette, 1, numberOfPalettes);
pal = *(ActivePaletteList[whichPalette]);
}