Cycle accélération, pause, décélération Moteur pas à pas déclenché par 1 bouton avec L298N + Arduino
Description :
Ce projet a pour but de maîtriser le mouvement d’un moteur pas à pas piloté par un Arduino et un driver L298N. L’objectif est de démontrer comment obtenir un mouvement fluide, sans à-coups mécaniques, en intégrant des rampes de vitesse.
Contrairement à un pilotage classique « tout ou rien », le démarrage est progressif (accélération) et l’arrêt est anticipé (décélération), tout cela lancé par un appui sur un bouton.
Prérequis :
- 1 x Carte Arduino Uno
- 1 x L298N
- 1 x Bouton
- 1 x Moteur PAP bipolaire (NEMA17)
- 1 x Alimentation 12V
- 1 x Breadboard
- Fils de connexion
Vidéo de démonstration :
Schéma de câblage :


Code :
#include <AccelStepper.h> // Inclut la bibliothèque pour gérer les moteurs pas à pas avec accélération
// Définition des numéros de broches (pins) de l'Arduino connectées au module L298N
#define IN1 8 // Bobine A - Entrée 1
#define IN2 9 // Bobine A - Entrée 2
#define IN3 10 // Bobine B - Entrée 3
#define IN4 11 // Bobine B - Entrée 4
#define PIN_BOUTON 3 // Broche reliée au bouton poussoir
// Crée l'objet "stepper" en mode 4 fils (FULL4WIRE).
// Note : L'ordre 1-3-2-4 est souvent nécessaire pour que le moteur tourne correctement avec un L298N.
AccelStepper stepper(AccelStepper::FULL4WIRE, IN1, IN2, IN3, IN4);
// Définit une liste d'états possibles pour gérer la logique du cycle (Machine à états)
enum Etat { REPOS, ALLER, PAUSE, RETOUR };
Etat etatActuel = REPOS; // Au démarrage, le programme est en attente (REPOS)
unsigned long chronoPause = 0; // Variable pour stocker le temps écoulé (en millisecondes) lors de la pause
const long distanceCible = 6000; // Définit la destination de l'aller (ici 4000 pas)
void setup() {
pinMode(PIN_BOUTON, INPUT_PULLUP); // Configure la pin 3 en entrée avec résistance de tirage interne (actif à l'état bas)
stepper.setMaxSpeed(1000.0); // Définit la vitesse maximale (en pas par seconde)
stepper.setAcceleration(200.0); // Définit la rampe d'accélération (en pas par seconde carrée)
}
void loop() {
// Cette fonction doit être appelée à chaque passage dans la boucle pour calculer et générer les impulsions du moteur
stepper.run();
switch (etatActuel) {
case REPOS:
// Vérifie si le bouton est pressé (la valeur passe à LOW quand on appuie)
if (digitalRead(PIN_BOUTON) == LOW) {
stepper.enableOutputs(); // RÉVEIL : Réactive le courant dans les bobines
stepper.moveTo(distanceCible); // Prépare le moteur à aller jusqu'à la position 4000
etatActuel = ALLER; // Change l'état pour passer à l'étape suivante
}
break;
case ALLER:
// Vérifie si la distance restant à parcourir est égale à 0 (moteur arrivé)
if (stepper.distanceToGo() == 0) {
chronoPause = millis(); // Enregistre l'heure actuelle (en ms) pour débuter le décompte de la pause
etatActuel = PAUSE; // Change l'état vers la pause
}
break;
case PAUSE:
// Calcule si 1,5 seconde (1500 ms) se sont écoulées depuis le début de la pause
if (millis() - chronoPause >= 1500) {
stepper.moveTo(0); // Prépare le moteur à revenir à sa position d'origine (0)
etatActuel = RETOUR; // Change l'état pour lancer le mouvement de retour
}
break;
case RETOUR:
// Vérifie si le moteur est revenu au point de départ
if (stepper.distanceToGo() == 0) {
stepper.disableOutputs(); // SOMMEIL : Coupe le courant pour éviter la chauffe
etatActuel = REPOS; // Remet le système au repos, prêt pour un nouvel appui sur le bouton
}
break;
}
}
