#include <IRremote.h>
// ==========================================
// KONFIGURASI PIN ESP32 (Sesuai Gambar Wokwi)
// ==========================================
// 16 Pin Relay (Urutan Baris 1 sampai 4)
const int relayPins[16] = {
13, 14, 27, 26, // Baris 1
25, 33, 32, 15, // Baris 2
4, 16, 17, 5, // Baris 3
18, 19, 21, 22 // Baris 4
};
const int IR_RECEIVE_PIN = 34; // Pin Sensor IR (Kabel Kuning)
const int ledPin = 2; // Pin LED Ekstra (Kabel Pink)
// ==========================================
// POLA ANIMASI MATRIX 4x4
// ==========================================
// Mode 1: Ular Melingkar (Spiral dari luar ke dalam)
const int animSpiral[16] = {0, 1, 2, 3, 7, 11, 15, 14, 13, 12, 8, 4, 5, 6, 10, 9};
// Mode 2: Sapuan Zig-Zag (Kiri-Kanan turun ke bawah)
const int animZigZag[16] = {0, 1, 2, 3, 7, 6, 5, 4, 8, 9, 10, 11, 15, 14, 13, 12};
// ==========================================
// VARIABEL SISTEM
// ==========================================
int currentMode = 0; // 0: OFF, 1: Spiral, 2: Zig-Zag, 3: ALL ON
int currentStep = 0;
unsigned long prevMillis = 0;
const long interval = 100; // Kecepatan gerak lampu (100 milidetik = Cepat!)
bool ledState = LOW; // Status untuk LED ekstra
void setup() {
Serial.begin(115200);
// Inisialisasi 16 Relay
// Secara coding, kita hanya menyuruh relay menyala (HIGH) atau mati (LOW).
// Arus listrik untuk LED bergantung pada sambungan kabel di terminal COM dan NO.
for(int i = 0; i < 16; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
}
// Inisialisasi LED Ekstra
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Mulai Penerima IR
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
Serial.println("==================================");
Serial.println("SISTEM MATRIX RUNNING SIAP!");
Serial.println("TOMBOL REMOT:");
Serial.println("[1] Animasi Spiral");
Serial.println("[2] Animasi Zig-Zag");
Serial.println("[3] Nyalakan Semua (All ON)");
Serial.println("[4] Matikan Semua (All OFF)");
Serial.println("[5] Toggle LED Pink");
Serial.println("==================================");
}
// Fungsi matikan semua relay
void turnOffAllRelays() {
for(int i = 0; i < 16; i++) {
digitalWrite(relayPins[i], LOW);
}
}
// Fungsi nyalakan semua relay
void turnOnAllRelays() {
for(int i = 0; i < 16; i++) {
digitalWrite(relayPins[i], HIGH);
}
}
void loop() {
// --- 1. BACA INPUT REMOT IR ---
if (IrReceiver.decode()) {
int command = IrReceiver.decodedIRData.command;
Serial.print("Kode Remot: ");
Serial.println(command);
switch (command) {
case 48: // Tombol Angka '1'
currentMode = 1;
currentStep = 0;
Serial.println("-> Berpindah ke Mode 1: Spiral");
break;
case 24: // Tombol Angka '2'
currentMode = 2;
currentStep = 0;
Serial.println("-> Berpindah ke Mode 2: Zig-Zag");
break;
case 122: // Tombol Angka '3'
currentMode = 3;
turnOnAllRelays();
Serial.println("-> Berpindah ke Mode 3: NYALAKAN SEMUA");
break;
case 16: // Tombol Angka '4'
case 162: // Atau Tombol 'POWER' Merah
currentMode = 0;
turnOffAllRelays();
Serial.println("-> Berpindah ke Mode 0: MATIKAN SEMUA");
break;
case 56: // Tombol Angka '5'
ledState = !ledState;
digitalWrite(ledPin, ledState);
Serial.println("-> LED Pink Ekstra Diubah");
break;
case 168: // Tombol 'PLAY'
if (currentMode == 0 || currentMode == 3) {
currentMode = 1;
}
Serial.println("-> Animasi Dimulai/Dilanjutkan");
break;
}
IrReceiver.resume();
}
// --- 2. JALANKAN ANIMASI (Non-Blocking) ---
unsigned long currentMillis = millis();
if (currentMillis - prevMillis >= interval) {
prevMillis = currentMillis;
if (currentMode == 1) {
// --- Logika Bergerak Spiral ---
turnOffAllRelays();
digitalWrite(relayPins[animSpiral[currentStep]], HIGH);
currentStep++;
if (currentStep >= 16) {
currentStep = 0; // Ulangi dari awal
}
}
else if (currentMode == 2) {
// --- Logika Bergerak Zig-Zag ---
turnOffAllRelays();
digitalWrite(relayPins[animZigZag[currentStep]], HIGH);
currentStep++;
if (currentStep >= 16) {
currentStep = 0; // Ulangi dari awal
}
}
}
}Power
Relay 16 Channel MATRIX