probleme avec ma classe

servo moteurs qui ne fonctionnent pas

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

Bonjour à tous. Je viens quérir votre aide pour mon programme Arduino avec le quelle j'ai un problème, n'arrivant pas à faire fonctionner mes servos moteurs.

En faisant des codes tout simples j'ai pu constater que mes servos moteurs fonctionnent, et donc en déduire que le problème vient de mon code, mais je n'arrive pas à déterminer pourquoi.

Je vous joins ma classe robot et son header :

  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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include "robot.h"
#include <Arduino.h>
#include <Servo.h>






robot::robot(): pinCapteurDroit(2), pinCapteurGauche(3) //constructeur
{
    moteurDroit = new moteur(4, 5);
    moteurGauche = new moteur(7,6);  // on allou les moteurs



    pinMode(pinCapteurGauche, INPUT); // on passe nos pins en mode entree
    pinMode(pinCapteurDroit, INPUT);

    roueFolle = new Servo();
    roueFolle->attach(9);
    triangle = new Servo();  // on allou les servos moteurs et leur donne le bon port
    triangle->attach(10);

}

robot::~robot() //destructeur
{
    delete moteurGauche;   //on désallou les pointeurs sur les moteurs pour liberer la mémoire
    delete moteurDroit;
    delete roueFolle;
    delete triangle;
}


void robot::faireDemitour()  //tant que le capteur droit ne detecte pas la bande blanche, on tourne à droite, puis on tourne jusqu'a ce que le capteur gauche la detecte aussi
{
    while(pinCapteurDroit == NOIR)
    {
        tourner(DROIT);
    }
    while(pinCapteurGauche == NOIR )
    {
        tourner(DROIT);
    }


}



void robot::testCapteurs(int choix, int temps)  // fonction qui permet de controler la sortie des capteurs, 1 pour le capteur droit 2 pour le capteur droit et 3 pour les deux capteurs en meme temps, le 2eme argument et le temps entre chaque information
{

    switch (choix)
    {
    case 1 :
        {
            if(couleurCapteurGauche == NOIR)
                Serial.println("noir");
                else
                  Serial.println("blanc");
            delay(temps);
            break;
        }
    case 2 :
        {
            if(couleurCapteurDroit == NOIR)
                Serial.println("noir");
            else
                  Serial.println("blanc");
            delay(temps);
            break;
        }
    case 3 :
        {
                if(couleurCapteurGauche == NOIR)
                    Serial.println(" capteur gauche : noir");
                else
                    Serial.println(" capteur gauche : blanc");


                if(couleurCapteurDroit == NOIR)
                    Serial.println(" capteur droit : noir");
                else
                    Serial.println(" capteur droit : blanc");
            delay(temps);
            break;

        }
    }


}

 void robot::accelerer(int vitesse) // methode pour accelerer
{
    moteurDroit->accelerer(vitesse);
    moteurGauche->accelerer(vitesse);

}


void robot::testMoteur(int choix)  // on test les moteurs du robot : 1 = moteur gauche, 2 = moteur droit, 3 = les deux moteurs
{
    switch(choix)
    {
    case 1:
        {
            moteurGauche->test(); //appelle de la fonction test du moteur droit
            break;
        }
    case 2:
        {
            moteurDroit->test(); //appelle de la fonction test du moteur gauche
            break;
        }
    case 3:  // cette fois on recreer la fonction de test pour faire tourner les deux en meme temps
        {
            int i =0;
            for(i =0; i <255;i++)
            {
                analogWrite(moteurGauche->getPinTension(), i);
                analogWrite(moteurDroit->getPinTension(), i);
                delay(25);
            }

            for(i =254; i >1;i--)
            {
                analogWrite(moteurGauche->getPinTension(), i);
                analogWrite(moteurDroit->getPinTension(), i);
                delay(25);
            }
            break;
        }
    }

}




void robot::tourner(int direction)  //fonction pour tourner, 1 = à gauche et 2 = à droite
{
    if(direction == DROIT)
    {
        Serial.println(" on tourne à droite ");
        roueFolle->write(45);
    }

    else
        Serial.println(" on tourne à gauche ");
        roueFolle->write(45);
}



void robot::bougerTriangle(int niveau)
{
    if(niveau ==1)
        triangle->write(90);
    else
        triangle->write(0);

}

void robot::corrigerTrajectoire()  // methode qui sera appelé pour corriger la trajectoire
{
    if(couleurCapteurDroit == BLANC) //si le capteur droit detecte une bande blanche
    {

        tourner(DROIT);  // on tourne donc à droite
    }
    else if (couleurCapteurGauche == BLANC)
    {

        tourner(GAUCHE); // et réciproquement à gauche si le capteur gauche mord la ligne blanche
    }


}


void robot::actualiserCapteur() //methode qui permet d'actualiser les valeurs des capteurs penses à rigoler ducon !
{
  couleurCapteurGauche = digitalRead(pinCapteurGauche);
   couleurCapteurDroit = digitalRead(pinCapteurDroit);
}





void robot::testServomoteur()
{



}

et voici le header :

 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
#ifndef ROBOT // protection contre l'inclusion multiple
#define ROBOT

#include "moteur.h"
#include <Servo.h>



class robot
{
private :
    moteur *moteurGauche;
    moteur *moteurDroit;   // pointeur de type moteur, pour pouvoir les controller
    Servo *roueFolle;
    Servo *triangle;        // pointeurs de type servo moteurs pour nos servos moteurs
    int pinCapteurGauche;
    int pinCapteurDroit;  // les pins ou nos capteurs sont connectés
    int couleurCapteurGauche;
    int couleurCapteurDroit;


public :
    robot();  // constructeur
    ~robot();  // destructeur
    void tourner(int direction);  // methode qui sert à tourner 1 pour à gauche, 2 pour tourner à droite
    void bougerTriangle(int niveau);  // methode qui sert à monter ou baisser le triangle 1 pour le monter, 2 pour descendre
    void corrigerTrajectoire(); //methode qui fait tourner quand un capteur montre qu'on coupe la ligne blanche
    void testCapteurs(int choix, int temps); // fonction qui permet de controler la sortie des capteurs, 1 pour le capteur droit 2 pour le capteur droit et 3 pour les deux capteurs en meme temps, le 2eme argument determine le delay entre deux infos, attention ! necessite la communication avec le port serie !!!!
    void faireDemitour(); // fonction pour faire demi tour
    void actualiserCapteur();

    //methode des moteurs
    void testMoteur(int choix); // on test les moteurs du robot : 1 = moteur gauche, 2 = moteur droit, 3 = les deux moteurs
    void accelerer(int vitesse);  // methode qui sert à accelerer

    //methode des servos moteurs eux aussi ils y ont le droit roh mais ho !
    void testServomoteur();

};

enum{BLANC, NOIR};
enum{USELESS, GAUCHE, DROIT, DEUX};



#endif
+0 -0

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

as-tu un main.ino? ou au mois la paire de fonctions

1
void setup()  

et

1
void loop()

?

pour ton servo roueFolle, quelque soit la direction ou tu veux aller (gauche ou droite), tu indique le même angle : 45° (et tu oublie des crochets)

1
2
3
4
5
6
7
8
9
if(direction == DROIT)
    {
        Serial.println(" on tourne à droite ");
        roueFolle->write(45);
    }

    else
        Serial.println(" on tourne à gauche ");
        roueFolle->write(45);

tu devrais plus faire quelque chose tel que

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
if(direction == DROIT)
    {
        Serial.println(" on tourne à droite ");
        roueFolle->write(45);
    }
    else if(direction == GAUCHE)
    {
        Serial.println(" on tourne à gauche ");
        roueFolle->write(135);
    }
    else
    {
        Serial.println(" tout droit ");
        roueFolle->write(90);
    }
+1 -0

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

Lu'!

Pourquoi tu te casses le cul avec des allocations dynamiques ?

  • en C++, on ne fait pas ça manuellement, on passe au minimum par une classe RAIIsante
  • ici, tu n'en as littéralement pas besoin puisque ceci suffit :
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
robot::robot(): 
  moteurGauche(7,6),
  moteurDroit(4, 5),
  pinCapteurDroit(2), 
  pinCapteurGauche(3)
{
    pinMode(pinCapteurGauche, INPUT); // on passe nos pins en mode entree
    pinMode(pinCapteurDroit, INPUT);
    roueFolle.attach(9);
    triangle.attach(10);
}
//avec 
class robot
{
private :
    moteur moteurGauche;
    moteur moteurDroit;   // pointeur de type moteur, pour pouvoir les controller
    Servo roueFolle;
    Servo triangle;
//...

Tu devrais rendre ton moteur non-copiable, ça évitera tout risque de copie fortuite qui provoquerait des catastrophes (pareil pour tes éléments de Robot à mon avis).

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+1 -0
Auteur du sujet

bonjour, tout d'abord merci de vos réponses et l'attention que vous apportez à ma requette. alors dans l'ordre de vos remarques :

voici mon testPOO.ino que je n'avais pas donné tout simplement car il est presque vide pour l'instant (PS puisqu'on en parle, suis-je obligé de déclarer mon objet triangleAuto en tant que variable global si je veux y avoir acces dans la fonction loop ? il n'existe pas de fonction main ou semblable ? on m'a toujours dit d'éviter les variables global au maximum) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <Arduino.h>
#include "robot.h"


robot triangleAuto; // on instanci notre robot avec la classe robot


void setup()
{
    Serial.begin(9600);// on demarre un flux pour communiquer avec le PC




}

void loop()
{
    triangleAuto.testCapteurs(3, 800);



}

pour ce qui est du meme angle, j'avou que pour l'instant c'est des valeurs arbitraires je voulais vérifier que le robot marche avant d'y coller les valeurs du model mathématique qu'on a calculé. En revanche vous me dites que j'ai oublié des crochets, je ne comprends pas. Mais votre façon d'aborder les choses, en prenant en compte le fait d'aller tout droit me plais, je vais tenter cela.

Enfin pour ce qui est des remarques sur les allocations dynamiques, ba vous avez entièrement raison simplement que j'ai appris à allouer dynamiquement les objets que je créer dans un autre.

Enfin vous me proposer de rendre mes moteurs non copiables, je ne sais pas faire cela, à quelle risques je m'expose en ne les rendant pas copiables ?

Édité par Armion

+0 -0

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

Enfin pour ce qui est des remarques sur les allocations dynamiques, ba vous avez entièrement raison simplement que j'ai appris à allouer dynamiquement les objets que je créer dans un autre.

Armion

Sauve toi la vie et limite l'usage de l'allocation dynamique explicite lorsqu'elle est nécessaire (pas souvent) et l'allocation/désallocation dynamique manuelle aussi (c'est à dire approximativement jamais en C++).

Enfin vous me proposer de rendre mes moteurs non copiables, je ne sais pas faire cela, à quelle risques je m'expose en ne les rendant pas copiables ?

Armion

Assez simple à faire :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//C++11/14 :
class Machin{
private:
  Machin(Machin const&) = delete;
  Machin& operator=(Machin const&) = delete;
};

//C++03 et inférieur:
class Machin{
private:
  Machin(Machin const&){
    assert(false && "you shalt not call this");
  }
  Machin& operator=(Machin const&){
    assert(false && "you shalt not call this");
    return *this;
  }
};

Pour ce qui est des problèmes que ça peut provoquer globalement ce serait tout ce qui peut se passer quand on a des partages non-voulus suite à une copie qui a eu lieu à un endroit où l'on aurait oublié une référence ou quelque chose comme ça. Dans le cas où l'on promène des pointeurs on peut vite avoir de désagréable surprises (double-free).

Après si ton moteur n'est qu'une valeur, tu peux aussi simplement te contenter de le garder ainsi, c'est juste qu'il faut que tu gardes en tête ce qui se passe lorsque tu le copies et quelle relation tu as entre l'objet d'origine et sa copie.

Après pour ce qui est de ton problème actuel, je pense que c'est plus dû à la partie Arduino et je ne sais pas manipuler ces machins ;) .

Édité par Ksass`Peuk

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+1 -0

@Ksass'Peuk : Je plussoie, je trouve ça plus explicite. Par contre, je n'ai pas compris : pourquoi tu as écrit shalt au lieu de shall ? C'est plus explicite ? :)

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+0 -0

En fait j'aurai même dû écrire "Thou Shalt not …". C'est de l'anglais ancien châtié. C'est une expression qui exprime un peu le commandement religieux :lol: . ((Mais je pense qu'il faut arrêter les HS et trouver des gens qui savent bien jouer avec Arduino)).

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+0 -0
Auteur du sujet

J'ai fini par résoudre contourner mon probleme, en fait il semblerait que la methode attach de la classe Servo ne puisse etre appellé que depuis la fonction setup. J'ai donc creer une methode attacherServo pour ma classe robot que j'appelle dans le setup et qui fait appelle à cette method attach. Merci de votre aide.

+0 -0

Je reviens loin, mais avec arduino, main() n'existe pas, donc pas besoin de s'en servir.

Si tu utilise des variables dans ton setup(), ou dans ton loop(), il faut les déclarer en global, donc en dehors de toute fonction, car sinon, elle pourrons être réinitialisées à chaque tour de boucle.

Enfin, Arduino, comme tout micro-controlleur, n'a pas beaucoup de mémoire (ou plutôt très peu), donc, lorsque l'on code pour ces systèmes, on essaye de limiter cet usage au maximum. Ainsi, on utilise, par exemple, une variable globale, plutôt que de passer des pointeurs (qu'on risque d'oublier de désallouer à la fin au passage) ou des variables qui prennent plus de place en mémoire, on utilise le char pour stocker des nombre, et pas uniquement des caractères,…

Bref, Que des petites optimisations de code qui limite grandement la quantité de mémoire utilisée.

N.B. Et tant mieux pour toi si tu as trouvé la solution de ton problème

+0 -0

H.S (mais pas totalement) : Même sur une plateforme incompatible C++11, il faut implémenter ses propres capsules RAII. Donc l'argument "qu'on risque d'oublier de désallouer" n'a pas de sens en C++.

Édité par mehdidou99

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+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