#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <AccelStepper.h>
// Définir les broches du moteur pas à pas
#define motorInterfaceType 4
#define motor1_pin1 3
#define motor1_pin2 11
#define motor2_pin1 12
#define motor2_pin2 13
// Définir les broches des boutons
#define resetButtonPin 7
#define pageButtonPin 8
#define selectButtonPin 9
#define manualButtonPin 10 // Nouveau bouton jaune pour faire tourner le moteur manuellement
// Définir la broche du potentiomètre
#define potPin A0
// Initialisation des instances
AccelStepper stepper(motorInterfaceType, motor1_pin1, motor1_pin2, motor2_pin1, motor2_pin2);
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS3231 rtc;
// Variables globales
int currentPage = 1; // Page actuelle (1 = heure/rotations, 2 = programmation, 3 = définir tours)
int rotationCount = 0; // Compteur de rotations
int selectedProgram = -1; // Programme sélectionné (-1 = aucun, 0, 1, 2 = programme 1, 2, 3)
int selectedField = -1; // Champ sélectionné (-1 = aucun, 0 = heures, 1 = minutes, 2 = tours)
int progHour[3] = {10, 11, 11}; // Heures de distribution programmées
int progMinute[3] = {50, 1, 15}; // Minutes de distribution programmées
int progTurns[3] = {30, 0, 20}; // Nombre de tours définis pour chaque programme
bool rotationCompleted[3] = {false, false, false}; // Indique si une rotation a été effectuée pour chaque programme
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 200; // Anti-rebond pour les boutons
unsigned long blinkTimer = 0; // Timer pour gérer le clignotement
bool blinkState = true; // État de clignotement
DateTime now;
// Variables pour gérer le bouton jaune
unsigned long manualButtonPressTime = 0; // Pour détecter combien de temps le bouton est pressé
bool manualButtonPressed = false; // Indique si le bouton jaune est pressé
void setup() {
lcd.begin(20, 4);
lcd.backlight();
stepper.setMaxSpeed(400);
stepper.setAcceleration(100);
pinMode(resetButtonPin, INPUT_PULLUP);
pinMode(pageButtonPin, INPUT_PULLUP);
pinMode(selectButtonPin, INPUT_PULLUP);
pinMode(manualButtonPin, INPUT_PULLUP); // Définir le bouton jaune en entrée
if (!rtc.begin()) {
lcd.print("Erreur RTC");
while (1); // Arrêter si RTC non trouvé
}
lcd.setCursor(0, 0);
lcd.print("DEMARRAGE DU (o> ");
lcd.setCursor(0, 1);
lcd.print("DISTRIBUTEUR /\ ");
lcd.setCursor(0, 2);
lcd.print("D'ALIMENTS V_/_ ");
delay(5000);
lcd.clear();
}
void loop() {
now = rtc.now();
handleButtons();
if (currentPage == 1) {
displayMainPage();
} else if (currentPage == 2) {
displayProgrammingPage();
} else if (currentPage == 3) {
displayDefineTurnsPage();
}
checkMotorActivation();
// Gestion du bouton jaune pour tourner manuellement
handleManualButton();
}
void handleButtons() {
if (digitalRead(pageButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
currentPage = (currentPage % 3) + 1; // Passer à la page suivante (1 -> 2 -> 3 -> 1)
lcd.clear();
}
if (digitalRead(selectButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
if (currentPage == 2) {
if (selectedProgram == -1) {
selectedProgram = 0;
} else if (selectedField == -1) {
selectedField = 0; // Sélectionner l'heure
} else if (selectedField == 0) {
selectedField = 1; // Sélectionner les minutes
} else if (selectedField == 1) {
selectedField = 2; // Sélectionner le nombre de tours
} else if (selectedField == 2) {
selectedField = -1; // Réinitialiser la sélection
selectedProgram++;
if (selectedProgram > 2) {
selectedProgram = -1;
}
}
} else if (currentPage == 3) {
// Confirmer le nombre de tours et revenir à la page principale
lcd.clear();
currentPage = 1;
}
}
if (digitalRead(resetButtonPin) == LOW && millis() - lastDebounceTime > debounceDelay) {
lastDebounceTime = millis();
rotationCount = 0;
lcd.clear();
}
}
void displayMainPage() {
lcd.setCursor(0, 0);
lcd.print("HEURE: ");
lcd.print(now.hour(), DEC);
lcd.print(":");
if (now.minute() < 10) lcd.print("0");
lcd.print(now.minute(), DEC);
lcd.print(":");
if (now.second() < 10) lcd.print("0");
lcd.print(now.second(), DEC);
lcd.setCursor(0, 1);
lcd.print("Rotations: ");
lcd.print(rotationCount);
lcd.setCursor(0, 2);
lcd.print("Defini: ");
lcd.print(progTurns[0]); // Afficher le nombre de tours du programme 1
lcd.print(" tours");
}
void displayProgrammingPage() {
lcd.setCursor(0, 0);
lcd.print("PROGRAMMATION");
if (millis() - blinkTimer >= 500) {
blinkTimer = millis();
blinkState = !blinkState;
}
for (int i = 0; i < 3; i++) {
lcd.setCursor(0, i + 1);
lcd.print("PROG ");
lcd.print(i + 1);
lcd.print(": ");
if (selectedProgram == i && selectedField == 0 && blinkState) {
lcd.print(" ");
} else {
if (progHour[i] < 10) lcd.print("0");
lcd.print(progHour[i]);
}
lcd.print(":");
if (selectedProgram == i && selectedField == 1 && blinkState) {
lcd.print(" ");
} else {
if (progMinute[i] < 10) lcd.print("0");
lcd.print(progMinute[i]);
}
lcd.print(" | ");
if (selectedProgram == i && selectedField == 2 && blinkState) {
lcd.print(" ");
} else {
lcd.print(progTurns[i]);
}
if (selectedProgram == i) {
int potValue = analogRead(potPin);
if (selectedField == 0) {
progHour[i] = map(potValue, 0, 1023, 0, 23); // Modifier l'heure
} else if (selectedField == 1) {
progMinute[i] = map(potValue, 0, 1023, 0, 59); // Modifier les minutes
} else if (selectedField == 2) {
progTurns[i] = map(potValue, 0, 1023, 0, 50); // Modifier les tours
}
}
}
}
void displayDefineTurnsPage() {
lcd.setCursor(0, 0);
lcd.print("TOURS PAR PROG");
for (int i = 0; i < 3; i++) {
lcd.setCursor(0, i + 1);
lcd.print("Prog ");
lcd.print(i + 1);
lcd.print(": ");
if (selectedProgram == i && blinkState) {
lcd.print(" ");
} else {
lcd.print(progTurns[i]);
}
}
if (millis() - blinkTimer >= 500) {
blinkTimer = millis();
blinkState = !blinkState;
}
if (selectedProgram != -1 && selectedField == 2) {
// Plage mappée de 0 à 50
int potValue = analogRead(potPin);
progTurns[selectedProgram] = map(potValue, 0, 1023, 0, 50);
}
}
void checkMotorActivation() {
for (int i = 0; i < 3; i++) {
if (now.hour() == progHour[i] && now.minute() == progMinute[i] && !rotationCompleted[i]) {
performMotorRotation(progTurns[i]); // Utilise le nombre de tours défini pour ce programme
rotationCompleted[i] = true;
} else if (now.minute() != progMinute[i]) {
rotationCompleted[i] = false;
}
}
}
void handleManualButton() {
if (digitalRead(manualButtonPin) == LOW) {
if (!manualButtonPressed) {
manualButtonPressed = true;
manualButtonPressTime = millis();
}
} else {
if (manualButtonPressed) {
unsigned long pressDuration = millis() - manualButtonPressTime;
if (pressDuration < 1000) {
performMotorRotation(1);
} else {
performMotorRotation(5);
}
manualButtonPressed = false;
}
}
}
void performMotorRotation(int numTurns) {
if (stepper.distanceToGo() == 0) {
stepper.moveTo(stepper.currentPosition() + 200 * numTurns);
while (stepper.distanceToGo() > 0) {
stepper.run();
}
rotationCount += numTurns;
}
}