// ---------------------------------------------------------------- //
// PROJEKT: DART COUNTER v0.1 //
// Autor: Twój pomysł, realizacja AI //
// Cel: Wyświetlanie menu i nawigacja joystickiem //
// ---------------------------------------------------------------- //
// --- Dołączanie bibliotek ---
//#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// --- Definicje pinów dla wyświetlacza TFT (interfejs SPI) ---
#define TFT_CS 5
#define TFT_DC 4
#define TFT_RST 2
// --- Definicje pinów dla joysticka ---
#define JOY_X_PIN 34 // Oś X - poruszanie góra/dół
#define JOY_Y_PIN 35 // Oś Y - nieużywana w tym kodzie, ale podłączona
#define JOY_SW_PIN 27 // Przycisk joysticka
// --- Inicjalizacja obiektu wyświetlacza ---
// Używamy sprzętowego SPI (HSPI na ESP32: SCK=18, MOSI=23)
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// --- Zmienne globalne dla menu ---
const char* menuItems[] = {"GRA", "GRACZE", "UST. PILOTA"};
const int itemCount = sizeof(menuItems) / sizeof(menuItems[0]);
int selectedItem = 0;
int lastSelectedItem = -1; // -1, aby wymusić pierwsze rysowanie menu
// --- Zmienne dla obsługi joysticka ---
unsigned long lastJoyMoveTime = 0;
const int joyDebounceDelay = 200; // Opóźnienie w ms, aby uniknąć zbyt szybkiego przewijania
// ================================================================= //
// SETUP //
// ================================================================= //
void setup() {
Serial.begin(115200);
Serial.println("Start projektu DART COUNTER!");
// --- Konfiguracja pinów joysticka ---
pinMode(JOY_SW_PIN, INPUT_PULLUP); // Włączamy wewnętrzny rezystor podciągający dla przycisku
// --- Inicjalizacja wyświetlacza TFT ---
tft.begin();
tft.setRotation(1); // Orientacja pozioma (można zmienić na 3 w zależności od montażu)
tft.fillScreen(ILI9341_BLACK); // Czyścimy ekran na czarno
Serial.println("Wyświetlacz TFT zainicjowany.");
}
// ================================================================= //
// LOOP //
// ================================================================= //
void loop() {
handleJoystickInput();
// Rysujemy menu tylko wtedy, gdy zmienił się wybrany element
// To zapobiega migotaniu ekranu
if (selectedItem != lastSelectedItem) {
drawMenu();
lastSelectedItem = selectedItem;
}
// Sprawdzanie naciśnięcia przycisku joysticka
if (digitalRead(JOY_SW_PIN) == LOW) {
Serial.print("Wybrano opcję: ");
Serial.println(menuItems[selectedItem]);
// Tutaj w przyszłości będzie akcja po wybraniu opcji
// np. przejście do nowego ekranu
delay(500); // Proste opóźnienie, aby uniknąć wielokrotnego odczytu
}
}
// ================================================================= //
// FUNKCJE POMOCNICZE //
// ================================================================= //
/**
* @brief Rysuje menu na ekranie TFT.
* Podświetla aktualnie wybraną pozycję.
*/
void drawMenu() {
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(3); // Ustawiamy rozmiar czcionki
for (int i = 0; i < itemCount; i++) {
// Obliczamy pozycję Y dla każdego elementu menu
int16_t yPos = 60 + (i * 40);
if (i == selectedItem) {
// Wybrany element: biały tekst na niebieskim tle
tft.fillRoundRect(20, yPos - 10, tft.width() - 40, 40, 8, ILI9341_BLUE);
tft.setTextColor(ILI9341_WHITE);
} else {
// Niewybrany element: biały tekst na czarnym tle
tft.setTextColor(ILI9341_WHITE);
}
// Ustawiamy kursor i drukujemy tekst
tft.setCursor(40, yPos);
tft.println(menuItems[i]);
}
}
/**
* @brief Odczytuje stan joysticka i aktualizuje wybraną pozycję w menu.
*/
void handleJoystickInput() {
// Sprawdzamy, czy minęło wystarczająco dużo czasu od ostatniego ruchu
if (millis() - lastJoyMoveTime > joyDebounceDelay) {
int xValue = analogRead(JOY_X_PIN); // Odczyt osi X
// Joystick w dół (wartości mogą wymagać kalibracji)
if (xValue > 3500) {
selectedItem++;
if (selectedItem >= itemCount) {
selectedItem = 0; // Zapętlamy menu
}
lastJoyMoveTime = millis(); // Zapisujemy czas ostatniego ruchu
}
// Joystick w górę (wartości mogą wymagać kalibracji)
else if (xValue < 500) {
selectedItem--;
if (selectedItem < 0) {
selectedItem = itemCount - 1; // Zapętlamy menu
}
lastJoyMoveTime = millis(); // Zapisujemy czas ostatniego ruchu
}
}
}