Bonsoir
voici un code à tester:
#include <Servo.h>
// Création des objets servo pour les deux moteurs
Servo moteur1, moteur2;
// Définition des broches
const byte bpPin = 2;
const byte moteur1Pin = 3;
const byte moteur2Pin = 5;
// Valeurs PWM pour servomoteur 360° (arrêt, sens horaire, sens antihoraire)
const byte stopVitesse = 90;
const byte vitesseAvant = 60;
const byte vitesseArriere = 120;
// Temps d’activité pour chaque phase (en millisecondes)
const uint16_t t1 = 1500, t2 = 2000, t3 = 1800, t4 = 1600;
// Paramètres de rampe douce (durée totale et pas de variation)
const uint16_t rampeDuree = 500;
const byte rampePas = 5;
// Définition des états pour la machine à états
enum Etat {
IDLE, // Attente d'appui ou relâchement
START_M1, // Démarrage progressif moteur 1 en avant
RUN_M1, // Attente après démarrage moteur 1
START_M2, // Démarrage progressif moteur 2 en avant
RUN_M2, // Attente après démarrage moteur 2
START_M2_REV, // Démarrage progressif moteur 2 en arrière
RUN_M2_REV, // Attente après démarrage moteur 2 en arrière
START_M1_REV, // Démarrage progressif moteur 1 en arrière
RUN_M1_REV // Attente après démarrage moteur 1 en arrière
};
Etat etatActuel = IDLE; // État initial
// Variables de timing pour transitions
unsigned long horloge = 0;
// Variables de lecture du bouton
bool bpActuel = true;
bool bpPrecedent = true;
// Variables pour la rampe douce
bool rampeActive = false;
byte rampePWM = stopVitesse;
byte rampeCible = stopVitesse;
Servo* moteurRampe;
void setup() {
pinMode(bpPin, INPUT_PULLUP); // Bouton avec pull-up interne
moteur1.attach(moteur1Pin); // Association servo 1 à sa broche
moteur2.attach(moteur2Pin); // Association servo 2 à sa broche
}
void loop() {
bpActuel = digitalRead(bpPin); // Lecture de l’état du bouton
// Détection des transitions (front montant ou descendant)
if (etatActuel == IDLE && !bpActuel && bpPrecedent)
etatActuel = START_M1; // Passage à la séquence avant
if (etatActuel == IDLE && bpActuel && !bpPrecedent)
etatActuel = START_M2_REV; // Passage à la séquence arrière
bpPrecedent = bpActuel; // Sauvegarde de l’état du bouton
// Machine à états principale
switch (etatActuel) {
case START_M1:
demarreRampe(moteur1, vitesseAvant);
horloge = millis();
etatActuel = RUN_M1;
break;
case RUN_M1:
if (millis() - horloge >= t1) {
moteur1.write(stopVitesse);
demarreRampe(moteur2, vitesseAvant);
horloge = millis();
etatActuel = RUN_M2;
}
break;
case RUN_M2:
if (millis() - horloge >= t2) {
moteur2.write(stopVitesse);
etatActuel = IDLE;
}
break;
case START_M2_REV:
demarreRampe(moteur2, vitesseArriere);
horloge = millis();
etatActuel = RUN_M2_REV;
break;
case RUN_M2_REV:
if (millis() - horloge >= t3) {
moteur2.write(stopVitesse);
demarreRampe(moteur1, vitesseArriere);
horloge = millis();
etatActuel = RUN_M1_REV;
}
break;
case RUN_M1_REV:
if (millis() - horloge >= t4) {
moteur1.write(stopVitesse);
etatActuel = IDLE;
}
break;
}
// ⏳ Rampe douce non bloquante pour moteurs
if (rampeActive && millis() - horloge >= rampeDuree / (abs(rampeCible - stopVitesse) / rampePas)) {
horloge = millis();
if (rampePWM != rampeCible) {
rampePWM += (rampeCible > stopVitesse) ? rampePas : -rampePas;
moteurRampe->write(rampePWM);
} else {
rampeActive = false; // Rampe terminée
}
}
}
// 🌀 Démarre une rampe pour le moteur donné jusqu’à la valeur cible
void demarreRampe(Servo& moteur, byte cible) {
rampePWM = stopVitesse;
rampeCible = cible;
moteurRampe = &moteur;
rampeActive = true;
horloge = millis();
}