faire tourner un moteur pas a pas unipolaire de plus de 300 steps. Pb de variabl

Bonjour à tous

Je fabrique pour mon plaisir personnel une horloge avec un mouvement planetaire et j’ai choisi de la faire tourner avec un moteur pas à pas unipolaire ( de la recup de scanner) et d’un driver uln2003. le tout controlé par wemos d1 minipro. Le montage fonctionne, le moteur tourne, mais pas comme je le voudrait !
J’utilise la bibliothèque stepper.h

Si j’upload le programme d’exemple stepper one revolution qu’on trouve dans la bibliothèque stepper, pas de soucis

Si j’envoie le programme modifié pour qu’il tourne non pas de 200 step mais de 500, ca ne fonctionne plus ( il fonctionne 5 sec puis s’arrête et reprend à nouveau

Si j’envoie le programme ci dessous : mème constat

#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 5, 4, 0, 2);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()  {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  for (long compteur = 0; compteur < 1000; compteur++)
  {
    myStepper.step(1);// code à exécuter
  }

Si je ne met que le code ci dessous dans le loop, le moteur fonctionne correctement en continu.

myStepper.step(1)

Je suppose donc que c’est un problème de variable, ( j’avais remplacé le int par long , mais ca n’a rien changé) . Pouvez vous m’apporter une solution pour que je puisse envoyer plus de 256 ( je suppose ?) steps au moteur.
J’espère avoir été clair dans les descriptions de mon problème

Cordialement Olivier

Merci d’avance

bonsoir olitask

Si j'envoie le programme modifié pour qu'il tourne non pas de 200 step mais de 500, ca ne fonctionne plus ( il fonctionne 5 sec puis s'arrête et reprend à nouveau

ce dois être normal!!!

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

utilise google trad pour la phrase en commentaire..tu devrais comprendre!

void loop()  {
 
    myStepper.step(1);// code à exécuter

je ne connais pas la bibliothèque stepper spécialement, mais a vue de nez, je dirais que là il tourne parce que tu lui "envoi" un seul pas par loop!

Bon courage à toi!

Je n'ai pas touché à la line const int stepperrevolution=200

Mais il y est fait reference plus loin dans le sketch https://www.arduino.cc/en/Tutorial/StepperOneRevolution

On fait tourner le moteur dans un sens puis dans l'autre de ce stepperrevolution. C'est dans la loop que j'ai enlevé ce stepperrevoluktion pour le remplacer par 500. Et du coup ca ne fonctionne plus

Olivier

void loop()  {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  for (long compteur = 0; compteur < 1000; compteur++)
  {
    myStepper.step(1);// code à exécuter
  }

Loop est une boucle, for en est une autre. Ce que fait ce programme:
Il écrit clockwise, ce qui lui prend 10 ms.
il fait 1000 pas (soit 5 tours)
et il recommence indéfiniment

Si il s’arrête c’est le temps d’écrire

Un des problèmes c’est qu’on s’occupe aussi de faire autre chose que la gestion seule du moteur, et que le multitâche n’existe pas et que cela prend du temps. et pendant ce temps, le moteur s’arrête. En général, le moteur ne va pas tourner sans arrêt dans le même sens.

A priori, la boucle for devrait pouvoir s’écrire simplement myStepper.step(1000);

C’est dans la loop que j’ai enlevé ce stepperrevoluktion pour le remplacer par 500

la, faut voir le code correspondant.

olitask

const int stepperrevolution= X;

Je dirais que, là, tu dois définir le nombres de pas de ton moteur!

(tu ne dis pas combien de pas a ton moteur, la valeur 200, je suppose que c'est par défaut!!)

Je pense qu'il ne faut pas confondre, le fait d'envoyer des impulsions pour faire tourner ton moteur (genre d'instruction comme celle là: myStepper.step(1 ou mille) ), et le nombre de pas qu'il faut connaitre pour que ton moteur fasse un tour!!

On fait tourner le moteur dans un sens puis dans l'autre de ce stepperrevolution. C'est dans la loop que j'ai enlevé ce stepperrevoluktion pour le remplacer par 500. Et du coup ca ne fonctionne plus

const, c'est parce que c'est une propriété constante et intrinsèque a ton moteur, donc forcement, si ailleur dans ton programme la même variable déclarée constante ce met a changer, effectivement il y a des chances qui ai un truc qui apprécie pas!

truc a pars, je suis intrigué par cette partie:

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 5, 4, 0, 2);

c'est tes pins c'est cà?? si tu les changes, ba la aussi, je connais pas de tête, mais ci ta pas les sorties PWM!!aie!

Apres comme dis vileroi, sans voir le prog complet, c'est un peut compliquer de voir ou ça coince!!

bon courage!

2terium:
c'est tes pins c'est cà?? si tu les changes, ba la aussi, je connais pas de tête, mais ci ta pas les sorties PWM!!aie!

Pas de PWM avec cette librairie. Les sorties sont pilotées directement.
Par contre il manque un paramètre à l'initialisation c'est la vitesse. Il faut la définir avec setSpeed().
Dans l'exemple de la librairie on demande d'avancer d'un certain nombre de pas mais on place un delay() derrière donc le moteur a le temps de rallier sa position.
Avec ta boucle for, c'est différent. les commandes arrivent en rafale et le moteur n'a pas le temps d'avancer.
Cette librairie n'est pas très évoluée. Pour l'utiliser il faut faire ainsi:
A l'initialisation

  • on crée une instance de Stepper

  • on défini les paramètres par défaut

  • le nombre de pas par tour

  • la vitesse par défaut (important car je ne vois pas de valeur par défaut pour ce paramètre dans la librairie)

Dans le programme

  • on modifie, si besoin, la vitesse
  • on donne un nombre de pas à effectuer

ATTENTION: la méthode step() est bloquante si tu donnes un nombre de pas important alors que la vitesse est faible ton code va être bloqué. Et les ESP8266 ou ESP32 n'aiment pas être bloqués, cela fait claquer un watchdog et génère un reset.
Dans documentation de la librairie il est suggéré dans ce cas de mettre une vitesse élevée et de gérer la vitesse dans le code de l'application

Fdufnews

salut, je ne savais pas! merci pour l'info PWM,

par contre il l'a mis l'initialisation myStepper.setSpeed(60);

Bonjour

Alors je le fais tourner sur un wemos esp8266 et fdufnews a peut être trouvé mon problème: Le but est de faire tourner une horloge et la première des choses est qu'elle se règle à la bonne heure . Pour ca j'ai besoin de faire tourner le moteur d'un grand nombre de pas : jusqu'à 20 000( j'ai mis beaucoup d'engrenages) .

En fait, tout va bien tant que je ne dépasse pas les environ 4-5 sec . Sinon l'esp plante et reboot. Moi je cherche comment lui envoyer beaucoup de pas d'un coup sans que ca plante. En plus, à vitesse élevée, le moteur rate des pas ...

Faire une boucle de 2000 * 10 pas ou faire 20000 pas d'un coup prendra un temps sensiblement égal.
L'avantage de la première solution c'est que tu peux faire un yield() après le step() à chaque itération de la boucle pour faire tourner l'OS sous-jacent et ainsi relancer le watchdog.

Bonsoir

Problème résolu, l'ESP n'aime pas la librairie stepper qui est bloquante. J'utilise maintenant la librairie Unistep2 qui fonctionne comme un charme.

Bon il me reste un autre problème à regler qui fait planter l'esp...

Merci à tous

Bonsoir.
Je m’arrache un peu les cheveux avec mon programme. Ça fonctionne dans les grandes lignes, mais le calibrage ne se fait pas ou mal. L’esp plante sur cette partie ( void calibrate() ) située à la fin du setup{}

Une grande partie de ce programme est disponible sur instructable.org, mais il est prévu pour un arduino “classique” et une RTC . Je l’avais modifié dans un premier temps pour un esp8266+ PAP bipolaire12Volt ( programme fonctionnel), puis à nouveau pour esp + PAP unipolaire 5Volt.

PS: 1 minute sur l’horloge correspond à ~ 130 steps
PS2 : Je n’utilise pas de sonde Hall, mais un bête bouton NO

/*wemos mini d1 pro
  pin  TX  RX  D1  D2  D3  D4  D5  D6   D7   D8 
  GPIO 1   3   5   4   0   2   14  12   13   15

*/


#if defined ARDUINO_ARCH_ESP8266  // s'il s'agit d'un ESP8266
#include <ESP8266WiFi.h>
#elif defined ARDUINO_ARCH_ESP32  // s'il s'agit d'un ESP32
#include "WiFi.h"
#endif

#include <WiFiUdp.h>
#include <NTPClient.h>
#include <TimeLib.h>
const long utcOffsetInSeconds = 7200;  //heure hiver-ete
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "fr.pool.ntp.org", utcOffsetInSeconds);
unsigned long derniereDemande = millis(); // moment de la plus récente demande au serveur NTP
unsigned long derniereMaJ = millis(); // moment de la plus récente mise à jour de l'affichage de l'heure
const int delaiDemande = 10 * 60; // nombre de secondes entre deux demandes consécutives au serveur NTP
unsigned long clock_time ;        //datetime varable to store the current position of the clock's arms
unsigned long rtc_time ;
unsigned long seconds ;
unsigned long steps = 0 ;
int dir = 1;


#include <Unistep2.h>
// for your motor
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// initialize the stepper library on pins D1 à D4 sur wemos:
Unistep2 stepperX(5, 4, 0, 2, stepsPerRevolution, 1500);
#define Sec_per_step 0.465     //ammount of seconds per step (change this for different ratios between stepper and minute hand)
#define Hall_pin 12          //pin for the hall effect sensor signal

int etat;
const char* ssid = "BoxWifi";
const char* password = "123456789";

void setup() {
  Serial.begin(9600);
  delay(100);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connexion au reseau WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }
  delay(100);

  stepperX.run();
  pinMode(Hall_pin, INPUT_PULLUP);
  timeClient.begin();
  delay(100);
  timeClient.update();
  calibrate();

}

void loop() {
  stepperX.run();
  rtc_time = (timeClient.getHours() * 60 + timeClient.getMinutes()) * 60;


  // est-ce le moment de demander l'heure NTP?
  if ((millis() - derniereDemande) >=  delaiDemande * 1000 ) {
    timeClient.update();
    derniereDemande = millis();

    Serial.println("Interrogation du serveur NTP");
  }

  // est-ce que millis() a débordé?
  if (millis() < derniereDemande ) {
    timeClient.update();
    derniereDemande = millis();
  }

  // est-ce le moment de raffraichir la date indiquée?
  if ((millis() - derniereMaJ) >=   5000 ) {

    afficheHeure();
    calc_steps();                       // use this void to calculate if, and how many steps are neccecary, result is stored in the variable "steps"
    if (steps != 0)                     // only if a step is neccecary this part of the code is used
    {
      Serial.print("steps:");
      Serial.println(steps);
      move_stepper();
    }


    derniereMaJ = millis();
  }

}


//================================================================================================================
void afficheHeure() {
  Serial.print(timeClient.getHours());
  Serial.print(":");
  Serial.print(timeClient.getMinutes());
  Serial.print("   -:");
  Serial.println(rtc_time);

}

//=============================================================================================================================

void calibrate()
{
  //This void matches the physical time of the hands with the time the RTC prescibes.
  //After a power down the Arduino does not know where the hands of the clock are
  //Therefore we use the hall effect sensor to detect when the hands are at a certain time
  //after this we move from this known time to the actual time we want to display

  while (digitalRead(Hall_pin) == HIGH)                         // while we have not reached the hall effect sensor
  {
    stepperX.move(100 * dir);
  }
  Serial.println("Position found, moving back");
  delay(500);
  stepperX.move(-300 * dir);                             // move back a litte bit to compensate for overshoot of fast movement
  delay(500);
  Serial.println("Calibrating-Slow Mode......");
  while (digitalRead(Hall_pin) == HIGH)                         // while we have not reached the hall effect sensor
  {
    stepperX.move(100 * dir);
    delay(300);
  }
  delay(1000);                                          // delay to give the user a chance to read the time

  //======================================
  //The next line sets the time at which the hands stop moving after hall effect sensor detection
  //in my case this is 5:49 or 17:49 (doesnt matter), change this accordingly
  clock_time = (6 * 60 + 1) * 60 ;   // Set the position of the arms (Year, Month, Day, Hour, minute, second) Year, Month and day are not important
  //======================================

}

//====================================================================================================================================
void calc_steps()
{
  seconds = (rtc_time - clock_time);       //calculate the difference between where the arms are and where they should be


  if (seconds > 43200)                        // we have an analog clock so it only displays 12 hours, if we need to turn 16 hours for example we can better turn 4 hours because its the same
  {
    seconds = seconds - 43200;
  }

  if (seconds > 21600)                        // if the difference is bigger than 6 hours its better to turn backwards
  {
    seconds = seconds - 43200;
  }
  steps = steps + (seconds / Sec_per_step);   //convert the seconds to steps
}


//====================================================================================================================================
void move_stepper()
{
  stepperX.move(dir * steps);           //tell the motor how many steps are needed and in which direction
  clock_time = rtc_time;                //since the steps will be made by the motor we can assume the position of the arms is equal to the new position
  steps = 0;
}

Olivier

Dans cette librairie, c'est l'exécution de run() qui fait avancer le moteur. SI tu n'appelles pas run() très régulierement dans ta boucle le moteur ne bouge pas.
Dans calibrate() tu as plusieurs boucles et plusieurs appels à move() sans appel à run().
Il faudrait revoir cette partie de code pour en faire une machine à états qui bouclerait en appelant run() à chaque itération de la boucle
Changer de librairie en cours de route c'est souvent s'ajouter des complications.