Performance et accélération AccelStepper

Bonjour à tous,
Je finalise un projet pour un menuisier et je rencontre des soucis de performance avec Accelstepper. C'est un guide avec vis à billes au pas de 10mm, moteur stepper Nema 34 avec codeur et driver que pilote avec un Esp32 Wroom, le tout contrôler par un IHM Nextion.

J'arrive au bout du programme, tout fonctionne mais les performances avec Accelstepper ne sont pas terrible. Lors des phases d'accélération la rampe n'est pas linéaire mais fait fait plutôt un escalier. J'ai réduis les micro step à 1000, c'est mieux mais j'aimerais faire mieux.
Dans la documentation c'est mentionné " 4 000 pas par seconde à une fréquence d'horloge de 16 MHz sur Arduino tel que Uno ".

Est-ce quelqu'un pourrait m'éclairer sur le bon usage de cette bibliothèque et les performances que je peux en attendre ?

Mes paramètres sont:
Vitesse 26000 step/s
Acceleration 16000 step/s²
Moteur 3200 step/tour

La boucle principale du code est assez courte, et l'ensemble des calculs de mouvements se font dans des triggers (void) :

void loop() {	
  myNex.NextionListen(); // ne pas rater de trigger
  stepper.run();
  sw_stop.update();
  sw_init.update();	
  
	if(sw_stop.read() == HIGH and initialisation == false and bt_init == true ){	// Cycle d'initialisation
		switch (etape) {
		  
		  case 1:
			stepper.setCurrentPosition(0); // on initialise stepper
			stepper.setMaxSpeed(petite_vitesse);	// petite vitesse pour initialisation
			stepper.setAcceleration(500000);	// on réduit le temps d'accélération (step/s) à son minimum pour le reset
			Serial.println("etape = 1");
			if(digitalRead(pin_capteur_1) == HIGH){
				Serial.println("etape = 2");
				etape = 2;
			}
			if(digitalRead(pin_capteur_1) == LOW){
				Serial.println("etape = 4");
				etape = 4;
				}
			break;
		  case 2:
			stepper.moveTo(((course_max - course_min) + offset_calibration) / distance_tour * nb_pas_tour);	// aller vers la droite en petite vitesse pour accoster capteur			
			if(digitalRead(pin_capteur_1) == LOW){
				Serial.println("etape = 3");
				etape = 3;
			}	
			break;
		  case 3:
			stepper.stop();
			if(stepper.distanceToGo() == 0){
				stepper.setCurrentPosition(0); // on initialise stepper
				Serial.println("etape = 4");
				etape = 4;
			}	
			break;
		  case 4:
			stepper.moveTo(-quitter_capteur / distance_tour * nb_pas_tour);	// quitter le capteur en petite vitesse vers la gauche
			if(stepper.distanceToGo() == 0 and digitalRead(pin_capteur_1) == HIGH){
				Serial.println("etape = 5");
				etape = 5;
			}
			break;
		  case 5:
			stepper.stop();
			if(stepper.distanceToGo() == 0){
				stepper.setCurrentPosition(0); 		// on initialise stepper
				stepper.setMaxSpeed(1000);			// changement de vitesse en step/s pour accoster le capteur au ralenti
				Serial.println("etape = 6");
				etape = 6;
			}				
			break;
		  case 6:
			stepper.moveTo((quitter_capteur + 1) / distance_tour * nb_pas_tour);	// aller vers la droite en vitesse lente pour toucher capteur
			if(digitalRead(pin_capteur_1) == LOW){
				Serial.println("etape = 7");
				etape = 7;
			}
			break;
		  case 7:
			stepper.stop();
			if(stepper.distanceToGo() == 0){ // on vérifie que le moteur est bien arrêté
				Serial.println("etape = 8");
				etape = 8;
			}				
			break;
		  case 8:
			stepper.setCurrentPosition(course_max / distance_tour * nb_pas_tour); // on initialise stepper à la course maximum
			stepper.setMaxSpeed(grande_vitesse);	  // grande vitesse quand on est pas en cours d'initialisation 
			stepper.setAcceleration(acceleration);	// accélération normale 
			myNex.writeStr("init.val=1");  // variable Init à 1 quand le cycle est complet
			myNex.writeStr("page Main");
			number_str = String((course_max + offset_calibration),1);
			myNex.writeStr("t1.txt", number_str); // mettre à jour la zone A Main
			myNex.writeStr("t0.txt", ""); // effacer la zone B Main
			initialisation = true; // Initialisation faite
			Serial.println("etape = 9");
			etape = 1;
			break;			  
		}

	}
  
	if(sw_stop.read() == HIGH and initialisation == true){ // Boucle principale en cours de fonctionnement après initialisation
		switch (etape) {
			case 1:				
				if(stepper.isRunning() and millis() >= delai_envoi + 100){					
					delai_envoi = millis();
					number_mm = (stepper.currentPosition() / nb_pas_tour * distance_tour) + offset_calibration;
					number_str = String(number_mm,1);
					myNex.writeStr("t1.txt", number_str);
				}
				else if(stepper.distanceToGo() == 0 and !lec_arret){
					etape = 2;
				}
				break;
			case 2:			
					myNex.writeStr("page Main");
					myNex.writeStr("t0.txt", "");
					number_mm = (stepper.currentPosition() / nb_pas_tour * distance_tour) + offset_calibration;
					number_str = String(number_mm,1);
					myNex.writeStr("t1.txt", number_str); // mettre à jour la zone A Main
					lec_arret = true;
					etape = 1;
				break;
			
		} 
    }
		
	if(sw_stop.fell()) { // Arrêt d'urgence enclanché
		Serial.println("Stop en position urgence");
		stepper.stop(); // Arrêt du moteur
		initialisation = false; // Empêche le mouvement et attends de refaire une initialisation 
		bt_init = false;
		myNex.writeStr("page Menu");  // Afficher la page Menu
		myNex.writeStr("lock.val=1"); // Verrouille le Nextion
		myNex.writeStr("init.val=0"); // Variable init 
		//myNex.writeStr("q0.picc=2");  // Allume le voyant Mode Manuel
    }

	if(sw_stop.read() == LOW){ // Pour faire clignoter le voyant d'arrêt d'urgence
		delai_envoi = (millis() / 700) %2;
		if(delai_envoi == 1) myNex.writeStr("q0.picc=2");  // Allume le voyant Arrêt d'urgence
		if(delai_envoi == 0) myNex.writeStr("q0.picc=1");  // Eteint le voyant Arrêt d'urgence
	}
	
	if(sw_stop.rose()) { // Bouton arrêt d'urgence est relaché
		Serial.println("Stop remis en route");
		myNex.writeStr("lock.val=0");  // Déverrouille l'interface
		myNex.writeStr("q0.picc=1");  // Etein le voyant Mode Manuel
    }	
} 

void trigger7(){	// Bouton Départ page Main
	number_str = myNex.readStr("Main.t0.txt"); // lire la zone B de la page Main, cible demandée
	if (number_str != ""){	// Si la zone B n'est pas vide
		signe = 0;
		cptp = 0;
		cptm = 0;
		cptf = 0;
		cptd = 0;
		longueur = number_str.length();		
		cptp = number_str.indexOf('+'); // recherche du signe + (0 = signe au début de la chaine; 255 = signe inexistant) 
		cptm = number_str.indexOf('-'); // recherche du signe - (0 = signe au début de la chaine; 255 = signe inexistant)
		cptf = number_str.indexOf('*'); // recherche du signe * (0 = signe au début de la chaine; 255 = signe inexistant)
		cptd = number_str.indexOf('/'); // recherche du signe / (0 = signe au début de la chaine; 255 = signe inexistant)

		for (int i = 0; i < longueur; i++) { // compte le nombre de fois qu'apparait le signe + et incrémente signe
			if (number_str.charAt(i) == '+') {
				signe++;
			}
		}	
		for (int i = 0; i < longueur; i++) { // compte le nombre de fois qu'apparait le signe - et incrémente signe
			if (number_str.charAt(i) == '-') {
				signe++;
			}
		}	
		for (int i = 0; i < longueur; i++) {	// compte le nombre de fois qu'apparait le signe * et incrémente signe
			if (number_str.charAt(i) == '*') {
				signe++;
			}
		}	
		for (int i = 0; i < longueur; i++) {	// compte le nombre de fois qu'apparait le signe / et incrémente signe
			if (number_str.charAt(i) == '/') {
				signe++;
			}
		}

		Serial.print("Saisie = ");
		Serial.println(number_str);
		Serial.print("signe = ");
		Serial.println(signe);		
		Serial.print("cptp = ");
		Serial.println(cptp);
		Serial.print("cptm = ");
		Serial.println(cptm);
		Serial.print("cptf = ");
		Serial.println(cptf);
		Serial.print("cptd = ");
		Serial.println(cptd);	
		Serial.println();
				
		if(signe >= 2){	// plus de 1 signe trouvé
			myNex.writeStr("t0.txt", "Trop de signes");
		}
			
		else if(cptp == 0){	// signe + trouvé en premier 
			op2 = number_str.substring(1);		// On récupère le nombre après le signe
			fop2 = op2.toFloat();
			number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
			number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
			result = number_mm + fop2;
			number_str = String(result,1);
			myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
			number_mm = result;
		}
			
		else if(cptm == 0){	// signe - trouvé en premier
			op2 = number_str.substring(1);		// On récupère le nombre après le signe
			fop2 = op2.toFloat();
			number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
			number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
			result = number_mm - fop2;
			number_str = String(result,1);
			myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
			number_mm = result;
		}
			
		else if(cptp == 255 and cptm == 255 and cptf == 255 and cptd == 255 ){ // Aucun signe trouvé
			number_mm = number_str.toFloat();  // la convertir en nombre flottant
		}
		
		else if(cptf >=0 or cptd >= 0) {
			signe++;
			myNex.writeStr("t0.txt", "Interdit");				
		}
	}

	else if (number_str == ""){		// Bouton envoie sans saisie de valeur déplace l'axe en fin de course max
		number_mm = course_max + offset_calibration;			
	}
	
	 // puis on part vers le déplacement avec la valeur B
	if ( signe <= 1 )	{
		if(initialisation == true and number_mm >= course_min and (number_mm - offset_calibration) <= course_max) { // accepter que > cour.mini et < course maxi
			nouvelle_position_pas = ((number_mm - offset_calibration)/ distance_tour)*nb_pas_tour; 
			stepper.moveTo(nouvelle_position_pas);	// et l'envoyer au moteur et tourner vers la lame
			lec_arret = false;
			delai_envoi = millis();
			myNex.writeStr("page Move");     // Passer sur la page Move Stop
		}
		else if(number_mm < course_min or (number_mm - offset_calibration) > course_max){
		myNex.writeStr("t0.txt", "Hors course");
		}
	}
}

accelstepper n'est pas un foudre de guerre...

il y a d'autres bibliothèques, par exemple GitHub - gin66/FastAccelStepper: A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3 and Atmel SAM Due et pour un ESP32 ils disent

ESP32

  • allows up to 200 000 generated steps per second
  • supports up to 14 stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
  • Steppers' command queue depth: 32

sinon sur

est-ce que votre driver et moteur sont capables de ces performances ? est-ce que l'alim suit ?

Alors le driver peut aller jusqu'à 51200 en micro pas et j'ai une alimentation 24V 10A juste pour le driver. J'ai ces même moteurs et drivers sur ma CNC 4x2 et ça tourne sans soucis.
La différence c'est que je suis en 24V et non 48V comme sur la CNC, mais le moteur ne bronche pas, surtout que j'ai une accélération assez lente pour ce système.

Dans mon cycle d'init, j'ai une accélération (500000) bien plus grande et ça fonctionne. Par contre je voudrais avoir une rampe bien plus douce pour le fonctionnement normal, c'est là que ça accélère par pallier.

faudrait voir le code et ce que vous faites

Pour la partie IHM je pourrais éventuellement faire une vidéo ou des captures d'écran si besoin. Sur le principe l'IHM sert à déclencher les différents trigger dans le code. L'utilisateur saisie des distances sur l'IHM et lance le mouvement qui déplace le guide de scie.

Voici l'ensemble du programme:

// ESP32 WROOM-DA Module

/*
  Infos importantes pour Nextion
  
  A chaque appel d'une page, les variables de la page sont remisent dans l'état par défaut configuré
 
  Si ton nombre est déclaré comme un float, sa précision est de 6 à 7 chiffres, mais ce ne sont pas 6 à 7 chiffres après la virgule. C'est la précision de la représentation de la valeur stockée en mémoire.

  Si ta valeur est égale à 1, tu pourras avoir entre 0.999999 et 1.000001
  Par contre si tu as le nombre 123456789, tu peux te retrouver avec par exemple 123456888. C'est du moins ce que je comprends de la représentation des float par un arduino.
  
  Si tu veux faire des calculs sur des grands nombres en conservant une précision bien meilleure, il existe une bibliothèque pour ça, elle s'appelle bignumber 7
*/

#include "EasyNextionLibrary.h"  // Include EasyNextionLibrary
#include <Arduino.h>
#include <EEPROM.h>
#include <AccelStepper.h>
#include <stdio.h>
#include <Bounce2.h>

const char version[] = "3.20";		// changer ce numéro pour version ESP32
const char version_Nextion[] = "10-C";		// changer ce numéro pour version_Nextion

EasyNex myNex(Serial2); 

Bounce sw_stop = Bounce();
Bounce sw_init = Bounce();
Bounce sw_fin_course = Bounce();

// bits et variables moteur
const byte pin_DIR = 0;  
const byte pin_STEP = 4; 

float course_min = 0;	
float course_max = 0;	
float distance_tour = 0;	
float nb_pas_tour = 0;	
float petite_vitesse = 0;	
float grande_vitesse = 0;	
float acceleration = 0;	
float compensation_jeu = 0;	
float offset_calibration = 0; 

long nouvelle_position_pas = 0;  // Valeur en pas de la position à atteindre
float quitter_capteur = 5; // distance en mm pour quitter le capteur

// Variables
boolean initialisation = false;	// défini l'état de l'initialisation
boolean bt_init = false; // action sur bouton initialisation du Nextion
boolean lec_arret = false;  // pour éviter de passer continuellement dans une boucle
unsigned long delai_envoi = 0;  // utilisé pour rythme d'envoi des positions à l'écran
static int etape = 1;	// Variable pour les fonctions Switch

// Objet accelstepper pour controller le moteur pas à pas
AccelStepper stepper(1, pin_STEP, pin_DIR);

// bit capteurs inductifs
const byte pin_capteur_1 = 19;
const byte pin_capteur_2 = 18;

// bit Arrêt d'urgence
const byte pin_stop = 21;

// paramètres en EEPROM
const byte adr_t1 = 15; // adresse t1 Course minimum 
const byte adr_t2 = 20; // adresse t2 Course maximum 
const byte adr_t3 = 25; // adresse t3 Distance par tour 
const byte adr_t4 = 30; // adresse t4 Pulses par tour 
const byte adr_t5 = 35; // adresse t5 Petite vitesse  
const byte adr_t6 = 40; // adresse t6 Grande vitesse  
const byte adr_t7 = 45; // adresse t7 Accélération 
const byte adr_t8 = 50; // adresse t8 Compensation du jeu de la vis à billes 
const byte adr_t9 = 55; // adresse t9 Offset Calibration 

// Variables pour les calculs de la page main avec les signes
byte signe = 0;	// Compteur pour interdire les calculs avec plusieurs signes
byte cptp = 0;	// Compteur de signe +
byte cptm = 0;	// Compteur de signe -
byte cptf = 0;	// Compteur de signe *
byte cptd = 0;	// Compteur de signe /
String op1;		// Opérateur 1 en string
String op2;		// Opérateur 2 en string
byte longueur;	// Pour connaitre le nombre de caractère dans la chaine reçu du Nextion
float fop1;		// Opérateur 1 en float
float fop2;		// Opérateur 2 en float
float result;	// Résultat de l'opération de calcul

// Nextion
String number_str;
float number_mm = 0;
float number_A = 0;	// Position actuelle du Nextion
float number_B = 0;	// Nouvelle position calibrée


void setup() {
  
  myNex.begin(115200); 
  Serial.begin(115200);
  
  // configuration autres bits
  pinMode(pin_capteur_1, INPUT_PULLUP); 	// bit du capteur optique
  sw_stop.attach( pin_stop ,  INPUT_PULLUP ); 
  sw_stop.interval(20); // interval in ms
  sw_init.attach( pin_capteur_1 ,  INPUT_PULLUP ); 
  sw_init.interval(20); // interval in ms
  //pinMode(pin_capteur_2, INPUT_PULLUP); 	// bit du capteur optique
  //sw_fin_course.attach( pin_capteur_2 ,  INPUT_PULLUP ); 
  //sw_fin_course.interval(20); // interval in ms

  
 	EEPROM.begin(500);
	delay(100);

	Serial.println();
	Serial.print("Lutcha Version ");
	Serial.println(version);
	Serial.print("Lutcha version_Nextion ");
	Serial.println(version_Nextion);
	Serial.println();

	EEPROM.get(adr_t1,course_min);
	EEPROM.get(adr_t2,course_max);
	EEPROM.get(adr_t3,distance_tour);
	EEPROM.get(adr_t4,nb_pas_tour);
	EEPROM.get(adr_t5,petite_vitesse);
	EEPROM.get(adr_t6,grande_vitesse);
	EEPROM.get(adr_t7,acceleration);
	EEPROM.get(adr_t8,compensation_jeu); 
	EEPROM.get(adr_t9,offset_calibration);

	Serial.print("EEPROM t1 Course minimum en mm = ");
	Serial.println(course_min);
	Serial.print("EEPROM t2 Course maximum en mm = ");
	Serial.println(course_max);
	Serial.print("EEPROM t3 Distance/tour en mm  = ");
	Serial.println(distance_tour);
	Serial.print("EEPROM t4 Pulses par tour  = ");
	Serial.println(nb_pas_tour);
	Serial.print("EEPROM t5 Petite vitesse en pas/sec = ");
	Serial.println(petite_vitesse);
	Serial.print("EEPROM t6 Grande vitesse en pas/sec = ");
	Serial.println(grande_vitesse);
	Serial.print("EEPROM t7 Acceleration en pas/sec = ");
	Serial.println(acceleration);
	Serial.print("EEPROM t8 compensation_jeu en mm = ");
	Serial.println(compensation_jeu);
	Serial.print("EEPROM t9 offset_calibration en mm = ");
	Serial.println(offset_calibration); 

}

void loop() {	
  myNex.NextionListen(); // ne pas rater de trigger
  stepper.run();
  sw_stop.update();
  sw_init.update();	
  
	if(sw_stop.read() == HIGH and initialisation == false and bt_init == true ){	// Cycle d'initialisation
		switch (etape) {
		  
		  case 1:
			stepper.setCurrentPosition(0); // on initialise stepper
			stepper.setMaxSpeed(petite_vitesse);	// petite vitesse pour initialisation
			stepper.setAcceleration(500000);	// on réduit le temps d'accélération (step/s) à son minimum pour le reset
			Serial.println("etape = 1");
			if(digitalRead(pin_capteur_1) == HIGH){
				Serial.println("etape = 2");
				etape = 2;
			}
			if(digitalRead(pin_capteur_1) == LOW){
				Serial.println("etape = 4");
				etape = 4;
				}
			break;
		  case 2:
			stepper.moveTo(((course_max - course_min) + offset_calibration) / distance_tour * nb_pas_tour);	// aller vers la droite en petite vitesse pour accoster capteur			
			if(digitalRead(pin_capteur_1) == LOW){
				Serial.println("etape = 3");
				etape = 3;
			}	
			break;
		  case 3:
			stepper.stop();
			if(stepper.distanceToGo() == 0){
				stepper.setCurrentPosition(0); // on initialise stepper
				Serial.println("etape = 4");
				etape = 4;
			}	
			break;
		  case 4:
			stepper.moveTo(-quitter_capteur / distance_tour * nb_pas_tour);	// quitter le capteur en petite vitesse vers la gauche
			if(stepper.distanceToGo() == 0 and digitalRead(pin_capteur_1) == HIGH){
				Serial.println("etape = 5");
				etape = 5;
			}
			break;
		  case 5:
			stepper.stop();
			if(stepper.distanceToGo() == 0){
				stepper.setCurrentPosition(0); 		// on initialise stepper
				stepper.setMaxSpeed(1000);			// changement de vitesse en step/s pour accoster le capteur au ralenti
				Serial.println("etape = 6");
				etape = 6;
			}				
			break;
		  case 6:
			stepper.moveTo((quitter_capteur + 1) / distance_tour * nb_pas_tour);	// aller vers la droite en vitesse lente pour toucher capteur
			if(digitalRead(pin_capteur_1) == LOW){
				Serial.println("etape = 7");
				etape = 7;
			}
			break;
		  case 7:
			stepper.stop();
			if(stepper.distanceToGo() == 0){ // on vérifie que le moteur est bien arrêté
				Serial.println("etape = 8");
				etape = 8;
			}				
			break;
		  case 8:
			stepper.setCurrentPosition(course_max / distance_tour * nb_pas_tour); // on initialise stepper à la course maximum
			stepper.setMaxSpeed(grande_vitesse);	  // grande vitesse quand on est pas en cours d'initialisation 
			stepper.setAcceleration(acceleration);	// accélération normale 
			myNex.writeStr("init.val=1");  // variable Init à 1 quand le cycle est complet
			myNex.writeStr("page Main");
			number_str = String((course_max + offset_calibration),1);
			myNex.writeStr("t1.txt", number_str); // mettre à jour la zone A Main
			myNex.writeStr("t0.txt", ""); // effacer la zone B Main
			initialisation = true; // Initialisation faite
			Serial.println("etape = 9");
			etape = 1;
			break;			  
		}

	}
  
	if(sw_stop.read() == HIGH and initialisation == true){ // Boucle principale en cours de fonctionnement après initialisation
		switch (etape) {
			case 1:				
				if(stepper.isRunning() and millis() >= delai_envoi + 100){					
					delai_envoi = millis();
					number_mm = (stepper.currentPosition() / nb_pas_tour * distance_tour) + offset_calibration;
					number_str = String(number_mm,1);
					myNex.writeStr("t1.txt", number_str);
				}
				else if(stepper.distanceToGo() == 0 and !lec_arret){
					etape = 2;
				}
				break;
			case 2:			
					myNex.writeStr("page Main");
					myNex.writeStr("t0.txt", "");
					number_mm = (stepper.currentPosition() / nb_pas_tour * distance_tour) + offset_calibration;
					number_str = String(number_mm,1);
					myNex.writeStr("t1.txt", number_str); // mettre à jour la zone A Main
					lec_arret = true;
					etape = 1;
				break;
			
		} 
    }
		
	if(sw_stop.fell()) { // Arrêt d'urgence enclanché
		Serial.println("Stop en position urgence");
		stepper.stop(); // Arrêt du moteur
		initialisation = false; // Empêche le mouvement et attends de refaire une initialisation 
		bt_init = false;
		myNex.writeStr("page Menu");  // Afficher la page Menu
		myNex.writeStr("lock.val=1"); // Verrouille le Nextion
		myNex.writeStr("init.val=0"); // Variable init 
		//myNex.writeStr("q0.picc=2");  // Allume le voyant Mode Manuel
    }

	if(sw_stop.read() == LOW){ // Pour faire clignoter le voyant d'arrêt d'urgence
		delai_envoi = (millis() / 700) %2;
		if(delai_envoi == 1) myNex.writeStr("q0.picc=2");  // Allume le voyant Arrêt d'urgence
		if(delai_envoi == 0) myNex.writeStr("q0.picc=1");  // Eteint le voyant Arrêt d'urgence
	}
	
	if(sw_stop.rose()) { // Bouton arrêt d'urgence est relaché
		Serial.println("Stop remis en route");
		myNex.writeStr("lock.val=0");  // Déverrouille l'interface
		myNex.writeStr("q0.picc=1");  // Etein le voyant Mode Manuel
    }	
} 

void trigger1(){  // Récupération des paramètres machine du Nextion et Calculs
	number_str = myNex.readStr("Settings.t1.txt");
	course_min = number_str.toFloat();
	Serial.println();
	Serial.print("course_min en mm = ");
	Serial.println(course_min);
	
	number_str = myNex.readStr("Settings.t2.txt");
	course_max = number_str.toFloat();
	Serial.print("course_max en mm = ");
	Serial.println(course_max);	
	
	number_str = myNex.readStr("Settings.t3.txt");
	distance_tour = number_str.toFloat();
	Serial.print("distance_tour en mm/tr = ");
	Serial.println(distance_tour);	
	
	number_str = myNex.readStr("Settings.t4.txt");
	nb_pas_tour = number_str.toFloat();
	Serial.print("nb_pas_tour en step/tr = ");
	Serial.println(nb_pas_tour);	
	
	number_str = myNex.readStr("Settings.t5.txt");
	petite_vitesse = number_str.toFloat();
	Serial.print("petite_vitesse en mm/min = ");
	Serial.println(petite_vitesse);	
	
	number_str = myNex.readStr("Settings.t6.txt");
	grande_vitesse = number_str.toFloat();
	Serial.print("grande_vitesse mm/min = ");
	Serial.println(grande_vitesse);	
	
	number_str = myNex.readStr("Settings.t7.txt");
	acceleration = number_str.toFloat();
	Serial.print("acceleration en mm/s² = ");
	Serial.println(acceleration);	
	
	number_str = myNex.readStr("Settings.t8.txt");
	compensation_jeu = number_str.toFloat();
	Serial.print("compensation_jeu en mm = ");
	Serial.println(compensation_jeu);	
	
	number_str = myNex.readStr("Settings.t9.txt");
	offset_calibration = number_str.toFloat();
	Serial.print("offset_calibration en mm = ");
	Serial.println(offset_calibration);
	Serial.println();	
	
	// Calculs sur les paramètres pour avoir la correspondance des unités entre Nextion et Accelstepper	
	petite_vitesse = (petite_vitesse * nb_pas_tour) / ( 60 * distance_tour );
	grande_vitesse = (grande_vitesse * nb_pas_tour) / ( 60 * distance_tour );
	acceleration = (acceleration * nb_pas_tour) / distance_tour;
	Serial.print("petite_vitesse en step/s = ");
	Serial.println(petite_vitesse);		
	Serial.print("grande_vitesse en step/s = ");
	Serial.println(grande_vitesse);		
	Serial.print("acceleration en step/s² = ");
	Serial.println(acceleration);
	Serial.println();	

	// Enregistrer les valeurs en EEPROM
	EEPROM.put(adr_t1, course_min); // enregistrer la valeur en EEPROM de course_min
	EEPROM.commit();	
	EEPROM.put(adr_t2, course_max); 
	EEPROM.commit();
	EEPROM.put(adr_t3, distance_tour); 
	EEPROM.commit();
	EEPROM.put(adr_t4, nb_pas_tour); 
	EEPROM.commit();
	EEPROM.put(adr_t5, petite_vitesse); 
	EEPROM.commit();
	EEPROM.put(adr_t6, grande_vitesse); 
	EEPROM.commit();
	EEPROM.put(adr_t7, acceleration); 
	EEPROM.commit();
	EEPROM.put(adr_t8, compensation_jeu); 
	EEPROM.commit();
	EEPROM.put(adr_t9, offset_calibration); 
	EEPROM.commit();	
	
	// Actualisation des paramètres pour accelstepper pour éviter de rebooter ESP32
	stepper.setMaxSpeed(grande_vitesse);	  // grande vitesse en fonctionnement normal
	stepper.setAcceleration(acceleration);	// accélération normale
}

void trigger2(){  // Page Menu bouton Initialisation enfoncé
	Serial.println("trigger1");
	initialisation = false; // bloquer machine
	bt_init = true; // bouton initialisation enfoncé
	etape = 1;  
}

void trigger3(){  // Page Menu bouton Initialisation relâché, on stoppe tout
	Serial.println("trigger2");
	stepper.stop(); // Arrêt du moteur
	initialisation = false; // bloquer machine
	bt_init = false;	// Bouton initialisation relaché
	etape = 1;
}

void trigger4(){  // Actualisation de la page keyboard Calibration
	number_str = myNex.readStr("Main.t1.txt"); // lire la saisie au clavier de la page Calibration
	number_A = number_str.toFloat();  // la convertir en nombre flottant
	myNex.writeStr("t1.txt", number_str); // mettre à jour la zone A de keyboard Calibration
	myNex.writeStr("t0.txt", ""); // mettre à jour la zone A de keyboard Calibration
	Serial.print("Nombre A = ");
	Serial.println(number_A);
	Serial.print("ancien offset calibration = ");
	Serial.println(offset_calibration);
}

void trigger5(){  // Bouton Valider du clavier de la page Calibration
	number_str = myNex.readStr("KeybdCali.t0.txt"); // lire la saisie au clavier de la page Calibration
	number_B = number_str.toFloat();  // la convertir en nombre flottant
	Serial.print("Nombre B = ");
	Serial.println(number_B);
	
	offset_calibration = offset_calibration + (number_B - number_A);
	// offset_calibration = offset_calibration + (number_B - number_A);
	Serial.print("nouvel offset calibration = ");
	Serial.println(offset_calibration);
	EEPROM.put(adr_t9, offset_calibration); 
	EEPROM.commit();
		
	// Envoie de la commande wepo... pour enregistrer la nouvelle valeur dans offset_calibration
	number_str = String(offset_calibration,1);
	Serial2.print("wepo ");		
	Serial2.print('"');
	Serial2.print(number_str);
	Serial2.print('"');
	Serial2.print(",88");
	Serial2.write(0xff);
	Serial2.write(0xff);
	Serial2.write(0xff);	
	
	// mise à jour de accelstepper avec le nouvel offset
	//stepper.setCurrentPosition((number_A + offset_calibration) / distance_tour * nb_pas_tour);
	Serial.print("stepper.currentPosition = ");
	Serial.println(stepper.currentPosition() / nb_pas_tour * distance_tour);
	
	// mise à jour de la page Main avec le nouvel offset_calibration
	number_str = String(number_B,1);
	myNex.writeStr("Main.t1.txt", number_str);
}

void trigger6(){	// Bouton = de la page Main
	number_str = myNex.readStr("Main.t0.txt"); // lire la zone B de la page Main, cible demandée
	signe = 0;
	cptp = 0;
	cptm = 0;
	cptf = 0;
    cptd = 0;
	longueur = number_str.length();
	cptp = number_str.indexOf('+'); // recherche du signe + (0 = signe au début de la chaine; 255 = signe inexistant)
	cptm = number_str.indexOf('-'); // recherche du signe - (0 = signe au début de la chaine; 255 = signe inexistant)
	cptf = number_str.indexOf('*'); // recherche du signe * (0 = signe au début de la chaine; 255 = signe inexistant)
	cptd = number_str.indexOf('/'); // recherche du signe / (0 = signe au début de la chaine; 255 = signe inexistant)
		
	for (int i = 0; i < longueur; i++) { // compte le nombre de fois qu'apparait le signe + et incrémente signe
		if (number_str.charAt(i) == '+') {
			signe++;
		}
	}	
	for (int i = 0; i < longueur; i++) { // compte le nombre de fois qu'apparait le signe - et incrémente signe
		if (number_str.charAt(i) == '-') {
			signe++;
		}
	}	
	for (int i = 0; i < longueur; i++) {	// compte le nombre de fois qu'apparait le signe * et incrémente signe
		if (number_str.charAt(i) == '*') {
			signe++;
		}
	}	
	for (int i = 0; i < longueur; i++) {	// compte le nombre de fois qu'apparait le signe / et incrémente signe
		if (number_str.charAt(i) == '/') {
			signe++;
		}
	}		

	Serial.print("Saisie = ");
	Serial.println(number_str);
	Serial.print("signe = ");
	Serial.println(signe);		
	Serial.print("cptp = ");
	Serial.println(cptp);
	Serial.print("cptm = ");
	Serial.println(cptm);
	Serial.print("cptf = ");
	Serial.println(cptf);
	Serial.print("cptd = ");
	Serial.println(cptd);	
	Serial.println();	
		
	if(signe >= 2){	// plus de 1 signe trouvé
		myNex.writeStr("t0.txt", "Trop de signes");
	}
	else if(cptp == 0){	// signe + trouvé en premier
		op2 = number_str.substring(1);		// On récupère le nombre après le signe
		fop2 = op2.toFloat();
		number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
		number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
		result = number_mm + fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
	}
	else if(cptm == 0){	// signe - trouvé en premier
		op2 = number_str.substring(1);		// On récupère le nombre après le signe
		fop2 = op2.toFloat();
		number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
		number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
		result = number_mm - fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
	}
	else if(cptf == 0){	// signe * trouvé en premier
		op2 = number_str.substring(1);		// On récupère le nombre après le signe
		fop2 = op2.toFloat();
		number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
		number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
		result = number_mm * fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
	}
	else if(cptd == 0){	// signe / trouvé en premier
		op2 = number_str.substring(1);		// On récupère le nombre après le signe
		fop2 = op2.toFloat();
		number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
		number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
		result = number_mm / fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
	}
    else if(cptp > 0 and cptp < 255) {  // c'est un + trouvé entre deux nombre 
		op1 = number_str.substring(0, cptp);		// On récupère le premier nombre
		op2 = number_str.substring(cptp+1, longueur);		// On récupère le second nombre
		fop1 = op1.toFloat();
		fop2 = op2.toFloat();
		result = fop1 + fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
      
    }
    else if(cptm > 0 and cptm < 255) {  // c'est un - trouvé entre deux nombre 
		op1 = number_str.substring(0, cptm);		// On récupère le premier nombre
		op2 = number_str.substring(cptm+1, longueur);		// On récupère le second nombre
		fop1 = op1.toFloat();
		fop2 = op2.toFloat();
		result = fop1 - fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
      
    }
    else if(cptf > 0 and cptf < 255) {  // c'est un * trouvé entre deux nombre 
		op1 = number_str.substring(0, cptf);		// On récupère le premier nombre
		op2 = number_str.substring(cptf+1, longueur);		// On récupère le second nombre
		fop1 = op1.toFloat();
		fop2 = op2.toFloat();
		result = fop1 * fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
      
    }
    else if(cptd > 0 and cptd < 255) {  // c'est un + trouvé entre deux nombre 
		op1 = number_str.substring(0, cptd);		// On récupère le premier nombre
		op2 = number_str.substring(cptd+1, longueur);		// On récupère le second nombre
		fop1 = op1.toFloat();
		fop2 = op2.toFloat();
		result = fop1 / fop2;
		number_str = String(result,1);
		myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
      
    }			
}

void trigger7(){	// Bouton Départ page Main
	number_str = myNex.readStr("Main.t0.txt"); // lire la zone B de la page Main, cible demandée
	if (number_str != ""){	// Si la zone B n'est pas vide
		signe = 0;
		cptp = 0;
		cptm = 0;
		cptf = 0;
		cptd = 0;
		longueur = number_str.length();		
		cptp = number_str.indexOf('+'); // recherche du signe + (0 = signe au début de la chaine; 255 = signe inexistant) 
		cptm = number_str.indexOf('-'); // recherche du signe - (0 = signe au début de la chaine; 255 = signe inexistant)
		cptf = number_str.indexOf('*'); // recherche du signe * (0 = signe au début de la chaine; 255 = signe inexistant)
		cptd = number_str.indexOf('/'); // recherche du signe / (0 = signe au début de la chaine; 255 = signe inexistant)

		for (int i = 0; i < longueur; i++) { // compte le nombre de fois qu'apparait le signe + et incrémente signe
			if (number_str.charAt(i) == '+') {
				signe++;
			}
		}	
		for (int i = 0; i < longueur; i++) { // compte le nombre de fois qu'apparait le signe - et incrémente signe
			if (number_str.charAt(i) == '-') {
				signe++;
			}
		}	
		for (int i = 0; i < longueur; i++) {	// compte le nombre de fois qu'apparait le signe * et incrémente signe
			if (number_str.charAt(i) == '*') {
				signe++;
			}
		}	
		for (int i = 0; i < longueur; i++) {	// compte le nombre de fois qu'apparait le signe / et incrémente signe
			if (number_str.charAt(i) == '/') {
				signe++;
			}
		}

		Serial.print("Saisie = ");
		Serial.println(number_str);
		Serial.print("signe = ");
		Serial.println(signe);		
		Serial.print("cptp = ");
		Serial.println(cptp);
		Serial.print("cptm = ");
		Serial.println(cptm);
		Serial.print("cptf = ");
		Serial.println(cptf);
		Serial.print("cptd = ");
		Serial.println(cptd);	
		Serial.println();
				
		if(signe >= 2){	// plus de 1 signe trouvé
			myNex.writeStr("t0.txt", "Trop de signes");
		}
			
		else if(cptp == 0){	// signe + trouvé en premier 
			op2 = number_str.substring(1);		// On récupère le nombre après le signe
			fop2 = op2.toFloat();
			number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
			number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
			result = number_mm + fop2;
			number_str = String(result,1);
			myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
			number_mm = result;
		}
			
		else if(cptm == 0){	// signe - trouvé en premier
			op2 = number_str.substring(1);		// On récupère le nombre après le signe
			fop2 = op2.toFloat();
			number_str = myNex.readStr("Main.t1.txt"); // lire la zone A de la page Main
			number_mm = number_str.toFloat();  // convertir la zone A en nombre flottant
			result = number_mm - fop2;
			number_str = String(result,1);
			myNex.writeStr("t0.txt", number_str); // mettre à jour la zone B Main
			number_mm = result;
		}
			
		else if(cptp == 255 and cptm == 255 and cptf == 255 and cptd == 255 ){ // Aucun signe trouvé
			number_mm = number_str.toFloat();  // la convertir en nombre flottant
		}
		
		else if(cptf >=0 or cptd >= 0) {
			signe++;
			myNex.writeStr("t0.txt", "Interdit");				
		}
	}

	else if (number_str == ""){		// Bouton envoie sans saisie de valeur déplace l'axe en fin de course max
		number_mm = course_max + offset_calibration;			
	}
	
	 // puis on part vers le déplacement avec la valeur B
	if ( signe <= 1 )	{
		if(initialisation == true and number_mm >= course_min and (number_mm - offset_calibration) <= course_max) { // accepter que > cour.mini et < course maxi
			nouvelle_position_pas = ((number_mm - offset_calibration)/ distance_tour)*nb_pas_tour; 
			stepper.moveTo(nouvelle_position_pas);	// et l'envoyer au moteur et tourner vers la lame
			lec_arret = false;
			delai_envoi = millis();
			myNex.writeStr("page Move");     // Passer sur la page Move Stop
		}
		else if(number_mm < course_min or (number_mm - offset_calibration) > course_max){
		myNex.writeStr("t0.txt", "Hors course");
		}
	}
}

void trigger8(){  // Bouton Stop page Move
		stepper.stop(); // Arrêt du moteur
		lec_arret = false;  // pour autoriser affichage à l'arrivée
}

j'ai jeté un coup d'oeil rapide, rien ne saute aux yeux si ce n'est la mise à jour toutes les 100ms de l'écran qui peut ralentir éventuellement le code et empêcher stepper.run(); d'être appelé assez souvent - ce qui conduirait au mouvement saccadé

avez vous testé les capacités du moteur sans tout ce code autour et sans rien faire sur l'écran ?

PS= il faut faire une soustraction quand on joue avec millis, pas des addictions, pour que ça se passe bien quand millis retombe à 0

➜ écrire

        if (stepper.isRunning() and millis() - delai_envoi >=  100) {

Non je n'ai pas tester le moteur en amont, car le code a été écrit avant que le matériel arrive et soit assemblé.
Je note pour millis, merci.

ce serait bien de faire le test sans "parler" à l'écran pour voir ce dont est capable le moteur

1 Like

Oui je vais essayer de faire un bout de programme pour faire ça.

postez sur youTube et mettez le lien youTube ici - nous somme nombreux à ne pas suivre les liens google drive et autres

lien YouTube

merci pour la vidéo

que doit on remarquer ?

La rampe d'accélération et décélération qui n'est pas linéaire mais qui accélère par pallier successifs avant d'atteindre la vitesse plateau. On entends bien le son du moteur qui accélère brusquement.

avec accelstepper les rampes d'accélération et décélération sont dictées par la position à atteindre et par la valeur de l'accélération donnée et la fréquence à laquelle vous appelez run()

quels sont les paramètres que vous avez pour le mouvement que l'on voit ?

@vileroi a une bibliothèque différente ou vous pouvez aussi regarder mobatools

J'ai fait un bout de programme avec seulement un déplacement et rien d'autre et le résultat est le même.

void loop() {	
  stepper.run();
  sw_stop.update();
  sw_init.update();	
  
	if(sw_stop.read() == HIGH and sw_init.read() == LOW){
	
		switch (etape) {
	
		case 1:
			stepper.moveTo(160000);
			if (stepper.distanceToGo() == 0){
			stepper.setCurrentPosition(0);
			etape = 2;
			}
			break;
			
		
		case 2:	
			stepper.moveTo(-160000);
			if (stepper.distanceToGo() == 0){
			stepper.setCurrentPosition(0);
			etape = 1;
			}
			break;	  		  
			
	  
	  
		}
	}
}

Mon driver moteur en micro pas est 3200 step/tr.

Mon driver moteur en micro pas est 400 step/tr.

vous pouvez poster tout le code ?

Lequel vous voulez ? Le complet de mon application ou le petit bout que j'ai fait pour tester ?

celui du test il manque le setup et quelques éléments

j'ai une théorie que je voudrais confirmer


#include <Arduino.h>
#include <EEPROM.h>
#include <AccelStepper.h>
#include <stdio.h>
#include <Bounce2.h>



//EasyNex myNex(Serial2); 

Bounce sw_stop = Bounce();
Bounce sw_init = Bounce();
Bounce sw_fin_course = Bounce();

// bits et variables moteur
const byte pin_DIR = 0;  
const byte pin_STEP = 4; 

float course_min = 0;	
float course_max = 0;	
float distance_tour = 0;	
float nb_pas_tour = 0;	
float petite_vitesse = 0;	
float grande_vitesse = 0;	
float acceleration = 0;	
float compensation_jeu = 0;	
float offset_calibration = 0; 

long nouvelle_position_pas = 0;  // Valeur en pas de la position à atteindre
float quitter_capteur = 5; // distance en mm pour quitter le capteur

// Variables
boolean initialisation = false;	// défini l'état de l'initialisation
boolean bt_init = false; // action sur bouton initialisation du Nextion
boolean lec_arret = false;  // pour éviter de passer continuellement dans une boucle
unsigned long delai_envoi = 0;  // utilisé pour rythme d'envoi des positions à l'écran
static int etape = 1;	// Variable pour les fonctions Switch

// Objet accelstepper pour controller le moteur pas à pas
AccelStepper stepper(1, pin_STEP, pin_DIR);

// bit capteurs inductifs
const byte pin_capteur_1 = 19;
const byte pin_capteur_2 = 18;

// bit Arrêt d'urgence
const byte pin_stop = 21;

// paramètres en EEPROM
const byte adr_t1 = 15; // adresse t1 Course minimum 
const byte adr_t2 = 20; // adresse t2 Course maximum 
const byte adr_t3 = 25; // adresse t3 Distance par tour 
const byte adr_t4 = 30; // adresse t4 Pulses par tour 
const byte adr_t5 = 35; // adresse t5 Petite vitesse  
const byte adr_t6 = 40; // adresse t6 Grande vitesse  
const byte adr_t7 = 45; // adresse t7 Accélération 
const byte adr_t8 = 50; // adresse t8 Compensation du jeu de la vis à billes 
const byte adr_t9 = 55; // adresse t9 Offset Calibration 

// Variables pour les calculs de la page main avec les signes
byte signe = 0;	// Compteur pour interdire les calculs avec plusieurs signes
byte cptp = 0;	// Compteur de signe +
byte cptm = 0;	// Compteur de signe -
byte cptf = 0;	// Compteur de signe *
byte cptd = 0;	// Compteur de signe /
String op1;		// Opérateur 1 en string
String op2;		// Opérateur 2 en string
byte longueur;	// Pour connaitre le nombre de caractère dans la chaine reçu du Nextion
float fop1;		// Opérateur 1 en float
float fop2;		// Opérateur 2 en float
float result;	// Résultat de l'opération de calcul

// Nextion
String number_str;
float number_mm = 0;
float number_A = 0;	// Position actuelle du Nextion
float number_B = 0;	// Nouvelle position calibrée


void setup() {
  
  //myNex.begin(115200); 
  Serial.begin(115200);
  
  // configuration autres bits
  pinMode(pin_capteur_1, INPUT_PULLUP); 	// bit du capteur optique
  sw_stop.attach( pin_stop ,  INPUT_PULLUP ); 
  sw_stop.interval(20); // interval in ms
  sw_init.attach( pin_capteur_1 ,  INPUT_PULLUP ); 
  sw_init.interval(20); // interval in ms
  //pinMode(pin_capteur_2, INPUT_PULLUP); 	// bit du capteur optique
  //sw_fin_course.attach( pin_capteur_2 ,  INPUT_PULLUP ); 
  //sw_fin_course.interval(20); // interval in ms

  
 	EEPROM.begin(500);
	delay(100);

	/*Serial.println();
	Serial.print("Lutcha Version ");
	Serial.println(version);
	Serial.print("Lutcha version_Nextion ");
	Serial.println(version_Nextion);
	Serial.println();*/

	EEPROM.get(adr_t1,course_min);
	EEPROM.get(adr_t2,course_max);
	EEPROM.get(adr_t3,distance_tour);
	EEPROM.get(adr_t4,nb_pas_tour);
	EEPROM.get(adr_t5,petite_vitesse);
	EEPROM.get(adr_t6,grande_vitesse);
	EEPROM.get(adr_t7,acceleration);
	EEPROM.get(adr_t8,compensation_jeu); 
	EEPROM.get(adr_t9,offset_calibration);

	Serial.print("EEPROM t1 Course minimum en mm = ");
	Serial.println(course_min);
	Serial.print("EEPROM t2 Course maximum en mm = ");
	Serial.println(course_max);
	Serial.print("EEPROM t3 Distance/tour en mm  = ");
	Serial.println(distance_tour);
	Serial.print("EEPROM t4 Pulses par tour  = ");
	Serial.println(nb_pas_tour);
	Serial.print("EEPROM t5 Petite vitesse en pas/sec = ");
	Serial.println(petite_vitesse);
	Serial.print("EEPROM t6 Grande vitesse en pas/sec = ");
	Serial.println(grande_vitesse);
	Serial.print("EEPROM t7 Acceleration en pas/sec = ");
	Serial.println(acceleration);
	Serial.print("EEPROM t8 compensation_jeu en mm = ");
	Serial.println(compensation_jeu);
	Serial.print("EEPROM t9 offset_calibration en mm = ");
	Serial.println(offset_calibration); 

stepper.setMaxSpeed(grande_vitesse);
stepper.setAcceleration(acceleration);
stepper.setCurrentPosition(0);

}

void loop() {	
  stepper.run();
  sw_stop.update();
  sw_init.update();	
  
	if(sw_stop.read() == HIGH and sw_init.read() == LOW){
	
		switch (etape) {
	
		case 1:
			stepper.moveTo(160000);
			if (stepper.distanceToGo() == 0){
			stepper.setCurrentPosition(0);
			etape = 2;
			}
			break;
			
		
		case 2:	
			stepper.moveTo(-160000);
			if (stepper.distanceToGo() == 0){
			stepper.setCurrentPosition(0);
			etape = 1;
			}
			break;	  		  
			
	  
	  
		}
	}
}	



merci

est-ce que vous rentrez toujours dans ce test dans chaque loop?

si oui vous appelez à chaque tour de loop stepper.moveTo() ce qui a pour effet de recalculer la vitesse pour le prochain pas. je serai tenté d'essayer avec un code simple qui ne met la destination qu'une seule fois et qui n'y touche plus pour tester

Attention j'ai viré le test des boutons donc utilisez des valeurs compatibles avec le montage.

#include <AccelStepper.h>

const byte pin_DIR = 0;
const byte pin_STEP = 4;
AccelStepper stepper(1, pin_STEP, pin_DIR);

long destination = 10000;   // <=== mettez la valeur compatible avec votre montage physique 

void setup() {
  Serial.begin(115200);
  stepper.setMaxSpeed(5000);    // <=== mettez la valeur que vous avez en EEPROM
  stepper.setAcceleration(500); // <=== mettez la valeur que vous avez en EEPROM
  stepper.setCurrentPosition(0);
  stepper.moveTo(destination);
}

void loop() {
  stepper.run();
  if (stepper.distanceToGo() == 0) {
    destination = -destination;
    stepper.moveTo(destination);
  }
}