Test de mouvement du Servo et arrêt de boucle si réussite

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut tout le monde,

Je reprends mon projet que j'avais mis en pause il y a quelques mois. Je récapitule un peu pour ceux qui ne l'ont pas suivi: j'ai trois moteurs pas à pas (PAP) qui essayent des positions un à un, et un ServoMoteur qui essaye de tourner à chaque combinaison des trois PAP.

Le problème qui se pose aujourd'hui est le suivant :

Ce que je souhaite, c'est : - le ServoMoteur essaye de tourner pendant 1seconde à chaque combinaison des trois PAP, puis si il n'y arrive pas qu'on passe a la combinaison suivante. - Si le ServoMoteur a réussi à tourner (ce qui veut dire que les trois PAP sont sur la bonne combinaison et que le Servo a réussi à tourner la clé) : que tous les moteurs (PAP et Servo) s’arrêtent.

A la base j'avais pensé à un bouton qui serait actionné physiquement en cas de réussite, mais le montage est bringuebalant c'est pas fameux.

Et apparemment si j'ai bien compris le ServoMoteur peut renvoyer la valeur de sa position, donc techniquement je devrait pouvoir lui dire "si tu es en position > à 90°, arrête la boucle (break)" . Sauf que ça ne marche pas :'( En gros j'ai essayé plusieurs bidouillages, soit tout s’arrête dès la première combinaison, soit le servo fait du nimp, soit je ne sais par quel miracle le truc marche mais s'arrète au quand la combinaison des PAP 0 - 1 - 16 (a revérifier) est atteinte…

Donc si vous avez des suggestions, Mesdames, Mesdemoiselles, Messieurs, n'hésitez pas !

Ci dessous le code du ServoMoteur, et sinon le code complet après pour ceux que ça intéresse.

Code Servo uniquement

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Servo myservo;
int pos = 0;
int lectpos = 0;
int chrono = 0;
myservo.attach(0);  // Servo branché sur le PIN 0
lectpos == myservo.read();  // la variable lectpos renvoie la valeur lue de la position du servomoteur
for(pos = 0 , chrono = millis(); pos < 200 || (millis() - chrono) >= 1000 || lectpos >= 90; pos += 180)
                           // test de 0 a 180degrees
            {                                   
                myservo.write(pos);    // va en position de la variable 'pos'
                delay(400);            // 400ms pour rejoindre la position  
                if (lectpos >= 90){break;}    
            }

Code complet

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
#include <stdio.h>
#include <string.h>
#include <Servo.h>
#include <LiquidCrystal.h>


//---------------------------------------Variables Servo moteur
    Servo myservo;
    int pos = 0;
    int lectpos = 0;
    int chrono = 0;


//---------------------------------------Branchements Ecran Lcd
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//---------------------------------------MotorShield
    Adafruit_MotorShield AFMSbot(0x61); // Declaration des deux shields
    Adafruit_MotorShield AFMStop(0x60);

    Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(200, 1);  // Connexion des trois moteurs PAP 200pas par tour
    Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2);  
    Adafruit_StepperMotor *myStepper3 = AFMSbot.getStepper(200, 1);

// Choix de mouvement  DOUBLE INTERLEAVE ou MICROSTEP
    void forwardstep1() {  myStepper1->onestep(FORWARD, SINGLE); }
    void backwardstep1() {  myStepper1->onestep(BACKWARD, SINGLE);}
    void forwardstep2() {  myStepper2->onestep(FORWARD, DOUBLE);}
    void backwardstep2() {  myStepper2->onestep(BACKWARD, DOUBLE);}
    void forwardstep3() {  myStepper3->onestep(FORWARD, INTERLEAVE);}
    void backwardstep3() {    myStepper3->onestep(BACKWARD, INTERLEAVE);}

// Now we'll wrap the 3 steppers in an AccelStepper object (aucune idée de l'utilité...)
    AccelStepper stepper1(forwardstep1, backwardstep1);
    AccelStepper stepper2(forwardstep2, backwardstep2);
    AccelStepper stepper3(forwardstep3, backwardstep3);



void setup()
{  
//-----------------------------Servo
    myservo.attach(0);  // Servo branché sur le PIN 1

//-----------------------------lcd
    lcd.begin(16, 2);   // LCD constitué de deux lignes de 16 caractères


//-----------------------------Shield
    AFMSbot.begin(); // Start the bottom shield
    AFMStop.begin(); // Start the top shield

    stepper1.setMaxSpeed(100.0);
    stepper1.setAcceleration(1000.0);

    stepper2.setMaxSpeed(100.0);
    stepper2.setAcceleration(1000.0);

    stepper3.setMaxSpeed(100.0);
    stepper3.setAcceleration(1000.0);

    lectpos == myservo.read();  // la variable lectpos renvoie la valeur lue de la position du servomoteur

//------------------------------ Boucles de calculs

    int i=-20 , j=0 , k=0 , l=0 , m=-20;    //déclaration des variables de position des moteurs pas à pas
    while ( i < 420 )
        {
        if (lectpos >= 140){break;}
         i += 20 ;
         j = -20;
         while ( j < 420 )
            {
            if (lectpos >= 140){break;}
            j += 20;
            m += 20;
            k = 0;
            while ( k < 420)
               {
                   lcd.clear();
                   stepper1.runToNewPosition(i);
                   stepper2.runToNewPosition(m);
                   stepper3.runToNewPosition(l);
                   lcd.print("M1:"); 
           lcd.print(   (i%400)/20, DEC);
           lcd.print(" M2:");
           lcd.print((m%400)/20, DEC);
           lcd.print(" M3:");
           lcd.print((l%400)/20, DEC);
                   if (lectpos >= 140){break;}


           //----------------------Servo

           for(pos = 0 , chrono = millis(); pos < 200 || (millis() - chrono) >= 1000 || lectpos >= 140; pos += 180)
                           // test de 0 a 180degrees
            {                                   
                myservo.write(pos);    // va en position de la variable 'pos'
                delay(400);            // 400ms pour rejoindre la position  
                if (lectpos >= 140){break;}    
            }

                   k += 20;
                   l += 20;
                   }
        }
    }

}







void loop()
{

//pas de boucle

}

Édité par Coyote

+0 -0
Auteur du sujet

Hello, Mon sujet n'amasse pas foule, aucune idée? J'ai essayé d'ajouter une variable boléenne, qui passe de zéro à un si le servo a réussi à faire le mouvement, et fonction de la valeur de cette variable les boucles s'arrêtent.

Ben ça ne marche pas. En fait j'ai l'impression que le ServoMoteur revient à sa position initiale avant que la fonction myservo.read() ne se fasse, et donc la valeur est toujours la même, même en cas de réussite.

+0 -0

Cette réponse a aidé l'auteur du sujet

Bon me revoila devant un ordinateur, je peux ptet aider…

Attention, j'ai lu vraiment en diagonale, si ca se trouve tu sais deja tout ca et je sers a rien.

On va couper court aux speculation : un servo analogique classique ne propose pas de retour d'information sur sa position. Ensuite, la fonction read() renvoi juste la derniere valeur envoyee avec write, donc ne sert a rien ou presque.

Bref, il faut bien un capteur pour determiner ta position.

ZdS, le best du Zeste ! Tuto Arduino, blog, etc

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte