#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Serial2 pada GPIO 16 (RX) dan 17 (TX)
#define RXD2 16
#define TXD2 17
String currentFloor = "GF";
String currentDirection = "STOP"; // "UP", "DOWN", "STOP"
bool arrowVisible = true;
unsigned long lastBlink = 0;
void setup() {
Serial.begin(115200); // Untuk monitor serial di Wokwi
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED tidak terdeteksi"));
while (true);
}
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(SSD1306_WHITE);
drawScreen();
Serial.println("ESP32 COP siap menerima data...");
}
void loop() {
receiveSerial();
handleBlink();
}
void receiveSerial() {
static String input = "";
while (Serial2.available()) {
char c = Serial2.read();
if (c == '\n') {
input.trim();
if (input.length() > 0) {
Serial.print("[ESP32 COP] Diterima: ");
Serial.println(input);
parseCommand(input);
}
input = "";
} else {
input += c;
}
}
}
void parseCommand(String cmd) {
if (cmd.startsWith("LANTAI:")) {
currentFloor = cmd.substring(7);
drawFloor();
} else if (cmd.startsWith("ARAH:")) {
currentDirection = cmd.substring(5);
drawArrow(); // langsung update panah saat arah berubah
}
}
void drawScreen() {
display.clearDisplay();
drawFloor();
drawArrow();
display.display();
}
void drawFloor() {
display.fillRect(0, 0, SCREEN_WIDTH, 40, SSD1306_BLACK);
display.setCursor(10, 15);
display.setTextSize(4);
display.setTextColor(SSD1306_WHITE);
display.print(currentFloor);
display.display();
}
void drawArrow() {
display.fillRect(0, 50, SCREEN_WIDTH, 14, SSD1306_BLACK);
if (currentDirection == "UP" && arrowVisible) {
display.fillTriangle(64, 50, 54, 63, 74, 63, SSD1306_WHITE);
} else if (currentDirection == "DOWN" && arrowVisible) {
display.fillTriangle(64, 63, 54, 50, 74, 50, SSD1306_WHITE);
}
display.display();
}
void handleBlink() {
if (currentDirection == "UP" || currentDirection == "DOWN") {
if (millis() - lastBlink >= 200) {
arrowVisible = !arrowVisible;
drawArrow();
lastBlink = millis();
}
} else {
arrowVisible = false;
drawArrow();
}
}