/*
* ========================================================
* DUAL OLED DISPLAY - ESP32
* ========================================================
*
* Hardware Configuration:
* - Board: ESP32
* - Display 1 (Video): SSD1306 OLED 128x64 @ I2C 0x3C
* - Display 2 (Lirik/Foto): SSD1306 OLED 128x64 @ I2C 0x3D
*
* Wiring:
* - SDA: GPIO 21 (default ESP32)
* - SCL: GPIO 22 (default ESP32)
* - Both displays share the same I2C bus
*
* Libraries Required:
* - Adafruit GFX Library
* - Adafruit SSD1306
*
* ========================================================
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "VideoFrameDisplay1.h" // Data untuk Display 1 (Video)
#include "VideoFrameDisplay2.h" // Data untuk Display 2 (Lirik/Foto)
// ========================================================
// KONFIGURASI LAYAR
// ========================================================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
// Alamat I2C untuk masing-masing layar
#define DISPLAY1_ADDRESS 0x3C // Layar 1: Video
#define DISPLAY2_ADDRESS 0x3D // Layar 2: Lirik/Foto
// ========================================================
// INISIALISASI OBJEK DISPLAY
// ========================================================
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ========================================================
// VARIABEL UNTUK TRACKING FRAME
// ========================================================
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
int currentFrame1 = 0;
int currentFrame2 = 0;
// ========================================================
// SETUP - Dijalankan sekali saat startup
// ========================================================
void setup() {
Serial.begin(115200);
Serial.println("\n========================================");
Serial.println("ESP32 Dual OLED Display - Starting...");
Serial.println("========================================");
// Set I2C speed ke 800 kHz untuk performa optimal
Wire.setClock(800000);
delay(100);
// Inisialisasi Display 1 (0x3C - Video)
Serial.print("Initializing Display 1 (0x3C)... ");
if(!display1.begin(SSD1306_SWITCHCAPVCC, DISPLAY1_ADDRESS)) {
Serial.println("FAILED!");
Serial.println("Display 1 tidak terdeteksi pada alamat 0x3C");
Serial.println("Periksa koneksi I2C dan alamat display!");
while(1); // Berhenti jika display 1 gagal
}
Serial.println("OK!");
// Inisialisasi Display 2 (0x3D - Lirik/Foto)
Serial.print("Initializing Display 2 (0x3D)... ");
if(!display2.begin(SSD1306_SWITCHCAPVCC, DISPLAY2_ADDRESS)) {
Serial.println("FAILED!");
Serial.println("Display 2 tidak terdeteksi pada alamat 0x3D");
Serial.println("Periksa koneksi I2C dan alamat display!");
while(1); // Berhenti jika display 2 gagal
}
Serial.println("OK!");
// Clear kedua display
display1.clearDisplay();
display1.display();
display2.clearDisplay();
display2.display();
// Tampilkan info frame
Serial.println("\n========================================");
Serial.println("Configuration:");
Serial.println("========================================");
Serial.print("Display 1 - Total Frames: ");
Serial.println(TOTAL_FRAMES_1);
Serial.print("Display 1 - Frame Delay: ");
Serial.print(FRAME_DELAY_1);
Serial.println(" ms");
Serial.print("Display 2 - Total Frames: ");
Serial.println(TOTAL_FRAMES_2);
Serial.print("Display 2 - Frame Delay: ");
Serial.print(FRAME_DELAY_2);
Serial.println(" ms");
Serial.println("========================================");
Serial.println("Starting video playback...\n");
}
// ========================================================
// LOOP - Dijalankan berulang-ulang
// ========================================================
void loop() {
unsigned long currentMillis = millis();
// ========================================
// Update Display 1 (Video)
// ========================================
if (currentMillis - previousMillis1 >= FRAME_DELAY_1) {
previousMillis1 = currentMillis;
display1.clearDisplay();
display1.drawBitmap(0, 0, video_frames_1[currentFrame1], SCREEN_WIDTH, SCREEN_HEIGHT, WHITE);
display1.display();
currentFrame1++;
if (currentFrame1 >= TOTAL_FRAMES_1) {
currentFrame1 = 0; // Loop kembali ke frame 0
}
}
// ========================================
// Update Display 2 (Lirik/Foto)
// ========================================
if (currentMillis - previousMillis2 >= FRAME_DELAY_2) {
previousMillis2 = currentMillis;
display2.clearDisplay();
display2.drawBitmap(0, 0, video_frames_2[currentFrame2], SCREEN_WIDTH, SCREEN_HEIGHT, WHITE);
display2.display();
currentFrame2++;
if (currentFrame2 >= TOTAL_FRAMES_2) {
currentFrame2 = 0; // Loop kembali ke frame 0
}
}
// Optional: Print status setiap 1 detik
static unsigned long lastPrint = 0;
if (currentMillis - lastPrint >= 1000) {
lastPrint = currentMillis;
Serial.print("Display 1 Frame: ");
Serial.print(currentFrame1);
Serial.print("/");
Serial.print(TOTAL_FRAMES_1);
Serial.print(" | Display 2 Frame: ");
Serial.print(currentFrame2);
Serial.print("/");
Serial.println(TOTAL_FRAMES_2);
}
}
Loading
grove-oled-sh1107
grove-oled-sh1107