#include <LiquidCrystal_I2C.h>
#include <SdFat.h>
#define MAX_FILENAME_LENGTH 16
// Pins des encodeurs rotatifs
#define CLK1 2
#define DT1 3
#define SW1 4
#define CLK2 5
#define DT2 6
#define SW2 7
#define CLK3 8
#define DT3 9
#define SW3 10
// Déclarations LCD et SD
LiquidCrystal_I2C lcd(0x27, 16, 2);
SdFat SD;
const uint8_t SD_CS_PIN = 53;
// État du menu
enum MenuState { SPLASH, NORMAL, EDIT };
MenuState currentMenu = SPLASH;
// Variables pour la capture alphanumérique
char filename[MAX_FILENAME_LENGTH + 1] = ""; // Nom du fichier
int cursorPos = 0; // Position du curseur dans le nom de fichier
int charIndex = 0; // Index du caractère sélectionné
const char charSet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const int charSetSize = sizeof(charSet) - 1;
// Variables pour les encodeurs
int lastStateCLK1, lastStateCLK2, lastStateCLK3;
// Initialisation
void setup() {
lcd.init();
lcd.clear();
lcd.backlight();
Serial.begin(9600);
pinMode(CLK1, INPUT);
pinMode(DT1, INPUT);
pinMode(SW1, INPUT_PULLUP);
pinMode(CLK2, INPUT);
pinMode(DT2, INPUT);
pinMode(SW2, INPUT_PULLUP);
pinMode(CLK3, INPUT);
pinMode(DT3, INPUT);
pinMode(SW3, INPUT_PULLUP);
lastStateCLK1 = digitalRead(CLK1);
lastStateCLK2 = digitalRead(CLK2);
lastStateCLK3 = digitalRead(CLK3);
// Splash Screen
splashScreen();
currentMenu = NORMAL;
displayNormalMenu();
}
// Boucle principale
void loop() {
switch (currentMenu) {
case NORMAL:
checkNormalMenuInput();
break;
case EDIT:
checkEditMenuInput();
break;
default:
break;
}
}
// Écran de démarrage
void splashScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Welcome to Synth!");
lcd.setCursor(0, 1);
lcd.print("Loading...");
delay(2000);
lcd.clear();
}
// Menu Normal
void displayNormalMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mode: Normal");
lcd.setCursor(0, 1);
lcd.print("Press SW1+SW2");
}
// Menu Edition
void displayEditMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Edit Filename:");
lcd.setCursor(0, 1);
lcd.print(filename);
}
// Retour au menu normal
void returnToNormalMenu() {
currentMenu = NORMAL;
displayNormalMenu();
}
// Capture alphanumérique
void updateFilenameDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Editing:");
lcd.setCursor(0, 1);
lcd.print(filename);
lcd.setCursor(cursorPos, 1);
lcd.print("^");
}
// Vérification des entrées en mode normal
void checkNormalMenuInput() {
if (digitalRead(SW1) == LOW && digitalRead(SW2) == LOW) {
delay(200); // Anti-rebond
currentMenu = EDIT;
displayEditMenu();
}
}
// Vérification des entrées en mode édition
void checkEditMenuInput() {
int currentStateCLK1 = digitalRead(CLK1);
if (currentStateCLK1 != lastStateCLK1 && currentStateCLK1 == 1) {
if (digitalRead(DT1) != currentStateCLK1) {
charIndex = (charIndex + 1) % charSetSize;
} else {
charIndex = (charIndex - 1 + charSetSize) % charSetSize;
}
filename[cursorPos] = charSet[charIndex];
updateFilenameDisplay();
}
lastStateCLK1 = currentStateCLK1;
if (digitalRead(SW1) == LOW) { // Validation du caractère
cursorPos = (cursorPos + 1) % MAX_FILENAME_LENGTH;
filename[cursorPos] = '\0'; // Met à jour la chaîne
updateFilenameDisplay();
delay(200); // Anti-rebond
}
int currentStateCLK2 = digitalRead(CLK2);
if (currentStateCLK2 != lastStateCLK2 && currentStateCLK2 == 1) {
if (digitalRead(DT2) != currentStateCLK2) {
cursorPos = (cursorPos + 1) % MAX_FILENAME_LENGTH;
} else {
cursorPos = (cursorPos - 1 + MAX_FILENAME_LENGTH) % MAX_FILENAME_LENGTH;
}
updateFilenameDisplay();
}
lastStateCLK2 = currentStateCLK2;
if (digitalRead(SW2) == LOW) { // Suppression du caractère sous le curseur
filename[cursorPos] = ' ';
updateFilenameDisplay();
delay(200); // Anti-rebond
}
if (digitalRead(SW3) == LOW) { // Retour au menu normal
delay(200); // Anti-rebond
returnToNormalMenu();
}
}