Programmation stepper et autres actions dans une même boucle ?

Hello

Me voici face à un petit problème de programmation.

Je gère un stepper moteur NEMA 17 avec un driver qui simplifie les commandes en Dir et Pul.
Ce genre de commande s'effectue forcément avec un delay d'impulsions qui fait varier la vitesse.
Exemple pour la vitesse la plus rapide:

digitalWrite(11, HIGH); // pin impulsions
delay(1);
digitalWrite(11, LOW);
delay(1);
digitalWrite(10, HIGH); //pin de direction

Le problème se présente si je veux utiliser cette commande moteur dans une condition if, mais en y ajoutant également d'autres actions.

if (détection d'un machin-truc)
{

  • allumer une led ou positionner servo moteur à 90°, ou autre...
  • delay (2000);
  • faire tourner le stepper;
    }

Dans ce cas, le stepper ne tournera que d'un pas toutes les deux secondes, puisque l'action précédente dans la boucle prévoit un delay de 2000 millisecondes entre les deux actions des deux moteurs différents.
Quel moyen pourrai-je utiliser pour qu'une action du stepper se fasse après une condition if et/ou un temps d'attente, sans que cela implique toute la boucle et donc condition la vitesse du stepper?

(j'espère que je suis assez clair, ce n'est pas facile à expliquer)

Merci !

bonjour,
fonction millis()

Bonne réponse :smiley: Millis ou Micros...

J'ai adapté un programme basé sur le principe des micros, mais quelques questions me viennent pour bien le comprendre :

Question 1 :

Je n'arrive pas toujours à comprendre la fonction "for" qu'on utilise dans ce cas de figure.

Exemple :

void step() {

digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(vitesse);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(vitesse);
}

void loop() {

for (int i = 0; i < 100; i++)
{
step();
}
}

Je ne vois pas à quoi ces 100 pas font référence étant donné que le moteur tourne en continu. On peut très bien remplacer ce chiffre par 20 ou 100000, ça ne change rien...

Question 2 :
J'ai tenté d'incorporer cette portion de programme dans une condition if, mais le moteur ne tourne plus. Je fais très certainement une bourde, mais comme je suis débutant, je ne vois pas quoi...
Quelle serait une structure type dans le void loop qui permettrait d'inclure une action avant et/ou après une rotation moteur?

void loop()
if machin-truc-bidule
{
servo.write (pos, 90);
delay (5000);

digitalWrite (pinbidule, HIGH);
delay (5000);

for (int i = 0; i < 100; i++)
{
step();
}
else
{
FactoryFormatArduino; ^^
}
}

hello
1/ oui, tu peux mettre 1 ou 100000, ça ne changera rien
une fois le maxi atteint, la loop fait son boulot et on recommence.

2/
attention aux () et aux {}

void loop()
{
  if (condition==vraie)
{
servo.write (pos, 90);
delay (5000);

digitalWrite (pinbidule, HIGH);
delay (5000);
  
for (int i = 0; i < 100; i++)
    {
        step();
    }
}
else
{
FactoryFormatArduino; ^^
} 
}

Oui oui, je faisais attention aux () dans mon programme, je l'avais bien structuré comme tu l'as mentionné. Mon programme était un peu trop grand, j'ai donc refais un nouveau avec la partie qui m'intéresse ici. Effectivement le moteur tourne bien (je ne comprends pas car l'autre programme est le même à cet endroit... bref, je scruterai tout ça plus tard).
J'ai toutefois encore un problème.

Est-il possible d'imaginer une boucle qui prévoit un nombre de tour très grand du stepper, mais qui est interrompue si une condition n'est plus remplie. Par exemple, dans le cas d'un bouton d'arrêt d'urgence pour stopper le stepper?

oui avec faire tant que

do{

appel fonction pour 1 pas moteur ( ou x pas )

} while ( arret urgence est true)

ah oui tiens, ça m'intéresse, merci :slight_smile:

Je viens d'explorer cette voie, en espérant qu'elle soit compatible avec des "if" qui la précède.
Mais quelque chose ne fonctionne pas...

void loop()
{
int bouton2 = digitalRead(2);
int bouton3 = digitalRead(3);

if (bouton3 == 1)

{

servoA.write (posA = 100);
delay (2000);
do{
for (int i = 0; i < 20000; i++)
{
StepperTourne();
}
}
while (bouton2 == 0);

}
}

Ca tourne, mais le while n'interrompt rien...
J'imagine qu'il faudrait dire que faire à While... ou encore que while ne peut fonctionner qu'avec TRUE ou FALSE ?

while (digitalRead(bouton2)==0)

Etrange...
Peux-tu m'expliquer pourquoi il faut indiquer à nouveau la fonction digitalRead alors qu'elle est déjà au début de la loop svp?

Ceci dit, je viens d'essayer, mais ça n'interrompt toujours rien.

do signifie faire
while signifie tant que

donc: faire la boucle "for" tant que bouton2==0

et pour savoir si bouton2 est toujours à 0, il faut bien le tester

Effectivement, il faut bien tester le bouton, mais il me semblait que cette fonction était déjà appelée au début de la boucle :
int bouton2 = digitalRead(2);
est déjà présent en tête de boucle.

Cela ne signifie-t-il pas que la valeur du bouton2 résulte de la lecture de la pin 2?
Ne peut-on pas simplement reconvoquer cette valeur plus tard dans la loop, en l'appelant "bouton2", après le While? Apparement, tu me dis que non, mais je ne comprends pas bien pourquoi.
Si le digitalRead n'avait pas été présent en début de boucle, je comprends bien qu'il aurait fallu lui indiquer au moment du While.

suit ton prg mentalement

tu verras qu'une fois que tu es dans le do while, tu ne peux en sortir que si BP2 est à LOW.

manque de pot, lors de la lecture en début de la loop, BP2 est à LOW

donc dans le do while, tu vas y rester éternellement.

si tu veux en sortir, il faudra bien que le BP2 soit actionné et passe en HIGH

et bien sur que tu lises son état.

cette fois ci j'abandonne....

Je te croyais sur parole, c'est juste que j'ai dû apprendre que while ne peut tenir compte d'autres infos pourtant déjà présentes précédemment dans la loop. Ca n'allait pas de soi dans mon esprit car, suivant la même logique, do ne devrait même pas connaitre l'existence d'une condition qui lui succède. C'est parce que les codeurs l'ont décidé arbitrairement de la sorte que cela fonctionne comme ça.

Je n'ai jamais remis en cause une seconde que l'état du bouton doive être lu. Je m'interrogeais sur la persistance à travers la loop de la fonction digitalRead. Mais tu m'as appris qu'elle n'était active qu'au moment de la convoquer.
Je pense que ma confusion vient du fait qu'avant j'utilisais un moteur DC pour cette application et que le digitalRead en début de loop était en permanence effectif et coupait l'action dès que le bouton était activé, même si l'action moteur était déjà lancée en vérifiant au préalable cette condition.
L'utilisation du stepper change la donne... D'où l'intérêt de l'ouverture de ce sujet ^^

Merci