Bonjour,
J’ai écrit un programme permettant d’allumer une diode et un moteur à courant continu avec sélection de 3 cycles de temps d'allumage.
Un bouton poussoir est géré par la bibliothèque Onebutton.h. et fonctionne de la façon suivante :
- un appui court allume la diode et le moteur pendant la durée du cycle présélectionné.
- un appui long, d’une durée de 2 secondes, arrête le cycle en cours et éteint diode et moteur.
Le programme fonctionne seulement lorsque le cycle a été choisi avec le commutateur ET que les switch sont tous ouverts… s’il en reste un fermé, le compte a rebours ne s’affiche plus…
Pourriez vous éclairer ma chandelle?
Voici le programme :
#include <OneButton.h>
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const byte in1Pin = 4; // Pin to connect to motor controller board
const byte in2Pin = 5; // Pin to connect to motor controller board
const byte sleepPin = 6; // Pin to disable motor controller sleep mode
const byte buttonPin = 2; // Switch
const byte ledPin = 13; // Arduino Nano integrated LED
const byte switchPin1 = 8; // First switch pin for cycle selection
const byte switchPin2 = 9; // Second switch pin for cycle selection
const byte switchPin3 = 10; // Third switch pin for cycle selection
const unsigned long seuilTemps = 2000; // Seuil de temps d'appui long
OneButton bouton(buttonPin); // Set the button to use INPUT_PULLUP
enum {moteurEtatArrete, moteurEtatDoitDemarrer, moteurEtatMarche, moteurEtatCycleArret, moteurEtatDoitArreter};
int moteurEtat = moteurEtatArrete;
// Durées des cycles (en millisecondes)
const unsigned long cycleDurations[] = {2000, 10000, 15000}; // 2s, 10s, 15s
unsigned long moteurMarcheTempo = cycleDurations[0]; // Temps de marche du moteur par défaut
unsigned long moteurMarcheMillis = 0; // Temps de marche du moteur, chrono
// Dans cette fonction, donc le click simple, on demarre le moteur
void simpleClick() {
if (moteurEtat == moteurEtatArrete) {
Serial.println(F("Moteur doit demarrer"));
moteurEtat = moteurEtatDoitDemarrer;
} else {
Serial.println(F("Moteur deja en marche"));
}
}
// Dans cette fonction, donc le click long, on arrete le moteur et on active le mode sleep
void clickLong() {
Serial.println(F("Moteur cycle doit arreter"));
moteurEtat = moteurEtatCycleArret;
}
// Fonction pour mettre à jour la durée du cycle basée sur la sélection du commutateur
void updateCycleDuration() {
if (digitalRead(switchPin1) == LOW) {
moteurMarcheTempo = cycleDurations[0];
Serial.println(F("Cycle: 2 secondes"));
u8g2.drawStr(0, 10, "2");
} else if (digitalRead(switchPin2) == LOW) {
moteurMarcheTempo = cycleDurations[1];
Serial.println(F("Cycle: 10 secondes"));
u8g2.drawStr(0, 10, "10");
} else if (digitalRead(switchPin3) == LOW) {
moteurMarcheTempo = cycleDurations[2];
Serial.println(F("Cycle: 15 secondes"));
u8g2.drawStr(0, 10, "15");
}
}
void setup() {
Serial.begin(115200);
// Initialisation ecran oled
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_timB10_tf) ; // sélection police de caractère
pinMode(in1Pin, OUTPUT); // Set the motor control pins as outputs
pinMode(in2Pin, OUTPUT); // Set the motor control pins as outputs
pinMode(sleepPin, OUTPUT); // Set the motor control sleep pin as output
pinMode(ledPin, OUTPUT); // Set the led pin as output
pinMode(buttonPin, INPUT_PULLUP); // Enable pull-up resistor for the button
pinMode(switchPin1, INPUT_PULLUP); // Enable pull-up for switch 1
pinMode(switchPin2, INPUT_PULLUP); // Enable pull-up for switch 2
pinMode(switchPin3, INPUT_PULLUP); // Enable pull-up for switch 3
bouton.setPressMs(seuilTemps); // Set long press time
bouton.attachClick(simpleClick); // Function for short press
bouton.attachLongPressStop(clickLong); // Function for long press stop
moteurEtat = moteurEtatDoitArreter;
}
void loop() {
bouton.tick(); // Keep watching the push button
updateCycleDuration(); // Update the cycle duration based on switch input
if (moteurEtat == moteurEtatDoitDemarrer) {
Serial.println(F("Moteur en marche"));
Serial.print(F("Durée du cycle: "));
Serial.print(moteurMarcheTempo / 1000); // Affichage en secondes
Serial.println(F(" secondes"));
u8g2.drawStr(0, 28, "moteurMarcheTempo / 1000");
moteurMarcheMillis = millis(); // Start the timer
moteurDemarrage();
moteurEtat = moteurEtatMarche;
}
if (moteurEtat == moteurEtatDoitArreter) {
Serial.println(F("Moteur Arret"));
moteurArret();
moteurEtat = moteurEtatArrete;
}
if (moteurEtat == moteurEtatCycleArret) {
Serial.println(F("Moteur Arret du cycle"));
moteurArret();
moteurEtat = moteurEtatDoitArreter;
}
if (moteurEtat == moteurEtatMarche) {
unsigned long currentMillis = millis();
unsigned long elapsed = currentMillis - moteurMarcheMillis; // Temps écoulé
unsigned long remaining = moteurMarcheTempo - elapsed; // Temps restant
static unsigned long lastUpdateMillis = 0; // Pour gérer l'affichage une fois par seconde
// Si le temps restant est supérieur à 0
if (remaining > 0) {
// Affichage du compte à rebours toutes les secondes
if (currentMillis - lastUpdateMillis >= 1000) {
lastUpdateMillis = currentMillis; // Mettre à jour le dernier temps d'affichage
// Afficher le temps restant en secondes
Serial.print(F("Temps restant: "));
Serial.print(remaining / 1000); // Convertir millisecondes en secondes
Serial.println(F(" secondes"));
u8g2.drawStr(0, 46, "remaining / 1000");
}
}
// Vérification de la fin du cycle
if (elapsed >= moteurMarcheTempo) {
Serial.println(F("Moteur Fin cycle"));
moteurEtat = moteurEtatDoitArreter;
}
}
}
void moteurDemarrage() {
digitalWrite(ledPin, HIGH);
digitalWrite(sleepPin, HIGH); // Disable the motor controller sleep mode
digitalWrite(in1Pin, HIGH); // Turn the motor on
digitalWrite(in2Pin, LOW); // Turn CW
}
void moteurArret() {
digitalWrite(ledPin, LOW);
digitalWrite(sleepPin, LOW); // Enable the motor controller sleep mode
digitalWrite(in1Pin, LOW); // Turn the motor off
digitalWrite(in2Pin, LOW);
}
et voici le Wokwi :