alors j'arrive à faire tourner mon moteur NEMA17 à l'aide d'un DRV8825 et d'un ESP32.
Mais voilà j'ai un soucis lorsque j'exécute ce code, mon moteur tourne tantôt dans un sens tantôt dans l'autre, alors qu'il ne devrait tourner que dans un sens.
#define dirPin 27
#define stepPin 26
#define stepsPerRevolution 2000
void setup() {
// Declare pins as output:
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
// Set the spinning direction clockwise:
digitalWrite(dirPin, HIGH);
// Spin the stepper motor 1 revolution slowly:
for (int i = 0; i < stepsPerRevolution; i++) {
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000);
}
Si le DRV8825 est en mode pas entier, il peut s'agir d'un phénomène de résonance. J'arrive aussi à faire tourner mon moteur en sens inverse, voir vidéo.
Merci pour votre réponse. Justement j'essaie de mettre en mode micro-pas le DRV8825 en mettant à HIGH les broches M0 M1 et M2. Vous me confirmez que mettre ces broches à HIGH veut dire qu'il faut leur mettre +5V ? Lorsque je met +5V sur ces trois broches mon moteur ne tourne plus.
Ce code ne correspond pas à la datasheet du DRV8825, ni du A4988 d'ailleurs :
// Spin the stepper motor 1 revolution slowly:
for (int i = 0; i < stepsPerRevolution; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
C'est une erreur qui est colportée par les copieurs du net, l'auteur original n'ayant pas lu ou pas compris la datasheet.
Encore un extrait de la datasheet :
Explication : tu mets 500 µs pour le plat du "1" alors que le circuit demande 2 µs.
Et tu en fais autant en fin boucle for.
Ce faisant tu divises la vitesse que tu penses mettre par deux.
La vitesse maximale que peut supporter le circuit intégré est de 1/(2 µs + 2 µs) = 250 kHz (le moteur aura décroché avant).
Je ne connais pas le temps que met la fonction digitalWrite() pour s'exécuter sur un ESP32.
Sur un atmega328p, digitalWrite() met un peu plus de 60 cycles horloge à 16MHz soit 3,75 µs.
Donc aucun delai n'est à spécifier, digitalWrite est suffisamment lente.
Il suffit d'écrire une fonction :
for (int i = 0; i < stepsPerRevolution; i++) {
avanceUnpas();
delayMicroseconds(500);
}
Avec ce nouveau code, tu feras effectivement un pas toutes les 500 µs.
Avantage : tu sépares le delayMicrosecond() nécessaire au fonctionnement du DRV8825 du delayMicrosecond() qui règle la vitesse de rotation. Le code est plus lisible.
Si tu n'arrives pas à connaître le temps d'exécution de la fonction digitalWrite() sur ESP32 tu placesun délai d'une à 2 µs
Je confirme qu'il faut mettre les trois broches à 5V.
Ne tourne plus ou ne tourne plus beaucoup? En passant en 32 micro pas, il faut envoyer 32 ordres pour faire un pas au lieu d'un seul ordre. Le moteur tourne 32 fois moins vite.
Dans le programme ci-dessus, la boucle dure environ
digitalWrite(stepPin, HIGH); 92 → X µs
delayMicroseconds(500); 92 → 500 µs
digitalWrite(stepPin, LOW); 92 → X µs
delayMicroseconds(500); 92 → 500 µs
Je ne sais pas combien de temps vaut X, avec une uno c'est 6µs. C'est petit de toutes façon devant les 1000µs. En faisant:
digitalWrite(stepPin, HIGH); 92 → X µs
delayMicroseconds(15); 92 → 15 µs
digitalWrite(stepPin, LOW); 92 → X µs
delayMicroseconds(15); 92 → 15 µs
il est possible que X ne soit plus négligeable devant les 30 µs et que le moteur tourne un peu moins vite qu'en comptant que les temporisations (1 tour toutes les 30µs x 32 ordres/pas x 200 pas/tour soit 5 tour/s)
Il est bien précisé dans le commentaire qu'une boucle fait un pas, et comme il y a deux délais, on a un pas toutes les ms.
Le circuit a besoin de 2µs minimum. On peut parfaitement en mettre 500µs. Je trouve que le code ci dessus permet de calculer le temps d'un pas. Il y a juste l'erreur (que l'on peut corriger) du temps des instructions digitalWrite() et du temps de la boucle (en principe faible).
En faisant un appel à le fonction, il y a beaucoup plus d'instructions et le temps de la boucle est plus compliquée à faire.
Pour faire un pas toutes les 500µs, il suffit de faire:
Bien sûr en supposant petit les temps des autres insrtuctions.
Cela règle le problème du temps minimum pour l'état haut, mais pas pour l'état bas. En mettant les deux délais comme ci dessus, on aura un problème qu'à partir de 250kHz. De toutes façon à cette vitesse on ne peut plus rien faire, sauf changer de circuit (par exemple le A4988 a un temps de 2µs au lieu de 3.8µs) ou de diminuer le nombre de micro pas.
Négliigeable devant quoi ?
Le but de mes propos c'est quoi ?
Le nom de la fonction digitalWrite() est le même mais le contenu de la fonction est différent selon que l'on soit avec un atmega, un ESP32 ou un STM32.
Si le temps d'exécution de digitalWrite() est supérieur à 2 µs il est inutile d'ajouter un delai pour avoir un ordre "step" conforme aux spécification du DRV8825..
S'il y a un doute on ajoute un delai de 2 µs.
De toute façon cela ne limitera pas la vitesse maximale de commande du moteur qui s'arrétera bien avant les 250 kHz propre au circuit intégré de commande.
Le message que j'ai voulu faire passer, visiblement vu les commentaires je n'y suis pas arrivé, est que le circuit intégré a un mode de fonctonnement : Un "1" qui dure au minimum 2 µs suivi d'un "O" qui doit durer aussi au minimum 2 µs.
Ces temps sont necessaires aux A4988 et DRV8825 pour comprendre l'ordre qu'on leur envoie.
Alors bien sûr on peut faire ce que l'on veut et faire fi de la datasheet mais à un moment où à un autre on va dire "j'comprend pas ça marchait, ça marche pu".
Très clairement je préfère me caller sur la datasheet.
Question : je serais curieux de savoir comment la bibliothèque Axelstepper procède.
La suite du message était implicite, apparament l'implicite ne fonctionne pas, il faut mettre les pieds dans le plat.
Utiliser des exemples ou une biblithèque ne dispense pas de jeter un coup d'oeil sur la datasheet des circuits intégrés que l'on achète soudés sur un bout de circuit imprimé.
Il n'est pas utile de tout lire mais au minimum le tableau des valeurs a ne jamais dépasser (Maximum Rating) et celui qui ressence les principales caractéristiques aux conditions d'usage préconisées par le fabricant du circuit intégré (et non pas celui du circuit imprimé).
Justement lorsque je dis que le temps d'exécution de la fonction digitalWrite() est négligeable c'était en rapport au 2µs de délai à ajouter. Hors je me rend compte après avoir relu qu'il est nécessaire d'ajouter un délai vue qu'on est à (586/1000)µs ce qui est inférieur au 2µs nécessaire pour faire comprendre au DRV8825 l'ordre qu'on lui envoie.
Je vais tester tout ça cet après midi et je reviens partager avec vous mes résultats.
Alors j'ai connecté mes broches M0 M1 et M2 au +5V de mon ESP32 afin qu'ils soient toujours à HIGH et j'ai codé ceci avec vos recommandations et en lisant la datasheet du DRV8825. Je lui envoie 32 fois les instructions HIGH et LOW en mettant 15µs de delay.
#define dirPin 27
#define stepPin 26
#define stepsPerRevolution 32
void setup() {
// Declare pins as output:
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
// Set the spinning direction clockwise:
digitalWrite(dirPin, HIGH);
for(int i=0; i < stepsPerRevolution; i++)
{
// Spin the stepper motor 1 revolution slowly:
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(15);
digitalWrite(stepPin, LOW);
delayMicroseconds(15);
}
}
Le moteur tourne correctement, j'entends par cela qu'il ne vibre pas et n'a pas l'air de sauter de pas comme vous pouvez le voir sur la vidéo.
Cependant quand j'appuie sur le bouton reset de mon ESP pour arrêter le programme et le relancer on peut voir que le sens de rotation du moteur change. Hors j'ai dis à la ligne 11 que je voulais que mon moteur tourne dans le sens anti-trigo.
Alors de ce que j'ai compris il se peut que lorsque j'arrête mon moteur de tourner celui ci se trouve dans une position (instable) qui ferait qu'au prochain lancement il se mettrait à tourner dans l'autre sens. Hors je pensais qu'en passant par le mode micro pas ce problème n'apparaitrait plus.
Je veux vraiment comprendre ce phénomène car je souhaite réaliser un bras robot par la suite et si les moteurs se mettent à tourner dans le sens inverse attendu chaque fois qu'ils sont à l'arrêt pour ensuite repartir, ça risque de faire des dégâts
!!!!! J'ai jamais vu ça!
Pour valider ton montage, plutôt que de faire tourner ton moteur "à la main", tu devrais utiliser une bibliothèque comme AccelStepper, qui a tout ce qu'il faut, comme faire tourner tes moteurs en mode bloquant ou non bloquant. Fais des essais sans micro-pas pour commencer.
Si tu regardes la vidéo tu verra qu'avec le code que j'ai utilisé, le moteur se met à tourner dans un sens puis dans l'autre dès lors que j'arrête le programme et le relance et ça de manière aléatoire. Comment explique tu celà ?
tu devrais utiliser une bibliothèque comme AccelStepper
Alors je préfère savoir coder ce que je souhaite pour bien comprendre le fonctionnement car par la suite je veux fabriquer un bras robot.
D'ailleurs j'ai essayé au tout début d'utiliser cette bibliothèque et elle ne m'a pas rendu service puisque sur le simple exemple fournit pour faire tourner mon moteur d'un seul tour (360°) j'avais des soucis
Je ne doute pas que tu as un problème, c'est pourquoi je te propose de faire l'essai avec une bibliothèque, pour être sûre de ton montage.
Quand je dis que je n'ai jamais vu ça, je voulais dire en utilisation normale, sans doute(s) à propos de l'installation.
Oui, c'est tout à fait louable que de vouloir faire marcher un moteur à la main, ça apprend (quoi que...) ça se résume juste à faire des impulsions. Quand à faire fonctionner un bras robot de la sorte, bon courage! L'usage d'une bibliothèque est quasiment incontournable.
Je n'ai pas le temps de faire des essais dans tes conditions, comme tu a eu des problèmes avec AccelStepper, essaies avec StepperDriver, ça marche sur ESP32, je l'ai déjà utilisé ainsi. Il y a des explications ici. Avec ça, ça doit fonctionner, autrement tu as des problèmes avec ton montage.
Bonjour a tous,
68tjs, tu as une interprétation très personnelle de la datasheet. Un comble pour un ardent défenseur de la lecture de cette prose.
Elle nous indique que l'impulsion positive sur STEP doit durer au minimum 1,9uS POINT
De même l'impulsion négative doit durer minimum 1,9uS POINT.
A ce point de vue là, le code de nekcorp, dans le message numéro 1, est parfaitement correct.
Si quelqu'un a envie de changer le niveau sur la pin Step toutes les demi-heures, il serait parfaitement dans les spécifications. Il n'y a pas de durée maximale définie.
Enfin, c'est comme cela que je lis l'extrait de la spec que tu publies.
Jacques
D'après ma compréhension des pas à pas le coup d'aller en arrière suite à un arrêt sur une position instable ne peut se produire que sur un seul pas et est donc difficile à détecter.
Si le DRV reçoit le bon niveau sur sa broche DIR je ne vois pas comment le moteur pourrait tourner à l'envers.
Le sens de rotation du moteur ne dépend pas de la position d'arrêt précédent, mais de l'ordre de commande et du sens du courant dans les bobinages. Et ça, c'est le travail du DRV.
Je pense que tu n'as pas cette chose :
C'est un analyseur logique qui permet de voir si les niveaux sont "1" ou "0", c'est indispensable.
Il possède 8 sondes.
Il coûte moins de 10 € --> il est indispensable.
Dans la pratique je réserve toujours une sonde pour la synchronisation.
const uint8_t pinX synchro;
pinMode(synchro, OUTPUT) ;
digitalWrite(synchro, LOW); // non indispensable mais fixe bien les choses`
Ce qu'il fait c'est que loop se répète (c'est sa fonction) et que pour chaque tour de loop, le moteur fait un pas. Quand loop est fini, loop recommence et le moteur ne s'arrête pas.
Pour faire les essais, ce serait mieux de mettre le paramètre stepsPerRevolution à la bonne valeur. le nombre de micro-pas par tour est de 20032, remplacer la ligne par: #define stepsPerRevolution 200*32
serait plus exact. Ce qui rendrait aussi le commentaire "// Spin the stepper motor 1 revolution" correct. Pour voir si cela fonctionne, faire par exemple un tour (une fois loop qui envoie alors 20032 fois l'impulsion) puis attendre un peu avec un delay genre 500ms.
Mais ce n'est pas cela qui fait que le moteur tourne dans un sens ou dans l'autre. D'après ce que je vois de la vidéo, je ne crois pas à la résonance non plus. On dirait plutôt que la broche DIR du DRV8825 n'est pas sur la broche 27. A vérifier. Pour voir si il s'agit d'un phénomène de résonnance, on peut diminuer fortement la vitesse. Ici on tourne à quelques tours par seconde, en divisant la vitesse par 10, on n'a plus de résonnance. Il est peu probable que l'on ait deux vitesses d'un rapport 10 qui fasse si bien tourner le moteur.
De toutes façons si cela ne fonctionne pas avec ce code simple, cela ne fonctionnera pas avec une bibliothèque.
Les essais ont été faits sans micro pas. Je note aussi qu'AccelStepper dit garantir la vitesse jusqu'à 1000 impulsions step par seconde soit 1000/(32*200)=0,16tr/s en 32 micro pas. Dans ces conditions, je comprend qu'i faut bannir les micro pas!
Je crois aussi qu'il fait relire la question: c'est "pourquoi MON code fait tourner mon moteur dans les deux sens", et pas "je voudrais copier le code d'un autre pour que mon moteur tourne dans un sens".
Je ne crois pas beaucoup que le moteur, même si il n'est pas sur le bon pas à l'initialisation,
parte dans le mauvais sens. Voir ce qui se passe pour des vitesses 10 fois plus faibles.
Le code ci dessus est un grand classique, et il est sans doute plus sûr qu'un bibliothèque. Rajouter une bibliothèque rajouterai des problèmes.
Le code principal est le suivant:
void AccelStepper::step1(long step)
{
(void)(step); // Unused
// _pin[0] is step, _pin[1] is direction
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
// Caution 200ns setup time
// Delay the minimum allowed pulse width
delayMicroseconds(_minPulseWidth);
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
}
En français:
− attend qu'une impulsion soit à faire
− impose la direction
− met STEP à HIGH
− attend les 1µs par défaut (modifiable)
− met STEP à LOW
Cela fonctionne bien avec un ESP, mais avec une Uno, faire:
− met STEP à HIGH
− met STEP à LOW
ferait déjà une impulsion de 6µs
250kHz en 200*32 micro pas par tour ne fait que 40 tours/s 2350tr/mn) ce qui est peut être possible, les courbes des couples sont souvent données pour 3000tr/mn. J'ai fait tourner un hybride à 1400tr/mn, mais il était très fortement sous alimenté. Mais dans le cas d'un bras, même si on met un réducteur, on n'atteindra pas cette vitesse.
Je confirme
Tellement indétectable qu'au moins Stepper possède un bug à ce sujet et que cela ne gêne que moi! Si le moteur partait en arrière sur un pas, les autres seraient dans le bon sens.
Je l'utilise aussi beaucoup avec une uno car l'échantillonnage peut se mettre sur 16MHz qui est la fréquence du quartz, mais avec une esp32, cela peut aller trop lentement.
Dans le cas présent la broche DIR ne devrait pas changer et devrait rester HIGH. Déjà un simple voltmètre devrait donner une indication. Pour l'instant je penche plutôt à une erreur de câblage, à un fil dupont qui n'assure pas le contact.
C'est assez complexe avec les nouveaux microntroleurs.
Déjà un ESP32 est un micro 32 bits mais il n'est pas sous architecture ARM comme on peut le lire trop souvent. C'est un microcontrôleur Xtensa de la société Tensilica (maintenant acheté par Cadence).
C'est une base de microcontrôleur qui est à terminer par le client.
Dans un micro ARM il y a plusieurs "bridges" d'horloge. Dans un micro ARM à 100 MHz d'horloge les sorties sont au mieux gérées par une horloge moitié, possiblement encore moins.
Je ne connais pas bien les Espressif mais je serai surpris qu'ils soient différents sur ce point, d'ailleurs cela servirait à quoi ?
Les E/S d'un STM32 possèdent 3 modes de fonctionnement : bande passante lente, moyenne, rapide. Que ce soit avec MBed ou Stm32duino, par défaut c'est le mode lent qui est activé. Avoir des fronts de montée du signal trop raides est une source d'ennuis et de consommation excessive.
Un ESP32 tourne sous système d'exploitation FreeRtos.
C'est obligatoire pour pouvoir gérer simultanément et la programmation et le Wifi/Bluetooth.
Avec l'emploi de "yield" qui si j'ai bien compris libère du temps micro pour la deuxième tâche.
Un ESP32 est un microcontrôleur "a terminer" par le client".
Il y a plusieurs façons de le terminer :
en achetant des blocs électroniques "de propriété industrielle" à Cadence comme une interface série, de la PWM, de l'I2C.
en économisant des sous et en faisant la même chose par programmation.
Quand on a vu ce que Cadence a fait d'Eagle à peine acheté, on se dit que ce n'est pas hasard qu'Espressif pour avoir des prix bas a choisi la seconde solution.
La conséquence est qu'il est connu que les fonctions réalisées électroniquement sont plus rapides que celles réalisées par programmation --> voir les limitations de l'interface série supplémentaire réalisé par logiciel sur atmega.
Tout cela pour dire que l'analyseur logique précité a encore de nombreuses années d'utilisation devant lui.
Il ne coûte que 10 €. Les modèles "légèrement" supérieurs sont entre 50 et 100 €.
Alors j'ai testé avec un Voltemètre et j'ai 3.31V sur la broche DIR quelque soit le sens de rotation. Lorsque je coupe le programme avec le bouton EN de l'ESP la tension passe à 0V et ensuite lorsque je le relâche le bouton EN la tension repasse à 3.31V quelque soit le sens de rotation. J'ai également changé les fils et le DIR est bien sur l'INPUT 27 de l'ESP. Demain je vais tester avec un autre ESP32 et un autre DRV8825.