#include <U8glib.h> // 또는 U8g2lib 등 사용하는 라이브러리
// OLED 객체 (사용하는 OLED 및 인터페이스에 맞게 수정)
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // 기존 U8glib 사용 시
// 핀 정의
const int JOYSTICK_X_PIN = A1;
const int JOYSTICK_Y_PIN = A2;
// 조이스틱 설정
const int JOYSTICK_CENTER = 512; // 조이스틱 중앙값 (10비트 ADC 기준)
const int JOYSTICK_DEADZONE = 100; // 데드존 설정 (값 조정 가능)
const int JOYSTICK_RETURN_DEADZONE = 50;
// 메뉴 아이템
const char* menuItems[] = {"Menu A", "Menu B", "Menu C", "Menu D", "Menu E"};
const int NUM_MENU_ITEMS = sizeof(menuItems) / sizeof(menuItems[0]);
// 메뉴 상태 변수
int currentMenuIndex = 0;
bool joystickMoved = false;
bool menuNeedsUpdate = true; // <<< 추가: 메뉴 업데이트 필요 여부 플래그 (초기값 true)
// 디스플레이 설정 (선택 사항)
const int MENU_TEXT_X = 5;
const int MENU_TEXT_Y = 30;
// 타이밍 (논블로킹 방식)
unsigned long lastMoveTime = 0;
const long moveDelay = 200;
void setup() {
Serial.begin(9600);
pinMode(JOYSTICK_X_PIN, INPUT);
pinMode(JOYSTICK_Y_PIN, INPUT);
if (u8g.getMode() == U8G_MODE_BW) {
u8g.setColorIndex(1);
}
// u8g.begin(); // 필요 시 호출
Serial.println("Setup complete. Ready.");
// 초기 메뉴를 한 번 그려줍니다. (menuNeedsUpdate가 true이므로 loop에서 그려짐)
}
void loop() {
unsigned long currentTime = millis();
int joystickX = analogRead(JOYSTICK_X_PIN);
int joystickY = analogRead(JOYSTICK_Y_PIN);
bool isOutsideDeadzone = (abs(joystickX - JOYSTICK_CENTER) > JOYSTICK_DEADZONE ||
abs(joystickY - JOYSTICK_CENTER) > JOYSTICK_DEADZONE);
bool isInsideCenter = (abs(joystickX - JOYSTICK_CENTER) < JOYSTICK_RETURN_DEADZONE &&
abs(joystickY - JOYSTICK_CENTER) < JOYSTICK_RETURN_DEADZONE);
if (currentTime - lastMoveTime > moveDelay) {
if (isOutsideDeadzone) {
if (!joystickMoved) {
// 메뉴 인덱스 순환 증가
currentMenuIndex = (currentMenuIndex + 1) % NUM_MENU_ITEMS;
joystickMoved = true;
lastMoveTime = currentTime;
menuNeedsUpdate = true; // <<< 변경: 메뉴 인덱스가 바뀌었으므로 업데이트 필요
Serial.print("Menu Index Advanced to: "); Serial.println(menuItems[currentMenuIndex]);
}
}
}
if (isInsideCenter) {
if (joystickMoved) {
Serial.println("Joystick centered, ready for next move.");
}
joystickMoved = false;
}
// 메뉴 그리기 (변경이 필요할 때만) <<< 수정된 부분
if (menuNeedsUpdate) {
drawMenu();
menuNeedsUpdate = false; // 업데이트 완료 후 플래그 리셋
Serial.println("Menu Redrawn."); // 디버깅 메시지 추가 (선택 사항)
}
// 여기에 다른 작업 추가 가능
}
void drawMenu() {
u8g.firstPage();
do {
u8g.setFont(u8g_font_unifont);
u8g.drawStr(MENU_TEXT_X, MENU_TEXT_Y, menuItems[currentMenuIndex]);
// (선택 사항) 추가적인 UI 요소 그리기
} while (u8g.nextPage());
}