Moteur pas à pas

Bonsoir les Arduinistes!

Question : j'aimerais faire tourner précisément un moteur pàp d'un tour par seconde. J'avoue, j'y arrive pas. J'ai beau jouer avec le stepsPerRevolution et rolePerMinute, j'ai pas vraiment le résultat voulu.

Le moteur est connecté à un ULN2003A (voir schéma Proteus joint). Peut être l'ai-je mal connecté?
Je l'ai déclaré sur ces PIN là Stepper myStepper(stepsPerRevolution, 8, 10,9,11).

Y'a t il une formule simple pour faire cela?

Thanks to all

Capture.PNG

Votre image
Capture.PNG

Postez votre code (avec les balises)

Sinon avez vous regardé la librairie AccelStepper et la méthode setspeed() ?

Hello

donc voici le code

en gros, je suis en train de fabriquer une sorte de porte automatique pour poulailler
en fonction du jour et de la nuit et j'aimerais, avec un bouton, faire tourner un stepper
d'un tour tout le temps que le bouton est appuyé (j'aimerais en fait enregistrer une
durée d'enroulement pour connaitre le timing pendant lequel je dois faire tourner la poulie pour ouvrir/fermer la porte, histoire de pas utiliser de capteur d'ouverture et fermeture comme ça ce système pourrait s'adapter sur porte coulissante comme sur porte de type pont-levis)

// Poulomatique
// 30/04/2019

// declaration PIN capteur de lumiere LDR
int LDR1 = 0;
// declaration librairie pour le moteur (stepper)
#include <Stepper.h>

// déclaration variable pour le moteur (stepper)
const int stepsPerRevolution = 1;  // change this to fit the number of steps per revolution
const int rolePerMinute = 60;         // Adjustable range of 28BYJ-48 stepper is 0~17 rpm
// declaration des PIN pour le moteur
Stepper myStepper(stepsPerRevolution, 8, 10,9,11);

// declaration des variables
int ValLDR1 = 0;
int ValLDR1Moins5 = 0;
int SeuilN = 10;
int DureeF = 5000;
int DureeE = 0;  // variable utilisée pour calculer le temps d'enroulement ou déroulement
int InstantT=0;
char EtatPorte = 'O';
boolean AppuiB1 = false;
boolean AppuiB2 = false;
boolean DebutDecompteDureeF = false;
unsigned long DepartTimer;



void setup () {

  // ouverture du port serie pour capturer des infos
  Serial.begin(9600);
  
  // configuration des paramètres du moteur
  myStepper.setSpeed(rolePerMinute);

  /* parametrage du mode de declenchement (changement d etat du pin 2)
    RISING = detection d un etat bas a l etat haut
    premier parametre a 0 signifie port 2 donc bouton B1 */
  attachInterrupt(0, AppuiBouton1, RISING);

  /* parametrage du mode de declenchement (changement d etat du pin 3)
    CHANGE = changement d'etat haut vers bas ou bas vers haut
    premier parametre à 1 signifie port 3 donc bouton B2 */
  attachInterrupt(1, AppuiBouton2, CHANGE);

}

void AppuiBouton1() {
  AppuiB1 = true;
}

void AppuiBouton2() {
  if (AppuiB2 == true) {
    AppuiB2 = false;
    EtatPorte = 'F';

  }
  else if (AppuiB2 == false) {
    AppuiB2 = true;
    DureeF = millis();
    DebutDecompteDureeF = true;
    Serial.println("Fermeture porte");
    myStepper.step(stepsPerRevolution);

  }
}

void Debobinage() {
  DureeE = millis();
  InstantT = millis();
  while ((InstantT - DureeE) < DureeF) {
  myStepper.step(-stepsPerRevolution);
  InstantT=millis();
  }
  Serial.println("Porte fermee");
  EtatPorte = 'F';
}

void Embobinage() {
  DureeE = millis();
  InstantT = millis();
  while ((InstantT - DureeE) <= DureeF) {
 myStepper.step(stepsPerRevolution);
  InstantT=millis();
  }
  Serial.println("Porte ouverte");
  EtatPorte = 'O';
}

void loop() {

  ValLDR1Moins5 = ValLDR1;
  ValLDR1 = analogRead(LDR1);

    if (ValLDR1 < SeuilN && ValLDR1Moins5 < SeuilN && EtatPorte == 'O' && AppuiB2 == false) {
      Serial.println("Debobinage");
      Debobinage();
    }

    if (ValLDR1 > SeuilN && ValLDR1Moins5 > SeuilN && EtatPorte == 'F' && AppuiB2 == false) {
      Serial.println("Embobinage");
      Embobinage();
    }

  DepartTimer = millis();
  while ((millis() - DepartTimer) <= 6000) {
    if (AppuiB1 == true) {
  Serial.print("Enregistrement nouveau seuil");Serial.println(SeuilN);
      SeuilN = analogRead(LDR1);
      AppuiB1 = false;
    }
    if (AppuiB2 == false) {
      if (DebutDecompteDureeF == true) {
        DureeF = millis() - DureeF;
        DebutDecompteDureeF = false;
        Serial.print("Duree bobinage = "); Serial.println(DureeF);
      }
    }
  }
}

personne n'a eu la même réflexion? vraiment?

Question : j'aimerais faire tourner précisément un moteur pàp d'un tour par seconde. J'avoue, j'y arrive pas. J'ai beau jouer avec le stepsPerRevolution et rolePerMinute, j'ai pas vraiment le résultat voulu.

La présence de deux boutons est en contradiction avec ceci :

j'aimerais, avec un bouton, faire tourner un stepper d'un tour tout le temps que le bouton est appuyé

Quelle est la question ?
Elle concerne la vitesse ? les boutons ?

Cela manque de clarté.
Comment sont câblés les boutons ? et sur quelles broches ?
Y a t-il des pullups ?
Je soupçonne 2 et 3 mais confirmer serait bien.

Tout d'abord merci pour la réponse

Ensuite, j'ai 2 boutons mais parlons d'un seul, le deuxieme sert juste à relever un seuil de luminosité, pour determiner le moment d'ouverture ou fermeture de la porte.
Maintenant, l'autre bouton : la porte du poulaillier sera levée ou descendu par une poulie (soit en coulissant, soit en mode "pont-levis" mais peut importe, avec une poulie et un fil). J'aimerais donc, pour que ce système soit adaptable à toutes longueurs de portes, qu'avec un appuie long, on simule une ouverture de porte (ou fermeture peut importe) pour ainsi enregistrer le temps necessaire à cette ouverture (ou fermeture). Avec cette durée enregistrée, je pourrais, dès le seuil de luminosité atteint, ouvrir ou fermer la porte en déroulant ou enroulant la poulie pendant la durée relevée.
Je souhaite donc juste un peu mieux maitriser la gestion du moteur pàp, j'aimerais par exemple envoyer une impulsion d'un tour par seconde au moteur tout le temps que le bouton sera appuyé.
Est ce plus claire?

Et merci par avance.

Suivant qu'il va faire chaud ou froid, sec ou humide, .....
La porte va descendre plus ou moins vite, du coup la mesure du temps ne sera pas valable et la porte sera partiellement ouverte ou fermée.

Les contacts fin de course permettent justement de garantir la position de la porte quelques soient les conditions.

je vais devoir me résoudre à utiliser des contacteurs de fin de course... je voulais éviter car le but final c'est d'équiper plusieurs personnes, d'avoir un montage simple à mettre en place, sans mon assistance, juste poser une porte et une poulie, là il faudra positionner assez précisement les contacteurs mais le gros avantage en effet c'est qu'il n'y'a pas de timing à prendre en compte, que même si le moteur met plus de temps ça ne sera pas un probleme et surement d'autres aspects.

Merci du conseil et vive l'arduino!

@fdufnews

Tu penses qu'un moteur PAP va subir les effets de la température ?

j'essaierais de lui imprimer un beau boitier bien rembouré et bien étanche pour passer l'hivers :wink:

Bonjour,

Il faut peut-être revoir la conception de ta porte pour coller au plus près de ton cahier des charges.

Switch, cellule à fourche ou par réflexion , mesure du courant dans le moteur, tige filetée inox...

Une bonne conception permet de faciliter la mise en place et le réglage du montage,
Et avec une documentation adaptée et bien imagée, un novice en bricolage devrait pouvoir d'en sortir :wink:

Avec un moteur pap c’est pas le temps d’ouverture qu’il faut mesurer mais le nombre de pas. C’est immuable.

Si tu veux un truc simple et sans fin de course: moteur DC avec mesure du courant, quand la porte arrive en butée, le moteur va consommer 7 à 10 fois son courant nominal, soit le courant de blocage => fin de course logicielle

hbachetti:
@fdufnews

Tu penses qu'un moteur PAP va subir les effets de la température ?

Pas le moteur, la porte.
Si elle arc-boute un peu, si des cochonnerie la coince plus ou moins elle ne va pas monter à la même vitesse.
La descente, je suppose qu'elle se fait par gravité et donc elle est encore plus susceptible aux aléas.

Jambe:
Avec un moteur pap c’est pas le temps d’ouverture qu’il faut mesurer mais le nombre de pas. C’est immuable.

Non ce n'est immuable que si le moteur ne bloque pas auquel cas on saute des pas.
Ou alors il faut avoir un couple de bourrin au risque de casser quelque chose.
Quelques exemple: à la descente, la porte se bloque les pas se déroulent.
Le câble se détend et sort de la poulie.
A la remontée, le cable est à coté de la poulie il coince.....

Ok on parle plutôt de défaillance que je n’exclue pas.
On est dans une boucle ouverte, il n’y a pas de contrôle effectif de la bonne manœuvre de la porte. Il faut faire sans

Voici la trappe que j'ai réalisé.. des fer en u, un verin 12v
Le verin gere ses fin de butée
Ca marche depuis 5 mois sans soucis
Si besoin d'explications.. demande.
Le verin m'a coûté une trentaine d'euro sur ebay ou ali

Merci à tous pour vos reflexions, en effet le verin semble une bonne idée.
J'avais commencé avec un moteur DC, beaucoup plus simple à mettre en place, mais je pense que ce type de moteur n'a pas assez de couple pour le cas, par exemple parmi pleins d'autres cas possibles, d'une poule qui serait sur la porte lors de la fermeture (en mode pont levis), ou autre gêne lors de la remontée de la porte. Le moteur PAP semblait donc plus approprié si besoin de forcer un peu.

Je vais revoir un peu mon projet. Je pense devoir utiliser des contacteurs, un en haut côté exterieur de la porte qui fera contact avec le sol lors de la fermeture, et un sur le montant qui sera donc actionné lorsque la porte sera fermée.

Mais j'ai toujours pas la réponse à la question de départ :wink:
Pour ma culture personnelle, j'aimerais savoir gérer un moteur PAP et savoir faire un tour par seconde. Y'a t il une formule de calcul simple à mettre en place dans le code?

Merci à tous pour vos réponses, top ce groupe...

Cedrik76:
Mais j'ai toujours pas la réponse à la question de départ :wink:
Pour ma culture personnelle, j'aimerais savoir gérer un moteur PAP et savoir faire un tour par seconde. Y'a t il une formule de calcul simple à mettre en place dans le code?

il faudrait connaître le nombre de pas pour faire un tour complet, si vous avez un driver etc.

la formule pour savoir quand faire un front pour faire un pas en microseconde serait:
((1000000UL/(PAS_PAR_TOUR * MICROPAS_PAR_PAS)) /TOURS_PAR_SECONDE)

codes tapés ici, non testés

Si vous voulez le faire "à la main" avec un driver qui supporte des micros-pas (genre EasyDriver) et que vous avez disons 200 pas par tours et 8 micro-pas pour faire un pas, un code comme cela devrait fonctionner

#define STEP_PIN          9     // la pin pour faire un pas sur le driver
#define DIRECTION_PIN     8     // la pin de direction sur le driver
#define PAS_PAR_TOUR      200   // nombre de pas pour un tour complet
#define MICROPAS_PAR_PAS 8     // nombre de micros pas en 1 pas pour le driver
#define TOURS_PAR_SECONDE 1     // le nombre de tours par seconde souhaités

#define MICROSECONDS_PAR_MICROPAS  ((1000000UL/(PAS_PAR_TOUR * MICROPAS_PAR_PAS)) /TOURS_PAR_SECONDE)

uint32_t tempsPrecedent = 0;

void setup() {
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIRECTION_PIN, OUTPUT);
  digitalWrite(STEP_PIN, LOW);
  digitalWrite(DIRECTION_PIN, LOW);
}

void loop() {
  uint32_t maintenant = micros();
  if ((maintenant - tempsPrecedent) >= MICROSECONDS_PAR_MICROPAS)
  {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(2); // suivant les drivers il faut au moins 1μs pour l'impulsion, on met 2
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(2); // suivant les drivers il faut au moins 1μs pour l'impulsion, on met 2
    tempsPrecedent += MICROSECONDS_PAR_MICROPAS;
  }

  // ici vous pouvez faire autre chose si ça ne prend pas trop longtemps
}

ensuite, la librairie accelStepper peut ensuite vous simplifier la vie

#include <AccelStepper.h>
#define STEP_PIN        9
#define DIRECTION_PIN   8
#define PAS_PAR_TOUR    200   // nombre de pas pour un tour complet

AccelStepper monMoteurPaP(AccelStepper::DRIVER, STEP_PIN, DIRECTION_PIN);

void setup()
{
  monMoteurPaP.setMaxSpeed(5 * PAS_PAR_TOUR); // vitesse max en pas par seconde ici 5 tour / s
  monMoteurPaP.setSpeed(PAS_PAR_TOUR);	    // vitesse constante désirée en pas par seconde ici 1 tour / s
}

void loop()
{
  monMoteurPaP.runSpeed(); // pas d'accélération ni décélération
  // ici vous pouvez faire autre chose si ça ne prend pas trop longtemps
}

Bonjour

Mon moteur est le suivant, j'ai un peu de mal à interpréter les informations.
Apparemment c'est le "stride angle" qui pourrait me permettre de déterminer le nombre de pas par tour?

Votre image

il semble que ce soit un un moteur pas à pas à 4 phases 28-BYJ48 très commun.

vous a-t-il été fourni avec son contrôleur ULN2003 ?
ctrl.png

(on trouve le système complet par 5 pour pas très cher même en france)

si vous regardez celui de Adafruit il disent "Small Reduction Stepper Motor - 12VDC 32-Step 1/16 Gearing" --> donc 32 x 16 = 512 pas pour faire un tour (en fait dans leur doc ils expliquent que c'est plutôt 513).

--> pour le votre vous savez que le Stride Angle est 64, il faudrait savoir quel est le ratio de "gearing" pour connaitre réellement le nombre de pas par tour. s'il n'y a rien de particulier ce sera 64 ticks mais il peut y avoir une adaptation dans une boîte de démultiplication, x64 par exemple, auquel cas il faudrai 64x64=4096 ticks pour faire un tour

--> envoyez 64 ticks et regardez s'il a fait un tour ou pas

ctrl.png

tout a fait! je l'ai accouplé au ULN2003A, c'est fourni dans le kit starter d'elegoo (très bon kit pour découvrir cet univers infini qu'est l'arduino d'ailleurs!)

mais bon, avant la réalisation, je test tout en virtuel sur Proteus pour ne pas griller mes composants, donc bon.... je sais pas si ça simule bien...