#include #include #include #include #include #define SCREEN_WIDTH 96 #define SCREEN_HEIGHT 16 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // ---------------- PINS ---------------- const int SD_CS = 53; const int CD_PIN = 2; // Buttons const int R1 = 23; const int R2 = 24; const int R3 = 25; const int C1 = 26; // ---------------- FILES ---------------- char files[50][32]; int fileCount = 0; // ---------------- UI ---------------- int cursor = 0; int scroll = 0; int selected = -1; // ---------------- CARD STATE ---------------- bool lastCardState = false; // CD is inverted in your module bool cardInserted() { return digitalRead(CD_PIN) == HIGH; } // ---------------- OLED ---------------- void msg(const char* text) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 4); display.println(text); display.display(); } void drawMenu() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); for (int i = 0; i < 2; i++) { int idx = scroll + i; if (idx >= fileCount) break; display.setCursor(0, i * 8); if (idx == selected) display.print("*"); // selected else if (idx == cursor) display.print(">"); // cursor else display.print(" "); String name = files[idx]; if (name.length() > 12) name = name.substring(0, 12); display.print(name); } display.display(); } // ---------------- SD SCAN ---------------- void scanSD() { fileCount = 0; File root = SD.open("/"); if (!root) return; while (true) { File entry = root.openNextFile(); if (!entry) break; if (!entry.isDirectory()) { String name = entry.name(); if (name.endsWith(".GCO") || name.endsWith(".GCODE")) { if (fileCount < 50) { name.toCharArray(files[fileCount], 32); fileCount++; } } } entry.close(); } root.close(); } // ---------------- BUTTONS ---------------- int readButton() { digitalWrite(C1, LOW); delayMicroseconds(5); if (digitalRead(R1) == LOW) return 1; if (digitalRead(R2) == LOW) return 2; if (digitalRead(R3) == LOW) return 3; return 0; } void waitRelease() { while (readButton() != 0) delay(10); } // ---------------- SETUP ---------------- void setup() { Serial.begin(115200); pinMode(R1, INPUT_PULLUP); pinMode(R2, INPUT_PULLUP); pinMode(R3, INPUT_PULLUP); pinMode(C1, OUTPUT); digitalWrite(C1, HIGH); pinMode(CD_PIN, INPUT_PULLUP); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); lastCardState = cardInserted(); if (lastCardState) { msg("SD inserted"); SD.begin(SD_CS); scanSD(); delay(1000); } else { msg("No SD card"); delay(1000); } drawMenu(); } // ---------------- LOOP ---------------- void loop() { bool current = cardInserted(); // ---------------- INSERT EVENT ---------------- if (current && !lastCardState) { msg("Card inserted"); delay(1000); if (SD.begin(SD_CS)) { scanSD(); cursor = 0; scroll = 0; } drawMenu(); } // ---------------- REMOVE EVENT ---------------- if (!current && lastCardState) { msg("Card removed"); delay(1000); fileCount = 0; cursor = 0; scroll = 0; selected = -1; } lastCardState = current; // ---------------- NO CARD ---------------- if (!current) { msg("NO SD CARD"); delay(200); return; } // ---------------- BUTTONS ---------------- int btn = readButton(); if (btn == 0) return; if (btn == 1 && cursor > 0) cursor--; if (btn == 2 && cursor < fileCount - 1) cursor++; if (btn == 3) { selected = cursor; Serial.print("Selected: "); Serial.println(files[selected]); } if (cursor < scroll) scroll = cursor; if (cursor > scroll + 1) scroll = cursor - 1; waitRelease(); drawMenu(); }