#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define LED_PIN 3
#define LED_COUNT 120
const int LED_ROW = 4;
const int LED_COL = 30;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
byte mode_seq; // mode animasi
unsigned long mode_speed; // mode kecepatan
// variable
int i_led_1 = 0;
int N_LEDS;
byte intensitas; // tingkat cahaya
bool v_mirror; // gerakan arah dari belakang
bool v_reverse; // gerakan arah mundur
byte count_jeda; // jeda animasi
byte rd_r; // code merah sementara
byte rd_g; // code green sementara
byte rd_b; // code blue sementara
byte num_warna = 1;
// variabel waktu
bool stats = 0; // mode blink
unsigned long ws1 = 0; // millis() returns an unsigned long.
int led_from_pixel (byte rows, byte cols)
{
int a = 0;
if (rows % 2 == 0) {
a = (rows * LED_COL) + cols;
} else {
a = ((rows + 1) * LED_COL) - 1 - cols;
}
return a;
}
void setup() {
Serial.begin(9600);
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(255); // Set BRIGHTNESS to about 1/5 (max = 255)
mode_speed = 30;
}
void loop() {
// Fill along the length of the strip in various colors...
warna(num_warna);
if (num_warna > 13) {
num_warna = 0;
num_warna++;
// Serial.print('\t'); Serial.println(num_warna);
} else {
num_warna++;
}
// colorWipe(0,0);
// colorStatis();
// delay(1000);
colorWipe_Bar(0,1);
// meteorEffect(0,1);
// colorWipe_Bar_Gradient(0,1);
// colorWipe_Bar_Gradient(1,0);
// colorWipeGradient(0, 0);
// if (stats == 0) {
// colorWipe_Bar(0, 1);
// } else {
// colorWipe_Bar(1, 1);
// }
}
void meteorEffect(bool rev, bool half) {
if (half == 1) {
N_LEDS = LED_COUNT / 2; // Setengah dari jumlah LED
} else {
N_LEDS = LED_COUNT; // Semua LED
}
i_led_1 = 0;
// Panjang ekor meteor
int tailLength = N_LEDS-5; // Ubah nilai ini untuk mengatur panjang ekor meteor
while (i_led_1 < N_LEDS + tailLength) {
if (millis() > ws1 + mode_speed) {
Serial.println(i_led_1);
// Matikan LED sebelumnya
for (int i = 0; i < N_LEDS; i++) {
if (half == 0) {
strip.setPixelColor(i, strip.Color(0, 0, 0)); // matikan semua LED
} else {
// Jika mode setengah aktif, matikan hanya bagian LED yang relevan
if (i < N_LEDS) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
strip.setPixelColor(i, strip.Color(0, 0, 0));
strip.setPixelColor(LED_COUNT - 1 - i, strip.Color(0, 0, 0));
}
}
}
// Gambar meteor dan ekornya
for (int i = 0; i < tailLength; i++) {
int ledPos = i_led_1 - i;
if (ledPos >= 0 && ledPos < N_LEDS) {
if (rev == 0) {
// Meteor bergerak maju, nyalakan LED
if (half == 0) {
strip.setPixelColor(ledPos, strip.Color(rd_r, rd_g, rd_b));
} else {
strip.setPixelColor(ledPos, strip.Color(rd_r, rd_g, rd_b));
strip.setPixelColor(LED_COUNT - 1 - ledPos, strip.Color(rd_r, rd_g, rd_b));
}
} else {
// Meteor bergerak mundur, nyalakan LED
if (half == 0) {
strip.setPixelColor(LED_COUNT - 1 - ledPos, strip.Color(rd_r, rd_g, rd_b));
} else {
strip.setPixelColor(N_LEDS + ledPos, strip.Color(rd_r, rd_g, rd_b));
strip.setPixelColor(N_LEDS - 1 - ledPos, strip.Color(rd_r, rd_g, rd_b));
}
}
}
}
strip.show();
i_led_1++;
ws1 = millis();
}
}
stats = !stats;
}
void colorWipe_Bar_Gradient(bool rev, bool half) {
if (half == 1) {
N_LEDS = LED_COL / 2;
} else {
N_LEDS = LED_COL;
}
float phase = 0.0; // Fase awal gradiasi
float phaseSpeed = 0.03; // Kecepatan perubahan fase (semakin besar, semakin cepat)
while (true) { // Loop terus menerus
if (millis() > ws1 + mode_speed) {
for (int col = 0; col < N_LEDS; col++) {
float progress = ((float)col / (N_LEDS - 1)) + phase; // Tambahkan fase ke progress
if (progress > 1.0) progress -= 1.0; // Pastikan progress dalam rentang [0,1]
uint32_t color = calculateGradientColor(progress); // Hitung warna gradiasi
Serial.println(progress);
if (rev == 0) {
if (half == 0) {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, col), color);
}
} else {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, col), color);
strip.setPixelColor(led_from_pixel(r, LED_COL - col - 1), color);
}
}
} else {
if (half == 0) {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, LED_COL - 1 - col), color);
}
} else {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, N_LEDS + col), color);
strip.setPixelColor(led_from_pixel(r, N_LEDS - col - 1), color);
}
}
}
}
strip.show();
ws1 = millis();
// Perbarui fase untuk menggeser gradiasi ke kanan
phase += phaseSpeed;
// Jika fase melebihi 1.0, reset ke 0.0 untuk mengulangi pola gradiasi
if (phase >= 1.0) {
phase -= 1.0;
}
}
}
stats = !stats;
}
void colorWipe_Bar(bool rev, bool half) { // rev 0=maju, 1=munndur half 0=line 1=separuh
if (half == 1) {
N_LEDS = LED_COL / 2;
} else {
N_LEDS = LED_COL;
}
i_led_1 = 0;
while (i_led_1 < N_LEDS) {
if (millis() > ws1 + mode_speed) {
Serial.println(i_led_1);
if (rev == 0) {
if (half == 0) {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, i_led_1), strip.Color(rd_r, rd_g, rd_b));
}
} else {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, i_led_1), strip.Color(rd_r, rd_g, rd_b));
strip.setPixelColor(led_from_pixel(r, LED_COL - i_led_1 - 1), strip.Color(rd_r, rd_g, rd_b));
}
}
} else {
if (half == 0) {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, LED_COL - 1 - i_led_1), strip.Color(rd_r, rd_g, rd_b));
}
} else {
for (int r = 0; r < LED_ROW; r++) {
strip.setPixelColor(led_from_pixel(r, N_LEDS + i_led_1), strip.Color(rd_r, rd_g, rd_b));
strip.setPixelColor(led_from_pixel(r, N_LEDS - i_led_1 - 1), strip.Color(rd_r, rd_g, rd_b));
}
}
}
strip.show();
i_led_1++;
ws1 = millis();
}
}
stats = !stats;
}
void colorStatis() {
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i_led_1, strip.Color(rd_r, rd_g, rd_b));
}
strip.show();
}
void colorWipe(bool rev, bool half) { // rev 0=maju, 1=munndur half 0=line 1=separuh
if (half == 1) {
N_LEDS = LED_COUNT / 2;
} else {
N_LEDS = LED_COUNT;
}
i_led_1 = 0;
while (i_led_1 < N_LEDS) {
if (millis() > ws1 + mode_speed) {
Serial.println(i_led_1);
if (rev == 0) {
if (half == 0) {
strip.setPixelColor(i_led_1, strip.Color(rd_r, rd_g, rd_b));
} else {
strip.setPixelColor(i_led_1, strip.Color(rd_r, rd_g, rd_b));
strip.setPixelColor(LED_COUNT - 1 - i_led_1, strip.Color(rd_r, rd_g, rd_b));
}
} else {
if (half == 0) {
strip.setPixelColor(LED_COUNT - 1 - i_led_1, strip.Color(rd_r, rd_g, rd_b));
} else {
strip.setPixelColor(N_LEDS + i_led_1, strip.Color(rd_r, rd_g, rd_b));
strip.setPixelColor(N_LEDS - 1 - i_led_1, strip.Color(rd_r, rd_g, rd_b));
}
}
strip.show();
i_led_1++;
ws1 = millis();
}
}
stats = !stats;
}
void colorWipeGradient(bool rev, bool half) { // rev 0=maju, 1=mundur; half 0=line, 1=separuh
if (half == 1) {
N_LEDS = LED_COUNT / 2;
} else {
N_LEDS = LED_COUNT;
}
float phase = 0.0; // Fase awal gradiasi
float phaseSpeed = 0.1; // Kecepatan perubahan fase (semakin besar, semakin cepat)
while (true) {
if (millis() > ws1 + mode_speed) {
for (int col = 0; col < N_LEDS; col++) {
float progress = ((float)col / (N_LEDS - 1)) + phase; // Tambahkan fase ke progress
if (progress > 1.0) progress -= 1.0; // Pastikan progress dalam rentang [0,1]
uint32_t color = calculateGradientColor(progress); // Hitung warna gradiasi
Serial.println(progress);
if (rev == 0) {
if (half == 0) {
strip.setPixelColor(col, color);
} else {
strip.setPixelColor(col, color);
strip.setPixelColor(LED_COUNT - 1 - col, color);
}
} else {
if (half == 0) {
strip.setPixelColor(LED_COUNT - 1 - col, color);
} else {
strip.setPixelColor(N_LEDS + col, color);
strip.setPixelColor(N_LEDS - 1 - col, color);
}
}
}
strip.show();
ws1 = millis();
// Perbarui fase untuk menggeser gradiasi ke kanan
phase += phaseSpeed;
// Jika fase melebihi 1.0, reset ke 0.0 untuk mengulangi pola gradiasi
if (phase >= 1.0) {
phase -= 1.0;
}
}
}
stats = !stats;
}
// Fungsi untuk menghitung warna gradiasi
uint32_t calculateGradientColor(float progress) {
int r, g, b;
// Gradient range: cyan (0.0) -> blue (0.33) -> magenta (0.66) -> cyan (1.0)
if (progress < 0.33) {
// Cyan (0,255,255) -> Blue (0,0,255)
float subProgress = progress / 0.33; // Skala ke rentang [0, 1]
r = 0;
g = (int)(255 * (1.0 - subProgress));
b = 255;
} else if (progress < 0.66) {
// Blue (0,0,255) -> Magenta (255,0,255)
float subProgress = (progress - 0.33) / 0.33; // Skala ke rentang [0, 1]
r = (int)(255 * subProgress);
g = 0;
b = 255;
} else {
// Magenta (255,0,255) -> Cyan (0,255,255)
float subProgress = (progress - 0.66) / 0.34; // Skala ke rentang [0, 1]
r = (int)(255 * (1.0 - subProgress));
g = (int)(255 * subProgress);
b = 255;
}
return strip.Color(r, g, b);
}
void warna(int n) {
switch (n) {
case 0: // BLACK
rd_r = 0;
rd_g = 0;
rd_b = 0;
break;
case 1: // WHITE
rd_r = 252;
rd_g = 125;
rd_b = 150;
break;
case 2: // RED
rd_r = 255;
rd_g = 0;
rd_b = 0;
break;
case 3: // ROSE
rd_r = 255;
rd_g = 0;
rd_b = 50;
break;
case 4: // MAGENTA
rd_r = 255;
rd_g = 0;
rd_b = 200;
break;
case 5: // VIOLET
rd_r = 150;
rd_g = 0;
rd_b = 255;
break;
case 6: // BLUE
rd_r = 0;
rd_g = 0;
rd_b = 255;
break;
case 7: // AZURE
rd_r = 0;
rd_g = 75;
rd_b = 255;
break;
case 8: // CYAN
rd_r = 0;
rd_g = 255;
rd_b = 255;
break;
case 9: // AQUAMARINE
rd_r = 0;
rd_g = 255;
rd_b = 75;
break;
case 10: // GREEN
rd_r = 0;
rd_g = 255;
rd_b = 0;
break;
case 11: // CHARTREUSE
rd_r = 100;
rd_g = 255;
rd_b = 0;
break;
case 12: // YELLOW
rd_r = 255;
rd_g = 100;
rd_b = 0;
break;
case 13: // ORANGE
rd_r = 255;
rd_g = 50;
rd_b = 0;
break;
case 100:
break;
default:
rd_r = 255;
rd_g = 255;
rd_b = 255;
break;
}
}