Go Down

Topic: asservissement de position (Read 8906 times) previous topic - next topic

B83s

#15
Mar 31, 2015, 05:43 pm Last Edit: Mar 31, 2015, 06:08 pm by B83s
Bon...

Tu déclares mesure_brute ( et consigne aussi) avant le setup (ce sera une variable globale,visible partout dans ton programme)
setup()
 mesure_brute = analogRead...  //lecture de l'accelerometre
 Angle = a x mesure_brute + b  // calcul de l'angle initial
 Consigne = angle //on fixe la consigne = angle initial de sorte que le moteur ne bouge pas au démarrage

Loop()
...

Stephanois57

Désolé, je ne suis pas beaucoup expérimenté en Arduino (c'est le moins qu'on puisse dire effectivement !)

D'accord, maintenant c'est plus clair ! Je comprends mieux ce que le programme est censé faire comme tu ceci.
Mais angle = -0.651*mesure_brute+329 je devrais pas le déclarer avant le setup aussi ? Arduino risque de me le rejeter sinon ?

B83s

#17
Mar 31, 2015, 08:43 pm Last Edit: Mar 31, 2015, 08:48 pm by B83s
La c'est un problème  de langage informatique ... En l'occurrence de langage C ... Arduino n'y est pour rien ... Il faudrait que tu trouves des cours sur les bases du C

Déclares angle aussi avant le setup ... Comme ça tu es tranquille.

Juste une précision, car je pense qu'on est pas sur la même longueur d'onde ... Quand tu écris  int angle = -0.651*mesures + 329
Tu fais deux choses en même temps (c'est autorisé) : tu déclares une variable de type int qui s'appelle angle, et tu lui donnes comme valeur le résultat de la formule mathématique (au moment où ton programme exécute cette ligne)
On est bien d'accord qu'en déclarant angle de la sorte, il n'est pas lié en permanence avec mesure_brute ... Autrement dit si mesure_brute change de valeur, ta variable angle ne changera pas de valeur automatiquement... A chaque fois que tu lis une mesure_brute, il faut appliquer la formule mathématique pour calculer la nouvelle valeur de angle ... Ok ?
 

Stephanois57

Mais mon angle je peux le déclarer en int au dessus du setup quand même ?

Oui oui, c'est mon mesure_brute qui influe sur la valeur de angle. Mais alors du coup là, si je comprends ce que tu me dis, ma variable angle ne change jamais de valeur ?
Parce que pour moi le "angle" venait chercher la valeur de mesure_brute, et l'introduisait dans l'équation mathématique pour m'en sortir une valeur de mon angle, et avant que je modifie le programme, quand je ne m'occupais pas de consigne encore, mon moteur tournait bien en fonction de la valeur de mon angle.

B83s

Dans ton premier programme, dans le loop, tu calculais l'angle avec la formule mathématique ... Ce n'est pas angle qui va chercher mesure_brute ... Les variables ne sont pas liées par une formule mathématique, même si a la déclaration tu mets une formule (c'est le résultat de la formule qui est affecté à la variable, pas la formule mathématique elle même !)

Si tu fais
Int a=1
Int c = a+ 2 // a vaut 1 et donc c vaudra 3 apres cette ligne
a = 2           // a vaut 2 maintenant mais c vaut toujours 3 !
a = 3           // a vaut 3 et c vaut toujours 3
c = 99         // a vaut 3 et c vaut 99 ...

On est d'accord ???

Ton programme
// déclaration des variables (pas besoin de leur affecter des valeurs ... )
Int angle;
Int mesure_ brute;
Int consigne;

Setup()
  Pinmode....
  Mesure_brute = analogRead(voie0);          // lecture de la position initiale
  Angle = 0.615* mesure_brute +329;         // calcul de l'angle initial
  Consigne = angle;                                    // consigne init

Loop()
  Mesure_brute = analogRead...          // lecture de la position actuelle
  Angle = 0.615* mesure_brute +329 // calcul de l'angle actuel
  If (blabla)...
  If (blabla)...

Si tu ne refais pas le calcul d'angle dans le loop (comme tu le faisais dans ton tout premier programme) il ne va pas se calculer tout seul par magie





 
 


Stephanois57

D'accord, donc oui, moi j'avais dans l'idée que c'était la formule mathématiques qui était affectée à ma variable, j'avais compris la chose à contre courant !

Donc j'ai fait comme tu m'as dit, je pense que ça doit être juste…
Code: [Select]

int E1 = 5;
int M1 = 4;
const int I1 = 2;
const int I2 = 3;

const int Voie_0=0;
int mesure_brute;
int consigne;
int angle;


void setup()
{
    pinMode(M1, OUTPUT); 
    pinMode(I1, INPUT);
    pinMode(I2, INPUT);
    Serial.begin(115200);
   
    mesure_brute=analogRead(Voie_0); // info de l'accéléromètre // lecture position initiale
    angle=0.615*mesure_brute+329;
    consigne=angle;
    //Serial.println(angle); // afficher à la ligne l'angle
     //delay(1000);
   
   
   
} // fin du setup



void loop()
{
 

  int value1 = digitalRead(I1);
  int value2 = digitalRead(I2);
  mesure_brute=analogRead(Voie_0); // position actuelle
  angle=0.615*mesure_brute+329; // calcul angle actuel

 if (value1==1)
  {
    digitalWrite(M1, HIGH);
    consigne=angle ;
    Serial.println("value1==1");
   }
 
 else if (value2==1)
 {
    digitalWrite(M1, LOW);
    consigne=angle;
    Serial.println("value2==1");
  }


 else
 {
 if (angle>consigne)
 {
   digitalWrite(M1, HIGH);
   Serial.println("HIGH");
 }
 else
 {
   digitalWrite(M1, LOW);
   Serial.println("LOW");
  }
 analogWrite(E1,50);
  }
 delay(200);
  }
 


Si tu me dis que mon programme parait bon, je vais essayer d'aller récupérer le moteur demain pour pouvoir le tester ce week-end avec le programme, et je te tiendrai informé !

Merci pour ta patience, et pour toutes les explications très claires !

Stephanois57

Bonjour,

J'ai essayé le programme, il à l'air de fonctionner. Cependant, quand la valeur de mon angle atteint ma valeur de consigne, comment faire pour dire au moteur de s'arrêter ?

B83s

#22
Apr 05, 2015, 09:05 pm Last Edit: Apr 05, 2015, 09:13 pm by B83s
Ben la il va falloir réfléchir un peu !

Poser tous les cas de figure sur une feuille et les traduire en programme ensuite ... Sans oublier de cas, comme par exemple si angle=consigne ...

Peut être que angle=consigne est un peu trop juste et que ton moteur va osciller autour de la position car tu n'auras jamais çette egalit stricte ... il faudra donc peut être mettre une zone morte autour de la consigne ... Ou ralentir le moteur quand on s'approche de la consigne ...

raccourci le delay(200) pour voir comment ton système réagit ...

C'est en forgeant qu'on devient forgeron ...

Stephanois57

J'ai bien testé le programme ce matin, et je vais te dire ce qu'il fait exactement :
-Je branche mon arduino au PC, je téléverse le programme sur la carte, le moteur se met à tourner
-J'actionne dans un sens ou dans l'autre mon inverse, le moniteur série me marque value1==1 ou value2==1 en fonction de la sortie actionnée de mon inverseur, ainsi que la valeur de l'angle, et mon moteur tourne dans un sens ou dans l'autre
-Je remet la position centrale de l'inverseur, le moniteur série marque alors HIGH ou LOW, comme prévu, et si je fais bouger mon accéléromètre, dès que je vais dépasser ma valeur de consigne (j'ai vérifié), mon moteur va se mettre à tourner dans l'autre sens.

Maintenant ce que je n'arrive pas me représente sous forme de programme, c'est comment stabiliser la rotation de mon moteur autour de ma valeur de consigne ? Comme tu dis une zone morte serait sans doute bien ( par zone morte moi je veux dire, quelques degrés au-dessus, et quelques degrés en-dessous de ma valeur de consigne, toi aussi ?).

Prenons un exemple concret, ma consigne vaut 30, et quand la valeur de angle vaut entre 25 et 35 par exemple, il faudrait que mon moteur s'arrête. Je ne vois pas comment traduire ça en langage arduino ?

(si tu veux des photos, ou des captures d'écran du moniteur série pour mieux comprendre, dis-moi le)

B83s

J'imagine que analogWrite(E1,50); te sers a faire varier la vitesse du moteur ... Je te laisse trouver la valeur qui va l'arrêter ...

Apres pour les différents cas de fonctionnement ... Ce n'est vraiment pas compliqué et je ne vais pas écrire le programme à ta place ...

La principe est
Si angle >consigne-5 et angle < consigne+5
     Arrêter le moteur
Sinon si angle > consigne+5
      Tourner dans le sens x
Sinon si angle < consigne-5
      Tourner dans le sens y

Ce n'est pas tres compliqué à traduire en langage C

Stephanois57

Oui analogWrite(E1,50) sert a faire varier la vitesse de mon moteur, je peux aller de 0 à 255.

Oui je sais que analogWrite(E1,0) ne ferra pas tourner mon moteur, mais j'avais fait quelque chose comme :
if (consigne=angle)
   analogWrite(E1,0)
mais ça n'avait pas fonctionner, enfin je vais réessayer d'autres possibilités.

Ah d'accord on peut faire simple comme ça, je croyais qu'il fallait que je passe par une histoire de pourcentage ou des choses comme ça. Je me complique la vie.

Par contre ton "Si angle >consigne-5 et angle < consigne+5", on ne peut pas l'écrire comme ceci ?
if (angle >consigns-5) and (angle < consigne+5)
   analogWrite(E1,0)

B83s

Ce serait trop simple ... Mais tu n'es pas loin...

Regardes dans la section référence du site ... Et tu trouveras

Stephanois57

#27
Apr 09, 2015, 01:28 pm Last Edit: Apr 09, 2015, 01:40 pm by Stephanois57
Je n'ai pas trouvé comment faire un encadrement, j'ai juste trouvé les "<=" et autres semblables.
Pourrais-tu me donner la méthode s'il te plait ?
Par exemple comment traduire :

Si A inférieur à B+5 et A supérieur à B-5 ?

Faut-il mettre 2 "if" l'un en dessous de l'autre ? J'avais vu une histoire avec "&&" mais ca ne veut pas me le compiler donc ca ne doit pas être comme cela.

unisev

...J'avais vu une histoire avec "&&" mais ca ne veut pas me le compiler donc ca ne doit pas être comme cela.
Si si, pour moi c'est bien ça !
EN: Libraries are my Gurus, they make me believe anything they want !
FR: Les librairies sont mes gourous, elles me font croire ce qu'elles veulent !

B83s

attention aux parenthèses ...

if (angle > consigne-5 && angle < consigne+5)

Go Up