Bonjour,
J'ai réalisé ce petit code qui me permet de déplacer un chariot avec un Nema 17. Quand le chariot touche le EndStop, le moteur tourne dans l'autre sens pour libérer le EndStop (et ne plus être en position LOW) .
Je fais cela via un temps mais ce n'est pas idéal voir inutilisable.
Je ne vois pas comment arrèter le moteur sitôt le EndStop relaché... (Détail : je dois pouvoir relancer le mouvement inverse plus tard donc je ne peux pas Exit() dès que je touche le EndStop)
Pourriez vous me donner un coup de pouce SVP ?
const int stepPin = 3;
const int dirPin = 4;
const int bouton = 2;
int btnetat;
int minutes = 8000;
void setup() {
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(bouton, INPUT);
//Serial.begin(9600);
}
void loop() {
btnetat = digitalRead(bouton);
//Serial.print(btnetat);
if (btnetat == HIGH){
digitalWrite(dirPin,LOW);
digitalWrite(stepPin,HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin,LOW);
delayMicroseconds(1000);
}else{
if (millis() < minutes) {
digitalWrite(dirPin,HIGH);
digitalWrite(stepPin,HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin,LOW);
delayMicroseconds(1000);
}else{
exit(0);
}
}
}
Je ne connais pas ton EndStop, il faudrait que tu en dises plus. Est-ce un bouton poussoir, un capteur de fin de course...?
Si ce genre de capteur fait des rebonds (comme le bouton poussoir), c'est peut-être là que se situe ton problème.
Aussi
ne dure qu'une milliseconde, c'est peut-être trop peu pour permettre au moteur de reculer et de relâcher le EndStop ?
Enfin,
ne sert à rien : je pense que ça sort de la loop, mais le code rentre immédiatement dans la loop donc aucun intérêt.
D'après ce que je comprend, c'est pour arrêter définitivement le programme. Habituellement, on met une boucle sans fin: while(TRUE);
Il y a un problème avec
Si le moteur doit revenir pendant X millisecondes, il faut initialiser minutes avec la valeur de millis actuelle et boucler tant que millis() - minutes est inférieur à X.
Dans ce programme l'attente dure jusqu'à 8s après l’initialisation de la machine (mise sous tension)
-> si on est quasi sur le capteur, on revient pendant 8s
-> si on met plus de 8s pour atteindre le capteur, il n'y a plus de retour.
Si j'ai bien compris, au départ du programme, EndStop LOW, le MPAP "avance" et arrive sur EndStop qui est HIGH, le MPAP "recule", jusqu'à ce que EndStop = LOW.
Si oui,
Quel est exactement ce mouvement inverse?
J'ai étudié ton programme, et pour pouvoir faire des "mécaniques" tel que tu le désires, il est mal structuré et rend la chose très difficile. Je me suis permis de le modifier afin que tu puisses voire comment faire. Tel quel il ne fait que faire tourner le moteur dans un sens et inverser le sens quand le bouton est pressé, mais ça peut être un bon point de départ. A partir de là on peut mettre les conditions dépendantes de l'état de EndStop.
Si tu le désires, je peut aller plus loin et implémenter la gestion de EndStop.
const int stepPin = 3;
const int dirPin = 4;
const int bouton = 2;
int btnetat;
int minutes = 8000;
const int mpapDirectionSh = LOW; // Pour sens horaire
const int mpapDirectionSah = HIGH; // Pour sens anti horaire
void setup() {
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(bouton, INPUT);
Serial.begin(9600);
}
void loop() {
btnetat = digitalRead(bouton);
Serial.println(btnetat);
if (btnetat == HIGH)
{
mpapMove1pas(mpapDirectionSh);
}
else{
mpapMove1pas(mpapDirectionSah);
}
}
void mpapMove1pas(int mpapDirection)
{
Serial.println(mpapDirection);
digitalWrite(dirPin,mpapDirection);
digitalWrite(stepPin,HIGH);
delayMicroseconds(800);
digitalWrite(stepPin,LOW);
delayMicroseconds(800);
}
Merci pour la modification du code jpbbricole et merci à tous pour les réponses.
Un problème avec ton code jpbbricole : comment je dois déclarer la fonction "mpapMove1pas" ? je n'y arrive pas et j'ai un renvoi " mpapMove1pas ne peut pas être utilisé comme une fonction"
J'explique mieux l'ensemble de ce que j'essaye de faire:
J'appui sur un 1er bouton -> le moteur tourne en sens horaire et déplace un chariot vers le haut.
Qd le chariot touche le EndStop du haut, le programme s'arrête pour stopper le mouvement.
J'appui sur un second bouton -> le moteur tourne en sens antihoraire et déplace le chariot vers le bas.
Qd le chariot touche le EndStop du bas, le programme s'arrète pour stopper le mouvement.
ETC...
J'avais expliqué qu'une partie pour ne pas être lourd et avancer pas à pas mais, effectivement c'est pas clair. (le delay ne servait à rien dans mon 1er code, c'etait juste pour essayer)
C'est typique d'une entrée "en l'air". D'après ton programme, tu est en technique PULL_DOWN (if (btnetat == HIGH)), ce qui veut dire que l'entrée bouton a une résistance d'environ 4.7k contre GND.
Le mieux, pour simplifier les choses, est de faire l'inverse, le PULL_UP.
Initialiser les entrées des boutons avec pinMode(bouton, INPUT_PULLUP);
Inverser les tests digitalRead(bouton) == LOW
devient digitalRead(bouton) == HIGH
et digitalRead(bouton) == HIGH
devient digitalRead(bouton) == LOW
et le commun des boutons passe de +5V à GND.
Ca paraît un peu tortueux au premier abord, mais ainsi plus de résistances, on utilise les internes e l'Arduino.
Suite à cette explication, voilà comment je vois la chose:
/*
Name: ARDFR_mpap.ino
Created: 21.06.2021
Author: jpbbricole
*/
const int btnEtatPresse = LOW;
const int endstopEtatTouche = LOW;
const byte stepPin = 3;
const byte dirPin = 4;
//const byte bouton = 2;
const byte btnVersHautPin = 5;
const byte btnVersBasPin = 6;
const byte endStopHautPin = 7;
const byte endStopBasPin = 8;
const int mpapDirectionCW = LOW; // CW Pour sens horaire
const int mpapDirectionCCW = HIGH; // CCW Pour sens anti horaire
void setup() {
Serial.begin(9600);
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(btnVersHautPin,INPUT_PULLUP);
pinMode(btnVersBasPin,INPUT_PULLUP);
pinMode(endStopHautPin,INPUT_PULLUP);
pinMode(endStopBasPin,INPUT_PULLUP);
}
void loop() {
// Si commande vers le haut et pas encore sur EndStop
if (digitalRead(btnVersHautPin) == btnEtatPresse && digitalRead(endStopHautPin) != endstopEtatTouche)
{
while (digitalRead(endStopHautPin) != endstopEtatTouche) // Tant que pas sur endstop haut
{
mpapMove1pas(mpapDirectionCW);
}
//delay(500);
}
// Si commande vers le bas et pas encore sur EndStop
if (digitalRead(btnVersBasPin) == btnEtatPresse && digitalRead(endStopBasPin) != endstopEtatTouche)
{
while (digitalRead(endStopBasPin) != endstopEtatTouche) // Tant que pas sur endstop haut
{
mpapMove1pas(mpapDirectionCCW);
}
//delay(500);
}
}
void mpapMove1pas(int direction)
{
digitalWrite(dirPin,direction);
digitalWrite(stepPin,HIGH);
delayMicroseconds(800);
digitalWrite(stepPin,LOW);
delayMicroseconds(800);
}
C'est basé sur un câblage PULL_UP mais facile à changer.
J'ai modifié, un peu, l'attribution des pin.
L'usage des moteurs pas à pas est un sujet passionnant, j'adore ça. Ceci est un bon début, après il faudrait utiliser la "puissance" d'une bibliothèque de MPA comme Stepper.h ou AccelStepper.h, mais pour ce programme ça ne t'aiderai pas beaucoup plus.
Jpbbricole je voudrais pas être lourd mais là, du coup, je suis totalement largué.
Je ne sais pas du tout faire les branchements et connexions.
Tu n'aurais pas un petit schéma sous le coude parce que sinon je ne vais pas pouvoir utiliser tout ça...
Wahou ! merci encore !
Bon j'ai du taf parce que, sans mon 4988 et les moteurs je suis pas à l'aise à l'aise mais je vais essayer de comprendre. Je te tiens au courant.
Il y a les 2 boutons; les 2 endstop, une diode DIR (qui ne s'allume pas d'ailleurs...) et un oscilloscope....
Non je disais juste que je n'etais pas à l'aise (pas dans mon element) avec tous ces codes et branchements
J'ai mis ces 2 choses, parce que, dans Tinkercad, je n'ai pas trouvé le nécessaire pour faire exctement comme ton montage, c'est à dire un A4988 couplé à un moteur pas à pas. La LED quand elle est allumée, indique un des sens (DIR) du MPAM et l'oscillo image les impulsions envoyées au MPAP
Oui, elle s'allume
Je te le concède, c'est pas évident à constater!
Malheureusement la simulation tasse un peu les étiquettes des boutons, le réel est ainsi
La séquence, au démarrage de la simulation est
btnVersHaut, (Signal carré sur oscille = impulsion pour STEP A4988 LED (DIR) éteinte)
endStopHaut, (Signal sur l'oscillo s'arrête)
btnVersBas, (Signal carré sur oscille = impulsion pour STEP A4988 + LED (DIR) s'allume)
endStopBas, (Signal sur l'oscillo s'arrête)
Pour démarrer la simulation,
C'est ici
Cliquer
puis