Go Down

Topic: Stacker pour feuille (Read 141 times) previous topic - next topic

Jul17

Bonjour,

Voici la problématique à résoudre, au travail nous venons de recevoir une machine qui éjecte des feuilles à très faible grammage, l'éjection se fait bien pour la première puis ça devient vite l'anarchie car la seconde tombe dessus et ainsi de suite jusqu'à, ce que très vite, l'une d'elle reste debout et provoque un bourrage à la sortie de la machine.

Je souhaiterai donc détecter chaque feuille, les plier grossièrement, les convoyer vers une panière.

Pour ça j'ai prévu, un détecteur d'obstacle, deux servo-moteurs 17g, un moteur PàP (nema 17) avec une carte pilote, deux capteurs de fin de course, et je dispose d'un Uno et d'un Nano.

J'ai fait le montage comme dans l'image en pièce jointe (pas forcément utilisé les mêmes pin, à force de bidouiller...).
J'arrive à faire fonctionner individuellement chaque composant, en gardant la même configuration pour chaque.

Mais lorsque j'assemble le tout pour provoquer les réactions en chaîne ça coince, voici le code :
Code: [Select]
#include <Stepper.h>
#include <Servo.h>

const int stepsPerRevolution = 200;
Servo myservo;           // création de l'objet myservo

Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int pinCapteurObstacle;  // Pin sur lequel est branché le capteur d'obstacle
int pin_servo = 6;       // Pin sur lequel est branché le servo
int position = 45;       // Position souhaitée
int pinCapteurFdC = 7;   // Pin de lecture du contact de fin de course

void setup() {

  Serial.begin(9600);
  pinCapteurObstacle=5; // Pin sur lequel est branché le capteur d'obstacle
  pinMode(pinCapteurObstacle,INPUT);
 
  myservo.attach(pin_servo);  // attache le servo au pin spécifié sur l'objet myservo
  myservo.write(position);    // Place le servo moteur dans la position initiale(45)

  myStepper.setSpeed(60);     // Fixe la vitesse du moteur à 60 rpm

  pinMode (pinCapteurFdC, INPUT); // indique que le capteur de fin de course est une donnée entrante sur le pin 7

}

void loop() {

  boolean etatCapteurObstacle=digitalRead(pinCapteurObstacle);
  Serial.println(etatCapteurObstacle);

  //si le capteur d'obstacle est égal à 1
  if (etatCapteurObstacle) {
    // Fait bouger le bras de 0° à 180°
    for (int position = 0; position <= 90; position++) {
      myservo.write(position);
      delay(15);
    }
 
    // Fait bouger le bras de 180° à 10°
    for (int position = 90; position >= 0; position--) {
      myservo.write(position);
      delay(15);
    }
  }
 
    boolean etatCapteurFdC=digitalRead(pinCapteurFdC);
   
    // Boucle tant que le capteur de fin de course n'est pas touché
    while(etatCapteurFdC != 1){ 
      myStepper.step(-stepsPerRevolution);  // Déclenche le moteur pas à pas jusqu'à ce qu'il touche le capteur

      }
     
}


Comme vous le pouvez le constater il n'y a qu'un seul servo-moteur et un seul capteur de fin de course...deux fois moins de problème pour le moment :smiley-roll:

1er problème : mon capteur d'obstacle, détecte tout de suite quelque chose ce qui lance la suite du code.
2ème problème : mon capteur de fin de course ne réagit pas lorsque je le touche, du coup le moteur pàp tourne indéfiniment.

J'espère que l'un d'entre vous pourra m'aiguiller, merci par avance.

fdufnews

#1
Apr 16, 2019, 10:28 am Last Edit: Apr 16, 2019, 10:28 am by fdufnews
Là, il y a comme un problème
Code: [Select]
    boolean etatCapteurFdC=digitalRead(pinCapteurFdC);
   
    // Boucle tant que le capteur de fin de course n'est pas touché
    while(etatCapteurFdC != 1){
      myStepper.step(-stepsPerRevolution);  // Déclenche le moteur pas à pas jusqu'à ce qu'il touche le capteur

      }
Tu lis l'état du capteur avant d'entrer dans la boucle while mais ensuite tu ne vérifies plus son état. il faudrait relire l'état du capteur systématiquement
Comme ça par exemple
Code: [Select]
// Boucle tant que le capteur de fin de course n'est pas touché
    while(digitalRead(pinCapteurFdC)!= 1){
      myStepper.step(-stepsPerRevolution);  // Déclenche le moteur pas à pas jusqu'à ce qu'il touche le capteur

      }

fdufnews

#2
Apr 16, 2019, 10:32 am Last Edit: Apr 16, 2019, 10:38 am by fdufnews
Pour ton premier problème
1er problème : mon capteur d'obstacle, détecte tout de suite quelque chose ce qui lance la suite du code.
il faudrait s'assurer que le capteur est obstrué pendant un certain temps avant de réagir sinon dès qu'un papier passe tu déclenches.

Ce genre de problématique (en fait l'ensemble de ton besoin) se traite assez bien en utilisant une machine à état. Il y a un tuto sur ce sujet.

Comme vous le pouvez le constater il n'y a qu'un seul servo-moteur et un seul capteur de fin de course...deux fois moins de problème pour le moment
Autant tester chacun des périphériques séparément à du sens, autant coder la moitié du besoin n'en a pas beaucoup car assez vite on s'aperçoit qu'on ne peut pas dupliquer le code et que l'on a pas pris en compte tous les paramètres du problèmes la première fois et il faut tout recommencer. En fin de compte on fait le travail deux fois.
S'il y a besoin de 2 servos et de 2 capteurs il faut l'intégrer dès le début dans l'analyse avant de coder.

PBZOOM

bonjour

Code: [Select]
//si le capteur d'obstacle est égal à 1
  if (etatCapteurObstacle) {


if .........= a ...? ou ==...

la , rien et desuite " {"
 quelle particularité de la variable etatCapteurObstacle
engendre cette accolade ?

dbrion06

etatCapteurObstacle est déclaré comme boolean -> cette construction, concise, est loin d'être choquante

Jul17

#5
Apr 16, 2019, 10:59 am Last Edit: Apr 16, 2019, 11:00 am by Jul17
Merci fdufnews pour tes réponses rapides, je vais corriger ce premier élément et potasser ton lien.

Et je rajouterai les éléments manquants à mon montage, tu as raison !

PBZOOM, alors je sais pas si je réponds à ta question d'après ce que j'ai pu comprendre d'après ce cours c'est comme si tu écrivais :  if (etatCapteurObstacle = 1) {


dbrion06

C'est beaucoup mieux, plus concis et ne fait pas l'hypothèse que vrai logique vaut 1 ....;


en passant, "=" != "=="
et vous auriez du écrire
  if (1== etatCapteurObstacle )
(le compilateur, avec cet ordre, détecte l'omission d'un "=")

Jul17

Oui exact dbrion :smiley-sweat:

J'ai profité de la pause déj pour essayer d'appliquer les conseils de fdufnews.

Voici le code retapé, je peux malheureusement pas le téléverser tout de suite, la compilation se fait correctement, voilà si des yeux avertis veulent bien me dire si ça a une chance de tourner ou si je suis à l'ouest...

Code: [Select]
#include <Stepper.h>
#include <Servo.h>

// On introduit le temps comme évènement supplémentaire
unsigned long chrono; // attention, type unsigned long comme millis()
const unsigned long TimeOut = 1000ul; // 1 seconde (le ul à la fin pour unsigned long)

const int stepsPerRevolution = 200;

Servo myservo_1;           // création de l'objet myservo 1
Servo myservo_2;           // création de l'objet myservo 2

Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int pinCapteurObstacle;    // Pin sur lequel est branché le capteur d'obstacle
int pin_servo_1 = 4;       // Pin sur lequel est branché le servo 1
int pin_servo_2 = 5;       // Pin sur lequel est branché le servo 2
int position = 90;         // Position souhaitée
int pinCapteurFdC_1 = 6;   // Pin de lecture du contact de fin de course 1
int pinCapteurFdC_2 = 7;   // Pin de lecture du contact de fin de course 2

void setup() {

  Serial.begin(9600);
  pinCapteurObstacle=3;              // Pin sur lequel est branché le capteur d'obstacle
  pinMode(pinCapteurObstacle,INPUT);
 
  myservo_1.attach(pin_servo_1);    // attache le servo 1 au pin spécifié sur l'objet myservo
  myservo_1.write(position);        // Place le servo 1 moteur dans la position initiale(45)

  myservo_2.attach(pin_servo_2);   // attache le servo 2 au pin spécifié sur l'objet myservo
  myservo_2.write(position);       // Place le servo 2 moteur dans la position initiale(45)

  myStepper.setSpeed(60);          // Fixe la vitesse du moteur à 60 rpm

  pinMode (pinCapteurFdC_1, INPUT); // indique que le capteur de fin de course est une donnée entrante sur le pin 4
  pinMode (pinCapteurFdC_2, INPUT); // indique que le capteur de fin de course est une donnée entrante sur le pin 5
}

void loop() {

  if (millis() - chrono >= TimeOut) {
    timeOut();
    chrono = millis(); // on ré-arme notre chronomètre
  }

}

void timeOut() {

  boolean etatCapteurObstacle=digitalRead(pinCapteurObstacle);
  Serial.println(etatCapteurObstacle);
 
  if (etatCapteurObstacle) convoyage();   //si le capteur d'obstacle est égal à 1 appelle la fonction convoyage
}

void convoyage() {

    // Fait bouger le servo 1 de 90° à 180°
    for (int position = 90; position <= 180; position++) {
      myservo_1.write(position);
      delay(15);
    }
 
       // Fait bouger le servo 2 de 90° à 0°
    for (int position = 90; position <= 0; position++) {
      myservo_2.write(position);
      delay(15);
    }
 

    // boolean etatCapteurFdC=digitalRead(pinCapteurFdC);
   
    // Boucle tant que le capteur de fin de course n'est pas touché
    while(digitalRead(pinCapteurFdC_1)!= 1){
      myStepper.step(-stepsPerRevolution);  // Déclenche le moteur pas à pas jusqu'à ce qu'il touche le capteur

      }

    // Fait bouger le servo 1 de 180° à 135°
    for (int position = 180; position >= 135; position--) {
      myservo_1.write(position);
      delay(15);
    }

    // Fait bouger le servo 2 de 0° à 180°
    for (int position = 0; position >= 180; position--) {
      myservo_2.write(position);
      delay(15);
    }
      delay(2000); // Patiente le temps que la feuille tombe

    // Fait bouger le servo 1 de 135° à 180°
    for (int position = 135; position >= 180; position--) {
      myservo_1.write(position);
      delay(15);
    }

    // Fait bouger le servo 2 de 180° à 0°
    for (int position = 180; position >= 0; position--) {
      myservo_2.write(position);
      delay(15);
    }
     
    // Boucle tant que le capteur de fin de course n'est pas touché
    while(digitalRead(pinCapteurFdC_2)!= 1){
      myStepper.step(stepsPerRevolution);  // Fait le chemin inverse jusqu'à ce qu'il touche le capteur fdc 2
    }
}


Je trouve pas ça pertinent de déclarer 'etatCapteurObstacle' dans la fonction 'Void timeOut()', dois je le déplacer, où et comment ?

Merci

fdufnews

De manière générale, on déclare les variables là où il y a en besoin.
Si une variable n'est utilisée que dans une fonction alors on la déclare localement à la fonction.
On ne déclare une variable en globale que si elle doit être accessible par plusieurs fonctions.

Jul17


Go Up