#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
#define NUM_LEDS 16
#define LED_PIN1 10
#define LED_PIN2 11
int Switch_SeinKiri = A0;
int Switch_Hazard = A1;
int Switch_Stoplamp = A2;
int Switch_SeinKanan = A3;
int Switch_Running_Animasi = A4;
bool animationEnabled = false;
bool animationTemporarilyDisabled = false;
unsigned long animationDisableStartTime = 0;
const unsigned long animationDisableDuration = 500;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(NUM_LEDS, LED_PIN2, NEO_GRB + NEO_KHZ800);
CRGB leds[NUM_LEDS];
CRGB leds2[NUM_LEDS];
uint8_t patternCounter = 0;
void setup() {
pinMode(Switch_SeinKiri, INPUT_PULLUP);
pinMode(Switch_SeinKanan, INPUT_PULLUP);
pinMode(Switch_Stoplamp, INPUT_PULLUP);
pinMode(Switch_Hazard, INPUT_PULLUP);
pinMode(Switch_Running_Animasi, INPUT_PULLUP);
strip.begin();
strip.show();
strip2.begin();
strip2.show();
FastLED.addLeds<WS2812B, LED_PIN1, GRB>(leds, NUM_LEDS);
FastLED.addLeds<WS2812B, LED_PIN2, GRB>(leds2, NUM_LEDS);
FastLED.setBrightness(255);
}
void loop() {
readActivation();
if (animationTemporarilyDisabled) {
if (millis() - animationDisableStartTime >= animationDisableDuration) {
animationTemporarilyDisabled = false;
}
}
if (!animationTemporarilyDisabled && animationEnabled) {
runAnimation();
}
}
void readActivation() {
int data0 = digitalRead(Switch_SeinKiri);
int data1 = digitalRead(Switch_Hazard);
int data2 = digitalRead(Switch_Stoplamp);
int data3 = digitalRead(Switch_SeinKanan);
static int hold0 = 0;
static int hold1 = 0;
static int hold2 = 0;
static int hold3 = 0;
if (data0 == 0) {
if (hold0 == 0) {
hold0 = 0;
SeinKiri();
}
} else {
hold0 = 0;
}
if (data1 == 0) {
if (hold1 == 0) {
hold1 = 0;
Hazard();
}
} else {
hold1 = 0;
}
if (data2 == 0) {
if (hold2 == 0) {
hold2 = 0;
Stoplamp();
}
} else {
hold2 = 0;
}
if (data3 == 0) {
if (hold3 == 0) {
hold3 = 0;
SeinKanan();
}
} else {
hold3 = 0;
}
if (data0 == 0 || data1 == 0 || data2 == 0 || data3 == 0) {
animationTemporarilyDisabled = true;
animationDisableStartTime = millis();
turnOffAllLEDs();
}
if (digitalRead(Switch_Running_Animasi) == 0) {
animationEnabled = !animationEnabled;
}
}
void runAnimation() {
switch (patternCounter) {
case 0:
rainbowEffect();
break;
case 1:
sinusoidalRainbowEffect();
break;
case 2:
verticalWaveEffect();
break;
case 3:
dotMovementEffect();
break;
case 4:
alternateDotMovementEffect();
break;
case 5:
colorfulpointMovementEffect();
break;
case 6:
pointMovementEffect();
break;
case 7:
twinklingWaveEffect();
break;
case 8:
beatRainbowEffect();
break;
case 9:
DoubleRainbowEffect();
break;
case 10:
RainbowEffectFromLastLED();
break;
case 11:
RainbowEffectFromFirstLED();
break;
case 12:
RainbowEffectFromEdgesToCenter();
break;
case 13:
RainbowEffectBounce();
break;
case 14:
DualDirectionLEDAnimation();
break;
}
EVERY_N_SECONDS(10) {
replaceAnimation();
}
FastLED.show();
}
void replaceAnimation() {
patternCounter = (patternCounter + 1) % 15;
}
void rainbowEffect() {
int rainbowColorOffset = 0;
int numActiveLEDs = 0;
int middleIndex = NUM_LEDS / 2;
int runningIndex = 0;
while (numActiveLEDs < 5) {
int reverseIndex = NUM_LEDS - 1 - runningIndex;
strip.setPixelColor(middleIndex + runningIndex, Wheel((runningIndex + rainbowColorOffset) & 255));
strip.setPixelColor(middleIndex - runningIndex, Wheel((runningIndex + rainbowColorOffset) & 255));
strip2.setPixelColor(middleIndex + runningIndex, Wheel((runningIndex + rainbowColorOffset) & 255));
strip2.setPixelColor(middleIndex - runningIndex, Wheel((runningIndex + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(30);
runningIndex++;
rainbowColorOffset += 5;
if (runningIndex >= middleIndex) {
runningIndex = 0;
numActiveLEDs++;
}
}
}
void sinusoidalRainbowEffect() {
uint16_t beatA = beatsin16(30, 0, 255);
uint16_t beatB = beatsin16(30, 0, 255);
fill_rainbow(leds, NUM_LEDS, (beatA + beatB) / 2, 10);
fill_rainbow(leds2, NUM_LEDS, (beatA + beatB) / 2, 10);
}
void verticalWaveEffect() {
uint8_t speed = 5;
uint8_t offset = millis() / 10;
for (uint16_t i = 0; i < NUM_LEDS; i++) {
uint8_t distance = abs(i - (NUM_LEDS / 2));
uint8_t wave = offset + (distance * speed);
leds[i] = CHSV(wave, 255, 255);
leds2[i] = CHSV(wave, 255, 255);
}
}
void dotMovementEffect() {
uint16_t posBeat1 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat2 = beatsin16(60, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat4 = beatsin16(60, 0, NUM_LEDS - 1, 0, 32767);
uint8_t colBeat = beatsin8(45, 0, 255, 0, 0);
leds[(posBeat1 + posBeat2) / 2] = CHSV(colBeat, 255, 255);
leds2[(posBeat3 + posBeat4) / 2] = CHSV(colBeat, 255, 255);
fadeToBlackBy(leds, NUM_LEDS, 10);
fadeToBlackBy(leds2, NUM_LEDS, 10);
}
void alternateDotMovementEffect() {
uint16_t posBeat1 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat2 = beatsin16(60, 0, NUM_LEDS - 1, 0, 0);
uint16_t posBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat4 = beatsin16(60, 0, NUM_LEDS - 1, 0, 0);
uint8_t colBeat = beatsin8(45, 0, 255, 0, 0);
leds[(posBeat1 + posBeat2) / 2] = CHSV(colBeat, 255, 255);
leds2[(posBeat3 + posBeat4) / 2] = CHSV(colBeat, 255, 255);
fadeToBlackBy(leds, NUM_LEDS, 10);
fadeToBlackBy(leds2, NUM_LEDS, 10);
}
void colorfulpointMovementEffect() {
uint16_t sinBeat1 = beatsin16(30, 0, NUM_LEDS - 1, 0, 0);
uint16_t sinBeat2 = beatsin16(30, 0, NUM_LEDS - 1, 0, 21845);
uint16_t sinBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t sinBeat4 = beatsin16(30, 0, NUM_LEDS - 1, 0, 43690);
leds[sinBeat1] = CRGB::Blue;
leds[sinBeat2] = CRGB::Red;
leds[sinBeat3] = CRGB::White;
leds[sinBeat4] = CRGB::Green;
leds2[sinBeat1] = CRGB::Blue;
leds2[sinBeat2] = CRGB::Red;
leds2[sinBeat3] = CRGB::White;
leds2[sinBeat4] = CRGB::Green;
fadeToBlackBy(leds, NUM_LEDS, 10);
fadeToBlackBy(leds2, NUM_LEDS, 10);
}
void pointMovementEffect() {
uint16_t posBeat1 = beatsin16(20, 0, NUM_LEDS - 1, 0, 0);
uint16_t posBeat2 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat3 = beatsin16(20, 0, NUM_LEDS - 1, 0, 0);
uint16_t posBeat4 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint8_t colBeat = beatsin8(60, 0, 255, 0, 0);
leds[(posBeat1 + posBeat2) / 2] = CHSV(colBeat, 255, 255);
leds2[(posBeat3 + posBeat4) / 2] = CHSV(colBeat, 255, 255);
fadeToBlackBy(leds, NUM_LEDS, 5);
fadeToBlackBy(leds2, NUM_LEDS, 5);
}
void twinklingWaveEffect() {
static uint16_t time = 0;
time += 1;
uint16_t sinBeat1 = beatsin16(30, 0, NUM_LEDS - 1, 0, time + 0);
uint16_t sinBeat2 = beatsin16(30, 0, NUM_LEDS - 1, 0, time + 21845);
uint16_t sinBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, time + 32767);
uint16_t sinBeat4 = beatsin16(30, 0, NUM_LEDS - 1, 0, time + 43690);
leds[sinBeat1] = CRGB::Blue;
leds[sinBeat2] = CRGB::Red;
leds[sinBeat3] = CRGB::White;
leds[sinBeat4] = CRGB::Green;
leds2[sinBeat1] = CRGB::Blue;
leds2[sinBeat2] = CRGB::Red;
leds2[sinBeat3] = CRGB::White;
leds2[sinBeat4] = CRGB::Green;
for (uint16_t i = 0; i < NUM_LEDS; i++) {
if (random8() < 50) { // 30% chance for a twinkling LED
leds[i] = CRGB::Black;
leds2[i] = CRGB::Black;
}
}
fadeToBlackBy(leds, NUM_LEDS, 10);
fadeToBlackBy(leds2, NUM_LEDS, 10);
}
void beatRainbowEffect() {
uint8_t beatA = beatsin8(30, 0, 255);
uint8_t beatB = beatsin8(30, 0, 255);
for (uint16_t i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV((beatA + beatB + i * 10) % 256, 255, 255);
leds2[i] = CHSV((beatA + beatB + i * 10) % 256, 255, 255);
}
}
void DoubleRainbowEffect() {
int rainbowColorOffset = 0;
int middleIndex = NUM_LEDS / 2;
strip.clear();
strip2.clear();
strip.show();
strip2.show();
for (int i = 0; i <= middleIndex; i++) {
int reverseIndex = NUM_LEDS - 1 - i;
strip.setPixelColor(middleIndex + i, Wheel((i + rainbowColorOffset) & 255));
strip.setPixelColor(middleIndex - i, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(middleIndex + i, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(middleIndex - i, Wheel((i + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(30);
rainbowColorOffset += 5; // Adjust this value to control rainbow speed
}
}
void RainbowEffectFromLastLED() {
int rainbowColorOffset = 0;
strip.clear();
strip2.clear();
strip.show();
strip2.show();
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(i, Wheel((i + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(30);
rainbowColorOffset += 5; // Sesuaikan nilai ini untuk mengontrol kecepatan pelangi
}
// Hapus kedua strip ketika efek selesai
strip.clear();
strip2.clear();
strip.show();
strip2.show();
}
void RainbowEffectFromFirstLED() {
int rainbowColorOffset = 0;
strip.clear();
strip2.clear();
strip.show();
strip2.show();
for (int i = NUM_LEDS - 1; i >= 0; i--) {
strip.setPixelColor(i, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(i, Wheel((i + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(30);
rainbowColorOffset += 5; // Sesuaikan nilai ini untuk mengontrol kecepatan pelangi
}
// Hapus kedua strip ketika efek selesai
strip.clear();
strip2.clear();
strip.show();
strip2.show();
}
void RainbowEffectFromEdgesToCenter() {
int rainbowColorOffset = 0;
strip.clear();
strip2.clear();
strip.show();
strip2.show();
for (int i = 0; i < NUM_LEDS / 2; i++) {
int outerPixel = NUM_LEDS - 0 - i;
int innerPixel = i;
strip.setPixelColor(outerPixel, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(outerPixel, Wheel((i + rainbowColorOffset) & 255));
strip.setPixelColor(innerPixel, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(innerPixel, Wheel((i + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(50);
rainbowColorOffset += 5; // Sesuaikan nilai ini untuk mengontrol kecepatan pelangi
}
// Hapus kedua strip ketika efek selesai
strip.clear();
strip2.clear();
strip.show();
strip2.show();
}
void RainbowEffectBounce() {
int rainbowColorOffset = 0;
strip.clear();
strip2.clear();
strip.show();
strip2.show();
int centerPixel = NUM_LEDS / 2;
for (int i = 0; i <= centerPixel; i++) {
int outerPixel1 = centerPixel - i;
int outerPixel2 = centerPixel + i;
strip.setPixelColor(outerPixel1, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(outerPixel1, Wheel((i + rainbowColorOffset) & 255));
strip.setPixelColor(outerPixel2, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(outerPixel2, Wheel((i + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(30);
rainbowColorOffset += 5; // Sesuaikan nilai ini untuk mengontrol kecepatan pelangi
}
for (int i = centerPixel - 1; i >= 0; i--) {
int outerPixel1 = centerPixel - i;
int outerPixel2 = centerPixel + i;
strip.setPixelColor(outerPixel1, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(outerPixel1, Wheel((i + rainbowColorOffset) & 255));
strip.setPixelColor(outerPixel2, Wheel((i + rainbowColorOffset) & 255));
strip2.setPixelColor(outerPixel2, Wheel((i + rainbowColorOffset) & 255));
strip.show();
strip2.show();
delay(30);
rainbowColorOffset += 5; // Sesuaikan nilai ini untuk mengontrol kecepatan pelangi
}
// Hapus kedua strip ketika efek selesai
strip.clear();
strip2.clear();
strip.show();
strip2.show();
}
void DualDirectionLEDAnimation() {
uint16_t posBeat1 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat2 = beatsin16(40, 0, NUM_LEDS - 1, 0, 0);
uint16_t posBeat3 = beatsin16(30, 0, NUM_LEDS - 1, 0, 32767);
uint16_t posBeat4 = beatsin16(40, 0, NUM_LEDS - 1, 0, 0);
uint8_t colBeat = beatsin8(40, 0, 255, 0, 0);
// Calculate positions for two directions
uint16_t pos1 = (posBeat1 + posBeat2) / 2;
uint16_t pos2 = (posBeat3 + posBeat4) / 2;
// Set LEDs in both directions for Strip 1
leds[pos1] = CHSV(colBeat, 255, 255);
// Calculate positions for the reverse direction for Strip 2
uint16_t pos1_reverse = NUM_LEDS - 1 - pos1;
// Set LEDs in the reverse direction for Strip 2
leds2[pos1_reverse] = CHSV(colBeat, 255, 255);
// Set LEDs in both directions for Strip 2
leds2[pos2] = CHSV(colBeat, 255, 255);
// Calculate positions for the reverse direction for Strip 1
uint16_t pos2_reverse = NUM_LEDS - 1 - pos2;
// Set LEDs in the reverse direction for Strip 1
leds[pos2_reverse] = CHSV(colBeat, 255, 255);
fadeToBlackBy(leds, NUM_LEDS, 10);
fadeToBlackBy(leds2, NUM_LEDS, 10);
}
void SeinKiri() {
SeinKiri(strip.Color(255, 255, 0), 10);
SeinKiri(strip.Color(0, 0, 0), 10);
}
void SeinKiri(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void SeinKanan() {
SeinKanan(strip2.Color(255, 255, 0), 10);
SeinKanan(strip2.Color(0, 0, 0), 10);
}
void SeinKanan(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip2.numPixels(); i++) {
strip2.setPixelColor(i, c);
strip2.show();
delay(wait);
}
}
void Hazard() {
Hazard(strip.Color(255, 255, 0), 10);
Hazard(strip.Color(0, 0, 0), 10);
}
void Hazard(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip2.setPixelColor(i, c);
strip2.show();
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void Stoplamp() {
Stoplamp(strip.Color(255, 0, 0), 50);
Stoplamp(strip.Color(0, 0, 0), 50);
Stoplamp(strip.Color(255, 0, 0), 50);
Stoplamp(strip.Color(0, 0, 0), 50);
Stoplamp(strip.Color(0, 0, 255), 50);
Stoplamp(strip.Color(0, 0, 0), 50);
}
void Stoplamp(uint32_t c, uint8_t wait) {
int center = NUM_LEDS / 2;
for (int i = 0; i <= center; i += 7) {
for (int j = 0; j < 7; j++) {
strip.setPixelColor(center - i + j, c);
strip.setPixelColor(center + i - j, c);
strip2.setPixelColor(center - i + j, c);
strip2.setPixelColor(center + i - j, c);
}
strip.show();
strip2.show();
delay(wait);
for (int j = 0; j < 7; j++) {
strip.setPixelColor(center - i + j, 0);
strip.setPixelColor(center + i - j, 0);
strip2.setPixelColor(center - i + j, 0);
strip2.setPixelColor(center + i - j, 0);
}
strip.show();
strip2.show();
delay(wait);
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip2.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip2.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip2.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void turnOffAllLEDs() {
for (uint16_t i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
leds2[i] = CRGB::Black;
}
FastLED.show();
strip.clear();
strip2.clear();
strip.show();
strip2.show();
}
void turnOffAllLEDsGradually() {
for (int brightness = 255; brightness >= 0; brightness -= 0) {
FastLED.setBrightness(brightness);
FastLED.show();
}
FastLED.setBrightness(255);
for (uint16_t i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
leds2[i] = CRGB::Black;
}
FastLED.show();
}