Moteur PaP fonction step bloque les actions suivantes

Bonjour,

je voudrai faire tourner un moteur Pap et un servo en même temp.

je n’arrive pas a faire tourner mon moteur Pap et faire les actions suivantes en même temp…
la fonction “step” est bloquante comme j’ai pu lire sur different sites.

#include <Stepper.h>
#include <Servo.h>
Servo servo_verseur;  // servo verseur
int pos = 0;    // la position 0 du servo
// 32 pas par tour, reducteur de 1/64... Donc 32*64 pas pour 1 tour.
int NbPas = 2048;
//moteur de 200 pas par tour
Stepper moteur(NbPas, 9, 11, 10, 6); // moteur PaP IN1=6 IN2=9 IN3=10 IN4=11

void setup()
{
  moteur.setSpeed(12); 
  servo_verseur.attach(3);  // servo sur la broche 3
  servo_verseur.write(pos);
}

void loop()
{
  //Faire un tour = 2048 pas dans le sens 1
  moteur.step(2048);
  delay(2000);
 //Faire un tour = 2048 pas dans le sens 2
  moteur.step(-2048);
  delay(2000);

// servo verseur premier mouvement

    for (pos = 0; pos <= 90; pos += 1) { // goes from 0 degrees to 180 degrees // in steps of 1 degree
        servo_verseur.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15); // VITESSE DE ROTATION DU SERVO
}  
// temps pour verser
         delay(2000);
                    
 // servo verseur deuxieme mouvement 
        for (pos = 90; pos >= 0; pos -= 1) { // goes from 0 degrees to 180 degrees // in steps of 1 degree
        servo_verseur.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);   // VITESSE DE ROTATION DU SERVO  

             
}
delay(500);
}

Avez vous un autre moyen de faire ?

Merci d’avance et bonne journée.

Bonjour

Poster votre code....

Il faut peut être envisager d'envoyer les ordres step par step

@+

J’avais oublié de mettre de code, je viens de modifier le post, merci.

Il faut deja supprimé tous les delay de votre code

regarder la page sur les millis() et Blink Without delay.

et je ne vois pas d'autre actions dans votre code a part faire tourner les moteurs...

@+

j’ai modifié le code.
Lorsque le moteur Pap a fini le nombre de tour demandé, le servo se met a fonctionner, j’aimerai que le moteur Pap tourne jusqu’a ce que je lui dise stop (ou nb de tour dans “moteur.step(2048);”),et que le servo puisse fonctionner pendant que le moteur Pap tourne.
j’espère avoir été plus claire…

#include <Stepper.h>
#include <Servo.h>
Servo servo_verseur;  // servo verseur
int pos = 0;    // variable to store the servo position
// 32 pas par tour, reducteur de 1/64... Donc 32*64 pas pour 1 tour.
int NbPas = 2048;
//moteur de 200 pas par tour
Stepper moteur(NbPas, 9, 11, 10, 6); // moteur PaP IN1=6 IN2=9 IN3=10 IN4=11

void setup()
{
  moteur.setSpeed(12); 
  servo_verseur.attach(3);  // servo sur la broche 3
  servo_verseur.write(pos);
}

void loop()
{
  //Faire un tour = 2048 pas dans le sens 1
  moteur.step(2048);
  // servo verseur premier mouvement
  for (pos = 0; pos <= 90; pos += 1) { // goes from 0 degrees to 90 degrees // in steps of 1 degree
        servo_verseur.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15); // VITESSE DE ROTATION DU SERVO
}  
// temps pour verser
         delay(2000);                   
 // servo verseur deuxieme mouvement 
        for (pos = 90; pos >= 0; pos -= 1) { // goes from 0 degrees to 180 degrees // in steps of 1 degree
        servo_verseur.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);   // VITESSE DE ROTATION DU SERVO              
}
}

comme j’ai dit en #3 il faut enlever les delay du code.

changer également les for qui sont bloquant aussi et mettre des conditions if

je ferait plutôt un :

if (compteurStepMoteur < ValeurStepCompteurVoulu)
{
  avancerd'UnStep++;

}

@+

Quand j'enlève ces delay le servo va trop vite et j'ai rien compris a ta condition IF.

les for sont pour les mouvement du servo. désolé je suis débutant....

J’ai changer les for par des if.
Mon servo va trop vite dans son mouvement et ne sais pas comment le ralentir.
Je ne comprends pas le problème avec “delay” et je n’arrive pas a remplacer par “millis”, ça ne marche pas et je ne comprends pas comment donner le temps souhaité (je n’ai rien compris dans les deux lien que tu m’as donné).

#include <Stepper.h>
#include <Servo.h>
Servo servo_verseur;  // servo verseur
int pos = 0;    // variable to store the servo position
// 32 pas par tour, reducteur de 1/64... Donc 32*64 pas pour 1 tour.
int NbPas = 2048;
//moteur de 200 pas par tour
Stepper moteur(NbPas, 9, 11, 10, 6); // moteur PaP IN1=6 IN2=9 IN3=10 IN4=11

void setup()
{
  moteur.setSpeed(18); 
  servo_verseur.attach(3);  // servo sur la broche 3
  servo_verseur.write(pos);
}
void loop()
{
  //Faire un tour = 2048 pas dans le sens 1
  moteur.step(2048);
  // servo verseur premier mouvement
  if (pos = 0; pos <= 90) { 
        pos = 90;
        }
        servo_verseur.write(pos);   
// temps pour verser
         delay(2000);        
  if (pos = 90; pos >= 0)
  { 
    pos = 0;
        }
        servo_verseur.write(pos);              
        
}

dafite:
je n'ai rien compris dans les deux lien que tu m'as donné.

Ouch, ça se présente mal...
Pour ce que tu veux faire, il est indispensable d'assimiler parfaitement ces deux articles...
Désolé, mais sinon tu vas passer ta vie à faire des copier/coller de bouts de code sans comprendre, et ça, ça ne marche pas très souvent.

Avec des exemples, je comprendrai peut être mieux, j'ai beau en chercher...
premier lien:
millis() donne le temps d'exécution du programme depuis son lancement = ok, je ne vois pas en quoi ça m'aide...
les delay sont une pause dans le programme si j'ai bien compris (teubé de newbie)
deuxième lien:
sur le clignotement sans delay= ok, je ne vois toujours pas en quoi ça m'aide a faire ce que je souhaite (par manque de connaissance, je sais)
Je viens sur ce forum pour avoir de l'aide dans ma compréhension et pour pouvoir faire mon code...
merci a vous.

En fait la bibliothèque stepper est bloquante. -> passe pas
J'en ai une qui ne l'est pas mais qui ne gère pas les moteurs unipolaire. -> passe pas (ou il faut que je la modifie!)
Accel stepper n'est pas bloquante, mais demande un programme qui ne l'est pas non plus. -> passe pas
Je crois que StepperDriver n'accepte pas non pus les moteurs unipolaires.


Pour faire travailler ensemble le moteur et le servo, il faudrait faire un programme non bloquant pour le serve et pour le pas à pas. Cela ressemble à:

Boucle loop()
   - si c'est l'heure d'avancer d'un pas, j'avance d'un pas
   - si c'est l'heure de faire tourner le moteur, je le fais tourner d'un degré
   - je calcule le reste mais pas trop longtemps.

Cela nécessite de savoir utiliser millis() comme le fait remarquer @biggil . Remarque, un jour il faudra bien passer par là!


Sinon en calculant bien, si par exemple le moteur doit avancer de 200 pas pendant que le servo doit avancer de 90°
et si pendant ce temps on n'a rien à faire d'autre, on peut faire quelque chose comme:

Pour compteur de 0 à 200*90;
   - si compteur est divisible par 90, j'avance d'un pas
   - si compteur est divisible par 200, j'avance d'un degré
   - j'attends (delay) le temps total que dure le mouvement / 200*90

On peut aussi diviser par 10, ce n'est pas plus clair:

Pour compteur de 0 à 20*9;
   - si compteur est divisible par 9, j'avance d'un pas
   - si compteur est divisible par 20, j'avance d'un degré
   - j'attends (delay) le temps total que dure le mouvement / 20*9

C'est ce que préconisait @J4l13n ("Il faut peut être envisager d'envoyer les ordres step par step")


millis() donne le temps d'exécution du programme depuis son lancement = ok, je ne vois pas en quoi ça m'aide...

Millis c'est ta montre. C'est elle qui dit: il s'est écoulé plus de 20 jours depuis le dernier ciné, je vais donc y aller immédiatement

Merci Vileroi, je comprends mieux les commentaires precedents.
je vais essayé de trouver d'autres exemples pour savoir comment utiliser millis() car avec "blink without delay" je n'arrive pas a saisir...
merci a vous

Vous me comprendrez peut être mieux avec mon code au complet et mes annotations, a la base j’avais mis un moteur type 130 mais pas assez de couple…

#include <Stepper.h>
#include <Servo.h>
int NbPas = 2048; // 32 pas par tour, reducteur de 1/64... Donc 32*64 pas pour 1 tour.
int etatBouton;
Stepper moteur(NbPas, 9, 11, 10, 6); // Moteur pas a pas, 6=IN1, 9=IN2, 10=IN3, 11=IN4
Servo servo_verseur;  // servo verseur en broche 8
int pos = 0;    // enregistre la postition 0 du servo
Servo servo_eau;  // servo deplacement de l'arrivée d'eau en broche 7
int pos1 = 0;    // enregistre la postition 0 du servo
Servo servo_ricard;  // servo deplacement de l'arrivée de ricard en broche 2
int pos2 = 0;    // enregistre la postition 0 du servo
const int bouton = 4; // bouton en pin 4
const int led = 13; // led en broche 13
const int pompe_ricard = 5;
const int pompe_eau = 3;


void setup() {

  pinMode(bouton, INPUT); // le bouton est une entrée
  moteur.setSpeed(12); ; // vitesse du moteur max 18
  pinMode(led, OUTPUT); 
  servo_verseur.attach(8);  
  servo_eau.attach(7);  
  servo_ricard.attach(2);  
}

void loop() {
  
    etatBouton = digitalRead(bouton); // lecture de l'etat du bouton

  if(etatBouton == HIGH) // test si le bouton a un niveau logique HAUT
 {

    digitalWrite(led, HIGH); // eteind la led
    moteur.step(0); // le moteur pas a pas ne tourne pas
    servo_verseur.write(pos);     // enregistre la postition 0 du servo
    servo_eau.write(pos1);     // enregistre la postition 0 du servo
    servo_ricard.write(pos2);     // enregistre la postition 0 du servo  
    digitalWrite(pompe_ricard, LOW); //le bouton est relâché, la pmpoe a ricard reste éteinte
    digitalWrite(pompe_eau, LOW); //le bouton est relâché, la pmpoe a eau reste éteinte
}

else  // test si le bouton a un niveau logique différent de HAUT (donc BAS)
   {

// led de fonctionnement
   
        digitalWrite(led, LOW);
 
 // moteur  DEMMARAGE
    //Faire x tour = 2048 pas dans le sens 1 // pour l'autre sens mettre - devant le nb de pas
      
        moteur.step(4096);
        delay(2000);        
// servo Ricard premier mouvement  

        for (pos2 = 0; pos2 <= 90; pos2 += 1){  // goes from 0 degrees to 180 degrees // in steps of 1 degree
        servo_ricard.write(pos2);              // tell servo to go to position in variable 'pos'
        delay(15); // VITESSE DE ROTATION DU SERVO
        
        
  }
 delay(1000);
// mise en route et arret de la pompe a ricard

        digitalWrite(pompe_ricard, HIGH); //le bouton est relâché, la LED est allumée
        delay(2000); // quantité eau dans le verre (temps en MS)
        digitalWrite(pompe_ricard, LOW); //la LED est etinte

        delay(1000);
        
 
// servo Ricard deuxieme mouvement vers le coté 
        for (pos2 = 90; pos2 >= 0; pos2 -= 1) { 
        servo_ricard.write(pos2);              
        delay(15);          
}        

// servo eau premier mouvement vers betonniere 

        for (pos1 = 0; pos1 <= 90; pos1 += 1) { 
        servo_eau.write(pos1);              
        delay(15); // VITESSE DE ROTATION DU SERVO
     
} 
// mise en route et arret de la pompe a eau

        digitalWrite(pompe_eau, HIGH); 
        delay(3000); // quantité d'eau dans le verre (temps en MS de fonctionnement de la pompe)
        digitalWrite(pompe_eau, LOW); //la LED est etinte
        
        delay(1000);

// servo eau deuxieme mouvement vers le coté 

        for (pos1 = 90; pos1 >= 0; pos1 -= 1) { 
        servo_eau.write(pos1);             
        delay(15);   // VITESSE DE ROTATION DU SERVO
}  

 
// servo verseur premier mouvement

    for (pos = 0; pos <= 90; pos += 1) { 
        servo_verseur.write(pos);              
        delay(15); // VITESSE DE ROTATION DU SERVO
}  
// temps pour vider le melange
         delay(2000);
         
// ARRET DU MOTEUR
                
// servo verseur deuxieme mouvement 
        for (pos = 90; pos >= 0; pos -= 1) { 
        servo_verseur.write(pos);              
        delay(15);   // VITESSE DE ROTATION DU SERVO                    
}
}
}

Quel est la carte utilisée? Uno? Nano?

En résumé le problème est comment faire tourner un moteur pas à pas avec un servo chacun avec une vitesse choisie. Non?

En fait, je ne vois pas du tout ce que je ferais si j'avais ce problème, sauf adapter ma bibliothèque pour ce type de cas. Il faudra donc que je le fasse un jour...

Je ne sais pas utiliser les servos (je n'en ai pas encore eu besoin). Mais mon dada actuel c'est les moteurs pas à pas. Mais même avec ce que je sais (et millis() ne me pose pas de problèmes de base), j'aurais beaucoup de mal à utiliser millis() pour faire avancer un pas à pas avec à côté un code bloquant.
Je me demande si la bonne solution ne serai pas que j'adapte avec un peu de bric et de broc, la bibliothèque que j'utilise pour mes pas à pas. La fonction n'est alors pas bloquante et peut être exécutée avec un code bloquant en même temps.

La seule autre solution que je vois est la 2ème méthode de mon post #10 et n'utiliserait alors que des moteur.step(1); ou moteur.step(-1); . Faire alors une fonction avance(nbPas, angle_depart, angle_arrivee); qui permettrait de faire marcher les deux en même temps.


Ce que je conseille, c'est de laisser dans un premier temps de côté le programme général, et de faire un programme le plus petit qui fasse la partie qui pose problème. Par exemple trouver ce qui manque pour que

avance(uint16_t nbPas, uint8_t angle_depart, uint8_t angle_arrivee)
{
}

loop()
{
 avance(2048/4, 0, 90);
 delay(2000);
 avance(-2048/4, 90, 0);
 delay(2000);
}

fasse tourner le pas à pas et le servo d'un quart de tour, attendre 2s et retour.

dafite:
sur le clignotement sans delay= ok, je ne vois toujours pas en quoi ça m'aide a faire ce que je souhaite (par manque de connaissance, je sais)

Tu n'as pas un problème de manque de connaissance, mais un manque de réflexion.
Cet exemple te met devant les yeux exactement ce dont tu as besoin.
Mais ... tu ne sais pas bien toi même ce dont tu as besoin (tu n'y a pas assez pensé).
Donc tu ne vois pas l'intérêt dans cet exemple. Pourtant tout est là.

vileroi:
Quel est la carte utilisée? Uno? Nano?

En résumé le problème est comment faire tourner un moteur pas à pas avec un servo chacun avec une vitesse choisie. Non?

@vileroi
#1 Clone Nano V3
#2 exatement

biggil:
Tu n’as pas un problème de manque de connaissance, mais un manque de réflexion.
Cet exemple te met devant les yeux exactement ce dont tu as besoin.
Mais … tu ne sais pas bien toi même ce dont tu as besoin (tu n’y a pas assez pensé).
Donc tu ne vois pas l’intérêt dans cet exemple. Pourtant tout est là.

@biggil j’ai mieux compris ton com avec l’explication de vileroi dans son com #10.

Dans cette page Blink Without delay, en fait ce n’est pas assez concret pour ma compréhension et réflexion et l’adapter dans mon code, j’ai trouvé ce lien que je n’ai pas encore lu (juste survolé) pour essayer mieux comprendre car il y a un peu plus d’exemples avec plus de codes sur cette fonction et en faisant des test je comprendrai peut être mieux pour élargir ma réflexion.

Avec vos commentaires, j’ai compris qu’il faut que je fasse mon code en “petits pas” en combinant tous les éléments.
mais il y a beaucoup d’éléments… et pour le moment je ne vois pas, mais je lâcherai pas.

je met mon code complet, attention @biggil mon code va te faire hérisser les poils, je vais le modifier au fur et a mesure de ma compréhension/reflexion, cela fait que 3 semaines que je tripote l’arduino et l’electronique.

#include <Stepper.h>
//Faire x tour = 2048 pas dans le sens 1 // pour l'autre sens mettre - devant le nb de pas
#include <Servo.h>
int NbPas = 2048; // 32 pas par tour, reducteur de 1/64... Donc 32*64 pas pour 1 tour.
int etatBouton_demarrage;
int etatBouton_nettoyage;
Stepper moteur(NbPas, 9, 11, 10, 6); // Moteur pas a pas, 6=IN1, 9=IN2, 10=IN3, 11=IN4
Servo servo_verseur;  // servo verseur en broche 8
int pos = 0;    // enregistre la postition 0 du servo
Servo servo_eau;  // servo deplacement de l'arrivée d'eau en broche 7
int pos1 = 0;    // enregistre la postition 0 du servo
Servo servo_ricard;  // servo deplacement de l'arrivée de ricard en broche 2
int pos2 = 0;    // enregistre la postition 0 du servo
const int bouton_demarrage = 4; // bouton demarage en pin 4
const int bouton_nettoyage = 12; // bouton nettoyage en pin 12
const int led = 13; // led en broche 13
const int pompe_ricard = 5;
const int pompe_eau = 3;


void setup() {
  
  pinMode(bouton_demarrage, INPUT_PULLUP); // le bouton de demarrage est une entrée
  pinMode(bouton_nettoyage, INPUT_PULLUP); // le bouton de nettoyage est une entrée
  moteur.setSpeed(12);  // vitesse du moteur max 18
  pinMode(led, OUTPUT); 
  servo_verseur.attach(8);  
  servo_eau.attach(7);  
  servo_ricard.attach(2);  
}

void loop() {
  
    etatBouton_demarrage = digitalRead(bouton_demarrage); // lecture de l'etat du bouton de demarrage
    etatBouton_nettoyage = digitalRead(bouton_nettoyage); // lecture de l'etat du bouton de nettoyage

    if(etatBouton_nettoyage == HIGH) // test si le bouton a un niveau logique HAUT
 {

    digitalWrite(led, HIGH); // eteind la led
    moteur.step(0); // le moteur pas a pas ne tourne pas
    servo_verseur.write(pos);     // enregistre la postition 0 du servo
    servo_eau.write(pos1);     // enregistre la postition 0 du servo
    servo_ricard.write(pos2);     // enregistre la postition 0 du servo  
    digitalWrite(pompe_ricard, LOW); //le bouton est relâché, la pmpoe a ricard reste éteinte
    digitalWrite(pompe_eau, LOW); //le bouton est relâché, la pmpoe a eau reste éteinte
 } 
    else  // test si le bouton a un niveau logique différent de HAUT (donc BAS)
   {

// led de fonctionnement
   
    digitalWrite(led, LOW);
 
   // servo eau premier mouvement vers betonniere 

    for (pos1 = 0; pos1 <= 90; pos1 += 1) { 
    servo_eau.write(pos1);              
    delay(15); // VITESSE DE ROTATION DU SERVO
     
} 
// mise en route et arret de la pompe a eau

    digitalWrite(pompe_eau, HIGH); 
    delay(3000); // quantité d'eau dans le verre (temps en MS de fonctionnement de la pompe)
    digitalWrite(pompe_eau, LOW); //la pompe a eau est éteinte
        
    delay(1000); //delai entre les deux actions pour les eventuelles goutes
    
// moteur  demarrage et arret
      
    moteur.step(4096);
    delay(2000); 
    
// servo eau deuxieme mouvement vers le coté 

    for (pos1 = 90; pos1 >= 0; pos1 -= 1) { 
    servo_eau.write(pos1);             
    delay(15);   // VITESSE DE ROTATION DU SERVO            
  }
    }
    if(etatBouton_demarrage == HIGH) // test si le bouton a un niveau logique HAUT
 {

    digitalWrite(led, HIGH); // eteind la led
    moteur.step(0); // le moteur pas a pas ne tourne pas
    servo_verseur.write(pos);     // enregistre la postition 0 du servo
    servo_eau.write(pos1);     // enregistre la postition 0 du servo
    servo_ricard.write(pos2);     // enregistre la postition 0 du servo  
    digitalWrite(pompe_ricard, LOW); //le bouton est relâché, la pmpoe a ricard reste éteinte
    digitalWrite(pompe_eau, LOW); //le bouton est relâché, la pmpoe a eau reste éteinte
}

    else  // test si le bouton a un niveau logique différent de HAUT (donc BAS)
   {

// led de fonctionnement
   
    digitalWrite(led, LOW);
 
 // moteur  DEMMARAGE 
 // le PB c'est que le moteur fait sont action et passe ensuite a la suivante pas comme la led qui reste allumée jusqu'a la fin de la boucle
      
    moteur.step(4096);
    delay(2000); 
           
// servo Ricard premier mouvement  

    for (pos2 = 0; pos2 <= 90; pos2 += 1){  
    servo_ricard.write(pos2);              
    delay(15); // VITESSE DE ROTATION DU SERVO      
  }
  
    delay(1000);
// mise en route et arret de la pompe a ricard

    digitalWrite(pompe_ricard, HIGH); //le bouton est relâché, la LED est allumée
    delay(2000); // quantité eau dans le verre (temps en MS)
    digitalWrite(pompe_ricard, LOW); //la pompe a ricard est éteinte

    delay(1000); // delai entre les deux actions pour les eventuelles goutes
        
 
// servo Ricard deuxieme mouvement vers le coté 
    for (pos2 = 90; pos2 >= 0; pos2 -= 1) { 
    servo_ricard.write(pos2);              
    delay(15);          
}        

// servo eau premier mouvement vers betonniere 

    for (pos1 = 0; pos1 <= 90; pos1 += 1) { 
    servo_eau.write(pos1);              
    delay(15); // VITESSE DE ROTATION DU SERVO
     
} 
// mise en route et arret de la pompe a eau

    digitalWrite(pompe_eau, HIGH); 
    delay(3000); // quantité d'eau dans le verre (temps en MS de fonctionnement de la pompe)
    digitalWrite(pompe_eau, LOW); //la pompe a eau est éteinte
        
    delay(1000); // delai entre les deux actions pour les eventuelles goutes

// servo eau deuxieme mouvement vers le coté 

    for (pos1 = 90; pos1 >= 0; pos1 -= 1) { 
    servo_eau.write(pos1);             
    delay(15);   // VITESSE DE ROTATION DU SERVO
}  

// servo verseur premier mouvement

    for (pos = 0; pos <= 90; pos += 1) { 
    servo_verseur.write(pos);              
    delay(15); // VITESSE DE ROTATION DU SERVO
}  
// temps pour vider le melange
    delay(2000);
         
// ARRET DU MOTEUR
                
// servo verseur deuxieme mouvement 
    for (pos = 90; pos >= 0; pos -= 1) { 
    servo_verseur.write(pos);              
    delay(15);   // VITESSE DE ROTATION DU SERVO                    
}

}
if(etatBouton_demarrage == LOW; etatBouton_nettoyage == LOW) // si les deux boutons sont appuyés en meme temps
 {
    moteur.step(0); // le moteur pas a pas ne tourne pas
    servo_verseur.write(pos);     // enregistre la postition 0 du servo
    servo_eau.write(pos1);     // enregistre la postition 0 du servo
    servo_ricard.write(pos2);     // enregistre la postition 0 du servo  
    digitalWrite(pompe_ricard, LOW); //le bouton est relâché, la pmpoe a ricard reste éteinte
    digitalWrite(pompe_eau, LOW); //le bouton est relâché, la pmpoe a eau reste éteinte
    digitalWrite(led, HIGH); // eteind la led
    delay(1000);
    digitalWrite(led, LOW); // allume la led
    delay(1000);
    digitalWrite(led, HIGH); // eteind la led
    delay(1000);
    digitalWrite(led, LOW); // allume la led
    delay(1000);
    digitalWrite(led, HIGH); // eteind la led
    delay(1000);
    digitalWrite(led, LOW); // allume la led
    delay(1000);
    
}
}

je n’aurai peut être pas du faire deux post different pour un même projet.

Merci a vous tous.

En gros, le problème de delay(), vous l’aurez compris, c’est que c’est bloquant. C’est à dire que cette fonction delay() contient une boucle qui va compter le temps qui passe, et vous ne sortirez de cette boucle que lorsque le temps spécifié est écoulé.
La fonction delay() définie par Arduino n’est pas basée sur millis(), mais elle pourrait l’être sur le principe de fonctionnement.
Ca, c’est ce que fait, sur le principe, la fonction delay() :

void delay(uint32_t attente){
  uint32_t fin = millis() + attente;
  while(millis() < fin){
    // rien à faire
  }
}

Le fonctionnement est assez simple : Avant de commencer la boucle, vous utilisez millis(), qui donne une référence temporelle en constante évolution. On pourrait dire qu’elle donne l’heure.
Vous savez que vous devez attendre tant de temps, vous regardez donc l’heure, vous y ajoutez votre temps d’attente, et ça vous donne l’heure à laquelle il faudra arrêter d’attendre. C’est ce que fait la première ligne.
Ensuite, vous exécutez la boucle. Et à chaque fois que vous recommencez la boucle du début, vous vérifier que l’heure prévue pour la fin n’est pas passée.

Maintenant si vous voulez faire quelque chose pendant un certain temps, mais sans bloquer votre programme, il faut réutiliser ce système (regarder sa montre est une manière éprouvée de savoir le temps qu’il nous reste), mais en permettant une autre activité (on ne peut pas non plus rester les yeux sur sa montre !)
Stepper a le même problème : quand vous utilisez la fonction de base pour avancer d’une nombre donné de pas en un temps donné, vous rentrez dans une boucle qui va majoritairement attendre.
Donc exit millis(). Dans l’idée vous allez faire quelque chose de ce genre-là :

uint32_t tempsCourant = millis();
uint_16t nombreDePas = 20;
uint32_t tempsTotal = 2000;
uint32_t tempsParPas = nombreDePas / tempsTotal;

void loop(){
  if(nombreDePas > 0) avancerUnPas(); // ici on vérifie qu'il faut bien avancer !
  // Plein d'autres choses ici !
}

void avancerUnPas(){
  if((tempsCourant + tempsParPas) < millis()) return; // ici on teste le temps écoulé depuis la dernière fois
  // Si le temps écoulé est supérieur à notre seuil, alors on met notre "horloge" à jour
  tempsCourant = millis();
  // On enlève un pas au nombre de pas qu'il reste à faire.
  nombreDePas -= 1;
  // Puis on avance le stepper d'un pas (je ne sais pas quelle fonction c'est, ça doit être
  Stepper.step(1, 1);
}

Vous avez l’idée : on définit quelques variables, pour stocker la dernière mesure de temps, et décortiquer le mouvement de notre moteur. Depuis la boucle principale, on appelle la fonction qui va nous permettre de vérifier le timing, et le cas échéant on va avancer.

Pour le servo, le prinicipe est le même. Vous définissez la plage de mouvement que vous voulez, le temps que cela doit durer, vous en déduisez un pas d’incrément et un temps séparant deux incrément successifs, puis vous écrivez une fonction similaire que vous appelez depuis le programme principal.

Ca peut paraître plus complexe (et ça l’est effectivement) que simplement définir un délai d’attente, mais c’est un élément clef en programmation : quelle que soit la puissance d’un microcontrolleur ou d’un microprocesseur, il ne peut faire qu’une chose à la fois (à part un système multi-cœurs). Il faut donc trouver des solutions pour qu’une tache (tourner un moteur de tant de tours en tant de temps) puisse être coupée en micro-taches appelées à intervalles réguliers (avancer régulièrement d’une petite quantité).

J'ai regardé ma bibliothèque. Une solution plus simple que je ne le pensais est de l'adapter aux moteurs unipolaires. Cela donnerait le PasAPas.h suivant:

#define SENS_NEGATIF false
#define SENS_POSITIF true

// pasAPasDeplacement fait tourner le moteur pas à pas
//    nbPas: nombre de pas pour la rotation 0..65535
//    sens: SENS_POSITIF ou SENS_NEGATIF; le vrai sens dépendra du câblage du moteur
void pasAPasDeplacement(uint16_t nbPas, bool sens);

// pasAPasIsRunning vaut true quand le moteur tourne. Ceci permet de savoir si le mouvement est fini (si 0) ou pas (si 1)
bool pasAPasIsRunning(void);

// pasAPasStop Arrête le mouvement
void pasAPasStop(void);

// Initialisation des broches utilisées
void pasAPasInit(void);

Pour faire tourner un moteur pas à pas, on appelle par exemple
pasAPasDeplacement(2048, SENS_POSITIF, 255);
Cette fonction n'est pas bloquante, et initie une rotation et pendant que le moteur tourne, on peut s'occuper du servo tranquillement avec un programme bloquant. On ne s'occupe plus du moteur pendant sa rotation.
Il suffit jusque que je l'adapte. Au début, je ne pensais pas le faire, mais au vu de ton problème, je crois que je vais le faire un jour. Autant le faire plus tôt si cela peut te servir.
Il faut aussi que j'ai la ou les vitesses utiles.

Voici une bibliothèque pour avoir un moteur pas à pas qui met entre 0,5s et 133s pour faire un tour. L’ordre n’est pas bloquant et tourne sans que l’on ait à s’en soucier. Normalement cela devrait fonctionner, mais n’ayant pas ce moteur, j’écris un peu à l’aveuglette.

Je n’avais au début pas l’intention de m’occuper de e type de moteur, mais le problème soulevé ici m’incite à changer d’avis. Merci Donc.

Les trois fichiers sont à mettre dans le même répertoire PasAPas

PasAPas.ino:

// Ce programme fait tourner un moteur n'ayant pas de limites à la rotation.  

// Les commandes pour faire les choix (base de temps, temps d'un pas et arrêt
// ou pas) se font par la console série à 115200 bauds.


#include "PasAPas.h"


//###########################################################################
//##                            Initialisations                            ##
//###########################################################################
void setup()
{
  pasAPasInit(); // Obligatoire pour initialiser la bibliothèque
  Serial.begin(115200); // Pour le dialogue
  Serial.println(F(
    "Temps entre pas 20µs par défaut entre 2 et 65536 fois l'horloge\n"
    "   + pour augmenter d'un incrément d'horloge\n"
    "   * pour augmenter de 10%\n"
    "   p pour doubler\n"
    "   - pour diminuer d'un incrément d'horloge\n"
    "   / pour diminuer de 10%\n"
    "   m pour diviser par 2\n"
    "Nombre de pas, 800 pas par défaut (1/4 tour en mode 16 micropas, moteur 200pas/tr)\n"
    "   7 pour augmenter de 800 pas le déplacement\n"
    "   8 pour doubler le déplacement\n"
    "   4 pour diviser par 2 le déplacement\n"
    "   1 pour diminuer de 800 pas le déplacement\n"
    "Sens de rotation\n"
    "   s pour changer le sens du moteur\n"
    "Arrêt entre les ordres\n"
    "   a pour changer arrêt/pas d'arrêt\n"
    "Ces commandes Hh+*p-/m7841sat sont a envoyer par la console\n"
    "Note: il peut y avoir du retard pour exécuter les ordres en mode continu\n"
    "(sans arrêt) le temps de finir le mouvement commencé\n\n" 
    )); // Affichage des instructions de fonctionnement
}


//###########################################################################
//##                           Boucle principale                           ##
//###########################################################################
uint16_t compteur = 255; // 16ms au départ (255*64µs)
bool affichage = true; // Force l'affichage au début
uint16_t deplacement = 40; //800; // Nombre de pas que va faire le moteur
uint8_t sens = 1; // 0: negatif,  1: positif, 2 ou 3: alterné
bool arret = false; // Pas d'arrêt entre les différents déplacements par défaut
void loop()
{
  //######################## Faire tourner le moteur ########################
  if (!pasAPasIsRunning()) // Si cela ne tourne plus
  {
    if (arret) delay(500); // Arrêt de 500ms entre deux déplacements
    if (sens > 1) sens ^= 1; // mode alterné, on alterne 2 et 3
    pasAPasDeplacement(deplacement, sens & 1, compteur);
  }
  //############################ Modifications ##############################
  if (Serial.available()) // Un ordre de modification est arrivé
  {
    affichage = true; // Il va falloir refaire l'affichage
    switch(Serial.read())
    {
      case '+': if (compteur < 255) compteur++; else affichage = false;  break;
      case '-': if (compteur > 1) compteur--; else affichage = false; break;
      case '*': if (compteur < 242) compteur+=compteur/20; else compteur = 255; break;
      case '/': compteur-=compteur/20; break;
      case 'p': if (compteur < 128) compteur*=2; else compteur = 255; break;
      case 'm': if (compteur > 3) compteur/=2; else compteur = 1;  break;
      case '7': if (deplacement < 64000) deplacement+=800; else affichage = false; break;
      case '8': if (deplacement < 32000) deplacement*=2; else deplacement = 64000; break;
      case '4': if (deplacement > 1000) deplacement=(deplacement / 1600) * 800; else affichage = false; break;
      case '1': if (deplacement > 0) deplacement-=800; else affichage = false; break;
      case 's': if (sens == 3) sens--; if (--sens == 0xFF) sens = 2;  break;
      case 'a': arret = !arret; break;
      default: affichage = false; // Il va falloir refaire l'affichage
    }
  }

  //################# Affichage si quelque chose à changé ###################
  if (affichage)
  {
    affichage = false; // Pour ne pas la faire deux fois...
    // Affiche genre "Horloge 0,5µs (1µs<pas<32ms) H pour augmenter, h pour diminuer"
    //               "Temps entre pas 5ms (ICR1=9999) p*+ pour augmenter, m/- pour diminuer"
    //               "Nombre de pas: 800 et 800; 7ou 9 pour augmenter, 1 ou 3 pour diminuer"
    //               "Pas d'arrêts entre les mouvements"

    // Temps
    Serial.print("Temps entre pas "); Serial.print(compteur*0.256); Serial.print("ms (tempsDuPas="); Serial.print(compteur); Serial.println(") p*+ pour augmenter, m/- pour diminuer");

    // Nombres de pas
    Serial.print("Nombre de pas: "); Serial.print(deplacement); Serial.println(" pas; 78 pour augmenter, 14 pour diminuer");

    // Sens
    Serial.print("Moteur sens "); Serial.print(sens > 1? "alterné": sens? "positif": "négatif");
    Serial.println(", s pour changer");
    
    // Arrêt ou pas
    if (arret) Serial.print("Arrêt entre les pas"); else Serial.print("Pas d'arrêt entre les pas");
    Serial.println(", a pour changer\n");


    if (arret) pasAPasStop(); // Permet de ne pas attendre, cela débloque si in a T=64µs et compteur=65535
  }
}

PasAPas.h

#define SENS_NEGATIF false
#define SENS_POSITIF true


// pasAPasDeplacement fait tourner le moteur pas à pas
//    nbPas: nombre de pas pour la rotation 0..65535
//    sens: SENS_POSITIF ou SENS_NEGATIF; le vrai sens de rotation dépendra du câblage du moteur
//    tempsDuPas: temps entre deux pas divisé par 256µs
//           maxi 255: 255*256µs=16ms, en mode pas entiers avec 2048 pas par tours -> 133s pour un tour, 0,007tr/s
//           minimum 1: soit 256µs, en mode pas entiers avec 2048 pas par tours -> 0,5s pour un tour, 1.9tr/s
//    tempsDuPas = 1 / (vitesse_en_tr/s * 0,000256µs * 2048)
void pasAPasDeplacement(uint16_t nbPas, bool sens, uint8_t tempsDuPas);

// pasAPasIsRunning vaut true quand le moteur tourne. Ceci permet de savoir si me mouvement est fini (si 0) ou pas (si 1)
bool pasAPasIsRunning(void);

// pasAPasStop Arrête le mouvement
void pasAPasStop(void);

// Initialisation des broches utilisées
void pasAPasInit(void);

PasAPas.cpp

#include <arduino.h> // LOW, HIGH, OUTPUT...
#include <avr/pgmspace.h> // Pour lire les valeurs d'accélération
#include "PasAPas.h"

enum {HORIZONTAL, VERTICAL};
#define bobine1 2 // <N° de la broche pour la première bobine>
#define bobine2 3 // <N° de la broche pour la deuxième bobine>
#define bobine3 4 // <N° de la broche pour la première troisième bobine (ordre inverse de la première bobine>
#define bobine4 5 // <N° de la broche pour la première quatrième bobine (ordre inverse de la deuxière bobine>

//###########################################################################
//##                          Variables globales                           ##
//###########################################################################

uint16_t tempsEntrePas; // Délai entre deux pas en paquets de 256µs
uint16_t nombreDePasRestants; // Nombre de pas restants
bool sensDeRotation; // sensDeRotation
volatile bool enMouvement = false; // Si true, on se déplace
volatile bool arretDemande = false; // On finit la temporisation du pas et on s'arrête
uint8_t pasEntier;
bool pasAPasIsRunning(void) { return enMouvement; } 
//###########################################################################
//##                     Fonction d'interruption Timer 2                   ##
//###########################################################################
ISR(TIMER2_COMPA_vect)
{
  if (arretDemande) // Il n'y avait plus d'ordres dans la table
  {
    TIMSK2 = 0; // Arrêter les inters du timer 2
    enMouvement = false;
    arretDemande = false; // Suppression de l'ordre, on en a tenu compte
  }
  else
  {
    // Envoi du pas
    if (sensDeRotation) pasEntier++; else pasEntier--; // compteur du type de pas  1100, 1001, 0011, 0110 
    if ((pasEntier >> 1) & 1)
    {
      digitalWrite(bobine1, HIGH); digitalWrite(bobine3, LOW);
      if (pasEntier & 1) { digitalWrite(bobine2, HIGH); digitalWrite(bobine4, LOW); }
      else { digitalWrite(bobine2, LOW); digitalWrite(bobine4, HIGH); }
    }
    else
    {
      digitalWrite(bobine1, LOW); digitalWrite(bobine3, HIGH);
      if (pasEntier & 1) { digitalWrite(bobine2, LOW); digitalWrite(bobine4, HIGH); }
      else { digitalWrite(bobine2, HIGH); digitalWrite(bobine4, LOW); }
    }

    OCR2A = tempsEntrePas; // Mettre le temps, a changé si on a changé de vecteur de déplacement

    if (nombreDePasRestants == 0) arretDemande = true; // Pour le dernier pas, il faut le finir (faire sa temporisation) avant de faire autre chose

    // Préparation des nouvelles valeurs
    nombreDePasRestants--;
  }
}


//###########################################################################
//##                         PasAPasDeplacement                          ##
//##                            Un seul moteur                             ##
//###########################################################################
void pasAPasDeplacement(uint16_t nbPas, bool sens, uint8_t tempsDuPas)
{
  if (tempsDuPas >0) tempsDuPas--; // A cause du timer
  if (nbPas > 0)
  {
    while (enMouvement);
    tempsEntrePas = tempsDuPas;
    nombreDePasRestants = nbPas;
    sensDeRotation = sens;
  }  
  while (arretDemande);
  if (!enMouvement) //il faut lancer le premier pas
  {
    TCNT2 = 0; // Remettre le compteur à 0 pour que la première tempo soit bonne
    OCR2A = 79; // Première impulsion dans 5µs (H=62ns) à 5ms (H=64µs) pour avoir le temps de finir cette fonction
    nombreDePasRestants--;
    enMouvement = true; // Indication: on a démarré
    TIFR2 = 0b00000010;
    TIMSK2 = 0b00000010; // Autoriser les interruptions
  }
}

//###########################################################################
//##                              pasAPasStop                              ##
//###########################################################################
// Cette fonction arrête le moteur. Cela permet par exemple de lancer le
// moteur et de l'arrêter avec un fn de course
void pasAPasStop(void)
  {
    TIMSK2 = 0; // Arrêter les inters du timer 2
    enMouvement = false;
    arretDemande = false; // Sauf cas où on étati en trai de demander un arrêt
  }

//###########################################################################
//##                              pasAPasInit                              ##
//###########################################################################
void pasAPasInit(void)
{
  // Initialisation des moteurs
#define bobine1 2 // <N° de la broche pour la première bobine>
#define bobine2 3 // <N° de la broche pour la deuxième bobine>
#define bobine3 4 // <N° de la broche pour la première troisième bobine (ordre inverse de la première bobine>
#define bobine4 5 // <N° de la broche pour la première quatrième bobine (ordre inverse de la deuxière bobine>
  digitalWrite(bobine1, LOW);
  pinMode(bobine1, OUTPUT);
  digitalWrite(bobine2, LOW);
  pinMode(bobine2, OUTPUT);
  digitalWrite(bobine3, HIGH);
  pinMode(bobine3, OUTPUT);
  digitalWrite(bobine4, HIGH);
  pinMode(bobine4, OUTPUT);
  delay(200);
  TIMSK2 = 0b00000000; // Pas d'interruption du timer pour l'instant
  TCCR2A = 0b00000010; // Pas de comparaisons, mode CTC
  TCCR2B = 0b00000111; // Mode CTC OCR (2), prescaler à /1024
}