Moteur bipolaire PAP 34HS59-5204S

Bonjour , je ne parvient pas à faire fonctionné mon moteur comme je le souhaite.

voici mon projet (professionnel) :
j'ai une étiqueteuse tombé en panne, j'ai changer toute la mécanique et installé un Arduino Méga avec le moteur PAP et un driver "R86 mini". ce moteur est piloter par 2 cellules avec relais.
1- première cellule détecte le produit
2- le moteur démarre et distribue l’étiquette
3- la deuxième cellule détecte le creux étiquette et arrête le moteur.

donc mon code fonctionne comme il faut , sauf pour la partie "Arrêt moteur".
celui-ci fait son tour complet avant qu'il s'arrête , peut importe si la deuxième cellule détecte le creux étiquette, du coup je ne parvient pas à réglé la longueur de mon étiquette.

Voici mon Code complet:

#include <Arduino.h>
#include <Nextion.h>
#include <Stepper.h>
#include <AccelStepper.h>

//Pin des cellules etiquete
const int ETIQON = 7;
const int ETIQOFF = 5;

//Gestion anti-rebond
bool etiqOnStatus = false;
bool etiqOnStatusOld = false;
unsigned long DebutTimer = 0;
unsigned long TimerDelais = 50;

//etat des cellules
int CelulleOn = LOW;
int CelulleOFF = LOW;

//variable utilisé pour le NEXTION
uint32_t numberRE = 0;

//definie les pin moteur et le setp pour le moteur
const int dirPin = 9; //DIR+
const int stepPin = 8; //PULL+
const int NombPas = 6400; //pas moteur - switch parametrer sur le driver sur 1600 STEPS ON/OFF/ON/ON (defaut=6400)
Stepper stepper(NombPas, 8, 9);

//declaration des elements nextion - exemple :( page ID = 0, element ID= 1, name = "b0")
//----SetupEtiquette----

NexText t5 = NexText(1, 8, "t5"); //Resultat valeur retard etiquette
NexSlider retet = NexSlider(1, 5, "retet"); //slider valeur

//registre des boutons
NexTouch *nex_listen_list[] = {
  &retet, NULL
};

//RETET
//Slider retard etiq
void retetPopCallback (void *ptr) {
  char temp[3] = {0};
  retet.getValue(&numberRE);
  utoa(numberRE, temp, 0);
}

void setup(void) {

  Serial.begin(9600);
  Serial2.begin(9600);

  // Nexion
  nexInit();
  retet.attachPop(retetPopCallback, &retet); //slide retard etiquette
  //retet.attachPop(retetPopCallback); //slide retard etiquette

  //vitesse moteur
  stepper.setSpeed(150); // vitesse du moteur en Dur
  //stepper.setSpeed(variant du bouton dans nexion); // vitesse moteur regler via Nexion

  // declaration des pins etiqueteuse
  pinMode(ETIQON, INPUT_PULLUP);  //entrer
  pinMode(ETIQOFF, INPUT); //entrer
  //Serial.println("Cellule initialisé");

  // declaration des pins moteur
  pinMode(dirPin, OUTPUT); // Sortie
  pinMode(stepPin, OUTPUT); // Sortie
}

void loop() {
  CelulleOn = digitalRead(ETIQON);
  nexLoop (nex_listen_list);
  DistribEtiq();
  //Antirebond();
  //Serial.println(&numberRE);
  // Serial.println(retet.getValue (&numberRE));
}

void DistribEtiq () {
  if (CelulleOn == HIGH) {
    do {
      delay (numberRE);
      CelulleOFF = digitalRead(ETIQOFF); // lit l'etat de la cellule off
      //Serial.println("Detection d'un flacon");
      // Faites tourner le moteur pas à pas d'un tour:
      for (int i = 1; i <= NombPas; i++) { // sens horaire
        digitalWrite(dirPin, HIGH);
        stepper.step(1);  // (1) nombre de tour du moteur PAP
        //CelulleOFF = digitalRead(ETIQOFF); // lit l'etat de la cellule off
      }
    }
    while (CelulleOFF == LOW); //arret moteur quand cellule off detecte un creux d'etiquette .
  }
}

void Antirebond(){
  int reading = digitalRead(ETIQON);
  if (reading != etiqOnStatusOld){
    DebutTimer = millis();
  }
  if ((millis() - DebutTimer)>= TimerDelais) {
    if (reading != etiqOnStatus){
      etiqOnStatus = reading;
    }
  }
  etiqOnStatusOld = reading;
}

Merci pour votre aide

Une fois que le moteur tourne, la condition pour l'arrêter est bien CelulleOFF = HIGH, mais il faut d'abord sortir de la boucle for qui fait des tours entiers. C'est d'ailleurs ce qui est en commentaire:
Faites tourner le moteur pas à pas d'un tour". Il y aura que des tours entiers.

Le do while va faire tourner le moteur et il faut en sortir si CelulleOFF = HIGH. Le for ne sert à rien, sauf si on veut s'arrêter après un nombre de tour entier. Pour s'arrêter immédiatement il suffit de retirer le for. Cela peut devenir:

void DistribEtiq () {
  if (CelulleOn == HIGH) {
    do {
      delay (numberRE);
      CelulleOFF = digitalRead(ETIQOFF); // lit l'etat de la cellule off
      //Serial.println("Detection d'un flacon");
      // Faites tourner le moteur pas à pas:
      digitalWrite(dirPin, HIGH);
      stepper.step(1);  // (1) nombre de tour du moteur PAP
      //CelulleOFF = digitalRead(ETIQOFF); // lit l'etat de la cellule off
      }
    }
    while (CelulleOFF == LOW); //arret moteur quand cellule off detecte un creux d'etiquette .
  }
}

Bien entendu il faudra sans doute combiner un peu des deux car lorsque le moteur dmarre, CelulleOFF est HIGH. Donc au démarrage, il faut par exemple faire tourner le moteur de 100 pas avant de tester si CelulleOFF est HIGH ou LOW, ou encore faire tourner le moteur tant que CelulleOFF est HIGH, puis faire tourner le moteur tant que CelulleOFF est LOW.

Bonjour , merci pour t'a réponse je vais regarder sa .

Bonjour , je suit arrivé à faire ce que je voulais.
voici mon code complet :

#include <Arduino.h>
#include <Nextion.h>
#include <Stepper.h>
#include <AccelStepper.h>

//Pin des cellules etiquete
const int ETIQON = 7;
const int ETIQOFF = 5;

//Gestion anti-rebond
bool etiqOnStatus = false;
bool etiqOnStatusOld = false;
unsigned long DebutTimer = 0;
unsigned long TimerDelais = 50;

//etat des cellules
int CelulleOn = LOW;
int CelulleOFF = LOW;

//variable utilisé pour le NEXTION
//uint32_t numberRE = 0; //Variable pour l'arret etiquette
uint32_t VitEtiq = 0; //Variable pour la vitesse etiquette

//definie les pin moteur et le setp pour le moteur
//const int dirPin = 9; //DIR+
//const int stepPin = 8; //PULL+
const int PasRevol = 6400;//pas moteur - switch parametrer sur le driver sur 1600 STEPS ON/OFF/ON/ON (defaut=6400)
Stepper MyMoteur(PasRevol, 9,8);
int StepCount = 0;

//declaration des elements nextion - exemple :( page ID = 0, element ID= 1, name = "b0")
//----SetupEtiquette----
//NexText t5 = NexText(1, 8, "t5"); //Resultat valeur retard etiquette
//NexSlider retet = NexSlider(1, 5, "retet"); //slider valeur
//-----------------------
NexSlider vitet = NexSlider(1, 9, "vitet");

//registre des boutons
NexTouch *nex_listen_list[] = {
  &vitet, NULL
};

//RETET
//Slider retard etiq
//    void retetPopCallback (void *ptr) {
//      char temp[3] = {0};
//      retet.getValue(&numberRE);
//      utoa(numberRE, temp, 0);
//    }

//VITET
//Slider vitesse etiq
    void vitetPopCallback (void *ptr) {
      char temp[3] = {0};
      vitet.getValue(&VitEtiq);
      utoa(VitEtiq, temp, 0);
    }

void setup(void) {

 // Serial.begin(9600); retour moniteur serie
  Serial2.begin(9600);

  // Nexion
  nexInit();
//  retet.attachPop(retetPopCallback, &retet); //slide retard etiquette
  vitet.attachPop(vitetPopCallback, &vitet); //slide vitesse etiquette 

  // declaration des pins etiqueteuse
  pinMode(ETIQON, INPUT_PULLUP);  //entrer
  pinMode(ETIQOFF, INPUT); //entrer
  //Serial.println("Cellule initialisé");

  // declaration des pins moteur
  //pinMode(dirPin, OUTPUT); // Sortie
 //pinMode(stepPin, OUTPUT); // Sortie
}

void loop() {
  CelulleOn = digitalRead(ETIQON);
  nexLoop (nex_listen_list);
  DistribEtiq();
}

void DistribEtiq () {
  if (CelulleOn == HIGH) {
    //delay (numberRE);
    do {
      CelulleOFF = digitalRead(ETIQOFF);      
      //Serial.println("Detection d'un flacon");
      int Speed = VitEtiq; //vitesse moteur (1450)
      int MoteurSpeed = map(Speed, 0, 1023, 0, 100);
      (MoteurSpeed >0);
        MyMoteur.setSpeed(MoteurSpeed);
        MyMoteur.step(PasRevol / 100);      
      }
    //}
    while (CelulleOFF == HIGH); //arret moteur quand cellule off detecte un creux d'etiquette .
    //Serial.println("Arret moteur OFF ");
  }
}

merci pour votre aide. si il y a moyen d'optimiser mieux le code je suit preneur :D.

Il faut spécifier cette bibliothèque dans les .cpp Mais elle est incluse automatiquement dans les ino. Elle est supperflue.

Non utilisée, c'est stepper.h qui est utilisée.

Note: il n'est pas nécessaire d'initialiser une variable. Il se trouve qu'elle est initialisée automatiquement. Perso, j'initialise à LOW une variable pour laquelle c'est important que sa valeur soit connue. En fait ici on mettrait HIGH ce serait pareil.

A priori ce sont deux capteurs équivalents. Pourquoi l'un utiliserait une résistance de pullup interne et l'autre externe? Seul ce point peut être à corriger.

La valeur de CelulleOn on est mise à jour avant. C'est OK. Mais pour plus de clarté, ce serait mieux
de les mettre ensembles, juste l'une derrière l'autre.
Pour une question d'économie de mémoire, je mets plutôt:

if (digitalRead(ETIQON) == HIGH)`

Cela économise deux octets de mémoire et un rangement. Ce n'est pas important si le code est court, mais peut le devenir par la suite. D'ailleurs pour une variable qui ne peut contenir que LOW ou HIGH, autatn la ranger dans un int8_t ou un uint8_t. Cela suffit.

Pourquoi pas:

      int MoteurSpeed = map(VitEtiq, 0, 1023, 0, 100); //vitesse moteur (1450)

J'avoue aussi que le 1450 m'interpelle. C'est VitEtiq qui peut valoir1450?

Pareil que tout à l'heure, autant mette ces deux lignes ensembles (CelulleOFF = digitalRead(ETIQOFF); juste avant le while). Cela change légèrement car en le mettant digitalRead au début, entre le moment ou ETIQOFF passe à LOW et le moment ou le moteur s'arrête, il peut y avoir entre 100 et 200 pas. En mettant digitalRead à la fin (ou dans le while), il y aura entre 0 et 100 pas avant l'arrêt.

Il faut être conscient que le temps qui sépare deux pas entre les 100 pas qui sont ensembles est fixé par MoteurSpeed, mais qu'entre les paquets de 100 pas, le temps est fixe et dépend du temps de la boucle. Il peut donc y avoir des àcoups. Mais je ne crois pas possible de faire autrement avec Stepper.h
Il y a la solution de ne faire qu'un seul pas à la fois et de mettre une temporisation (delay) dans la boucle pour choisir le temps. Mais dans ce cas autant laisser tomber la bibliothèque Stepper.h et envoyer des impulsions directement sur la broche 9.

La fonction DistribEtiq () fait tourner le moteur tant que CelulleOFF est HIGH. Ce n'est pas la peine de refaire le calcul de la vitesse à chaque itération de la boucle. Une seule fois suffit, ce qui ferait par exemple:

void DistribEtiq () {
  if (CelulleOn == HIGH) {
    //delay (numberRE);
    int Speed = VitEtiq; //vitesse moteur (1450)
    int MoteurSpeed = map(Speed, 0, 1023, 0, 100);
    if (MoteurSpeed >0) {
        MyMoteur.setSpeed(MoteurSpeed);
        MyMoteur.step(PasRevol / 100);      
     }
  do {
      //Serial.println("Detection d'un flacon");
      CelulleOFF = digitalRead(ETIQOFF);      
      }
    //}
    while (CelulleOFF == HIGH); //arret moteur quand cellule off detecte un creux d'etiquette .
    //Serial.println("Arret moteur OFF ");
  }
}

Bonjour, Merci Vileroi pour cette réponse très complète , je vais jeter un œil dessus et faire mais modification en fonction.
pour la valeur de 1450 ces ma vitesse par défaut ont va dire.
pour le pinMode, javait oublier effectivement de re-modifier cette ligne.

Merci , Cordialement

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.