Arduino Forum

International => Français => Topic started by: Stephanois57 on Mar 27, 2015, 08:43 pm

Title: asservissement de position
Post by: Stephanois57 on Mar 27, 2015, 08:43 pm
Bonjour à tous,

Je fais un projet sur un asservissement de position, et pour cela j'utilise un accéléromètre et un moteur à courant continu. J'utilise également un inverseur 3 positions (ON OFF ON) qui me permet de donner ma consigne.

J'ai réussit à faire un programme qui marche bien, je vous le mets ici :
Code: [Select]

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

const int Voie_0=0;
int mesure_brute=0;


void setup()
{
    pinMode(M1, OUTPUT);  
    pinMode(I1, INPUT);
    pinMode(I2, INPUT);
    
    Serial.begin(115200);
    
} // fin du setup





void loop()
{


  //int value1 = digitalRead(I1);
  //int value2 = digitalRead(I2);
  mesure_brute=analogRead(Voie_0);
  //Serial.println(mesure_brute);
  int angle = -0.651*mesure_brute+329;
  Serial.println(angle); // afficher à la ligne l'angle

  //delay(1000);
 
  
 if (angle<0)
 {
    digitalWrite(M1, HIGH);
    Serial.println("HIGH");
    
  }


 if (angle>0)
 {
   digitalWrite(M1, LOW);
   Serial.println("LOW");
 }
 
 
 analogWrite(E1,50);
 
  }
  
  
  


Cependant, ce programme ne prend pas en compte ma consigne. Mon but dans ce projet et d'arriver à maintenir une position angulaire (l'équation "angle = -0.651*mesure_brute+329" me donne l'angle, et le fait très bien, le problème n'est pas là). En fait je voudrais à l'aide de mon inverseur donner une consigne, c'est-à-dire faire tourner mon moteur jusqu'à une position voulue (mon moteur étant relié à une "planche" où est fixé dessus l'accéléromètre, donc je veux conserver la mesure de l'angle donnée par l'accéléromètre). J'ai donc essayé de modifier mon programme pour arriver à cela, mais le moteur "bourre" quand je téléverse le programme dans mon arduino (uno).

Quelqu'un saurait-il comment faire le bon programme ? Je vous laisse un schéma pour illustrer la situation, ainsi que le programme "modifié".

Code: [Select]

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

const int Voie_0=0;
int mesure_brute=0;


void setup()
{
    pinMode(M1, OUTPUT);  
    pinMode(I1, INPUT);
    pinMode(I2, INPUT);
    
    Serial.begin(115200);
    
} // fin du setup





void loop()
{
 while (I1==1 or I2==1)
  mesure_brute=analogRead(Voie_0);
  int consigne = -0.651*mesure_brute+329;


  //int value1 = digitalRead(I1);
  //int value2 = digitalRead(I2);
  mesure_brute=analogRead(Voie_0);
  //Serial.println(mesure_brute);
  int angle = -0.651*mesure_brute+329;
  Serial.println(angle); // afficher à la ligne l'angle

  //delay(1000);
 
  
 if (angle<consigne)
 {
    digitalWrite(M1, HIGH);
    Serial.println("HIGH");
    
  }


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


Merci de votre réponse, et bonne soirée à tous !
Title: Re: asservissement de position
Post by: infobarquee on Mar 28, 2015, 12:09 pm
bonjour,
je sais pas ou est passée ma réponse, donc je me retape le tout.

Code: [Select]
  int consigne = -0.651*mesure_brute+329;
et
Code: [Select]
  int angle = -0.651*mesure_brute+329;
sont identiques, comment veux tu qu'un soit supèrieur  ou inférieur à l'autre?

après comment veux tu que ceci soit valable?
Code: [Select]
while (I1==1 or I2==1)
tu déclare avant
Code: [Select]
const int I1 = 2;
const int I2 = 3;

sans modifié leur valeur après avec un Read vu qu'ils sont en INPUT
donc tes conditions ne sont jamais bonnes

Title: Re: asservissement de position
Post by: Stephanois57 on Mar 28, 2015, 04:04 pm
Bonjour,

Pour mon "int consigne" et "int angle" c'est vrai que ça ne peut pas marcher… Mais alors comment définir ma consigne ? Parce que dans mon programme je n'ai qu'une seule équation qui me donne mon angle.

I1 et I2 sont les sorties de mon inverseur. Pour moi (je dis bien "pour moi" car ce n'est sans doute pas comme ça qu'il faut penser) quand je dis I1==1 par exemple, c'est que ma sortie de l'inverseur I1 est au niveau logique 1, donc qu'elle est actionnée. Je voulais donc me servir de ce "1" en question, pour que mon programme sache ce qui me permet de donner ma consigne, en l'occurrence quand I1 ou I2 est actionné.

Merci beaucoup pour ton aide !
Title: Re: asservissement de position
Post by: vohu on Mar 28, 2015, 05:08 pm
Ce qu'il veut dire c'est que ces 2 variables ne sont jamais modifiées.

tu devrais alors décommenter :
Code: [Select]
 //int value1 = digitalRead(I1);
  //int value2 = digitalRead(I2);


Et faire un test
Code: [Select]
value1==1 or value2==1
Title: Re: asservissement de position
Post by: B83s on Mar 28, 2015, 06:53 pm
Pour le réglage de la consigne ... Si j'ai bien compris ton inverseur on off on te sert à faire tourner le moteur (dans un sens ou dans l'autre) pour régler ta consigne et la position neutre est celle où le moteur doit conserver la consigne ?

Si c'est ça, la règle est assez facile : quand le bouton est sur on, tu fais bouger ton moteur et tu mesures ton angle et tu affectes sa valeur a la consigne
Quand tu remets ton inter sur off, tu mesures ton angle et tu le compares a la consigne

Loop
 Valeur1 = digitalRead...
 Valeur2 = digitalRead...
 Angle = ....
 If valeur1==1
     Tourne moteur sens 1
     Consigne = angle
Else if valeur2==1
     Tourne moteur sens2
     Consigne =angle
Else
     If angle > consigne
         Tourne moteur sens 1
     Else
         Tourne moteur sens 2
Fin du loop
   
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 28, 2015, 07:58 pm
Bonsoir,

Oui c'est exactement cela que je cherche à faire.

Par contre, dans ce schéma du programme à suivre que tu viens de me donner, comment et où dois-je déclarer mon "consigne" ?
Title: Re: asservissement de position
Post by: B83s on Mar 28, 2015, 08:07 pm
Déclares consigne avant le setup comme ça sa valeur sera visible dans tous le programme
Au départ elle vaudra par defaut 0 ... A toi de voir si ça te convient
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 28, 2015, 08:42 pm
Mais il y a une chose que je ne comprends pas : il faut que je déclare consigne et angle ? Pour déclarer mon angle, je vais faire "int angle = -0.651*mesure_brute+329" mais pour ma consigne, je mets quoi ? Je peux pas remettre la même équation ?   
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 29, 2015, 07:12 pm
Je viens d'essayer de modifier mon programme, mais comme je n'ai pas le moteur sous la main, je ne peux pas vérifier s'il marche. Je suis toujours perplexe sur la façon dont j'ai posé "consigne"... Je le poste ici, et pourrais-tu me dire ce que tu en penses ? (en tout cas, au niveau "écriture du programme" il est bon, puisque Arduino le vérifie parfaitement)

Code: [Select]

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

const int Voie_0=0;
int mesure_brute=0;
int consigne = -0.651*mesure_brute+329;


void setup()
{
    pinMode(M1, OUTPUT); 
    pinMode(I1, INPUT);
    pinMode(I2, INPUT);
   
    Serial.begin(115200);
   
} // fin du setup



void loop()
{
 
 

  int value1 = digitalRead(I1);
  int value2 = digitalRead(I2);
  mesure_brute=analogRead(Voie_0); // info de l'accéléromètre
  //Serial.println(mesure_brute);
  int angle = -0.651*mesure_brute+329;
  Serial.println(angle); // afficher à la ligne l'angle

  //delay(1000);

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


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


Merci à tous pour l'aide !
Title: Re: asservissement de position
Post by: B83s on Mar 29, 2015, 08:54 pm
Pour l'initialisation c'est bon ... Tu pourrais aussi dans le setup lire la valeur de mesures brutes ( comme tu le fais dans le loop) et initialiser la valeur de la consigne avec cette mesure ... Ainsi ton moteur ne bougera pas au démarrage (angle mesuré au départ = consigne)

Dans le loop quand tu écris consigne==angle, tu n'auras pas le résultat que tu attends ... Je te laisse réfléchir un peu

J'ajouterai des Serial.print dans les différents tests du loop pour vérifier que ton programme passe bien là où il faut et je mettrai un petit delay(200)  à la fin du loop pour le calmer

Si tu n'as pas de moteur tu mets des serial.print ...

Au niveau câblage du moteur tu fais comment ? Car je ne vois pas comment tu inverses son sens de rotation
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 30, 2015, 07:08 pm
Je n'ai pas très bien compris l'histoire du mesure brute…

C'était consigne=angle du coup ?

Code: [Select]

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

const int Voie_0=0;
int mesure_brute=0;
int consigne = -0.651*mesure_brute+329;


void setup()
{
    pinMode(M1, OUTPUT); 
    pinMode(I1, INPUT);
    pinMode(I2, INPUT);
   
   
    Serial.begin(115200);
   
} // fin du setup



void loop()
{
 
 

  int value1 = digitalRead(I1);
  int value2 = digitalRead(I2);
  mesure_brute=analogRead(Voie_0); // info de l'accéléromètre
  //Serial.println(mesure_brute);
  int angle = -0.651*mesure_brute+329;
  Serial.println(angle); // afficher à la ligne l'angle

  //delay(1000);

 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);
  }
 
 


Le câblage c'est le même que j'ai mis dans la pièce jointe, j'ai relié mes 2 sorties de mon inverseur sur le 2 et 3 de l'arduino, puis j'ai relié mon moteur sur un shield L298P. Je sais pas si je suis assez clair ?
Title: Re: asservissement de position
Post by: B83s on Mar 30, 2015, 08:27 pm
Autant pour moi, je n'avais pas vu le schéma du moteur ...

Au démarrage du programme tu as le choix entre :
1: (Ce que tu as fait) initialiser la valeur de mesure_brute à zero, et calculer la consigne qui en decoule avec la formule ... Donc au démarrage ton moteur va tourner pour atteindre cette consigne

2: Soit dans le setup, tu fais mesure_brute = analogRead(Voie0), tu calcules l'angle correspondant, et tu initialises ta consigne avec cet angle... Du coup au démarrage ton moteur ne bouge pas et reste dans sa position initiale ...

L'un comme l'autre fonctionne .. C'est juste 2 façons de débuter le programme

Et oui, consigne=angle c'est mieux ...
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 30, 2015, 08:58 pm
Quote
2: Soit dans le setup, tu fais mesure_brute = analogRead(Voie0), tu calcules l'angle correspondant, et tu initialises ta consigne avec cet angle... Du coup au démarrage ton moteur ne bouge pas et reste dans sa position initiale ...
--> Donc si je fais ça, au démarrage mon moteur ne tournera pas car il sera déjà dans une position "pré-réglée" ? Je ne vois pas trop comment calculer l'angle correspondant ?
Title: Re: asservissement de position
Post by: B83s on Mar 30, 2015, 09:57 pm
 :o ... Tu n'as qu'une seule formule à utiliser pour convertir la mesure brute de ton accéléromètre en valeur d'angle ! Et c'est toujours la même et tu l'utilises déjà dans ton programme ...ou alors c'est moi qui ne comprends rien ...
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 31, 2015, 04:37 pm
Non non la formule je sais que c'est toujours la même, ce n'est pas ça que je ne comprends pas. Je ne vois juste pas comment mon programme saura quelle est ma valeur de départ si je mets le mesure_brute dans le setup ?
Title: Re: asservissement de position
Post by: B83s on Mar 31, 2015, 05:43 pm
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()
...
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 31, 2015, 07:24 pm
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 ?
Title: Re: asservissement de position
Post by: B83s on Mar 31, 2015, 08:43 pm
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 ?
 
Title: Re: asservissement de position
Post by: Stephanois57 on Mar 31, 2015, 09:21 pm
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.
Title: Re: asservissement de position
Post by: B83s on Mar 31, 2015, 10:11 pm
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





 
 

Title: Re: asservissement de position
Post by: Stephanois57 on Apr 01, 2015, 02:01 pm
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 !
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 05, 2015, 06:12 pm
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 ?
Title: Re: asservissement de position
Post by: B83s on Apr 05, 2015, 09:05 pm
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 ...
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 06, 2015, 10:52 am
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)
Title: Re: asservissement de position
Post by: B83s on Apr 06, 2015, 07:14 pm
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
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 06, 2015, 09:47 pm
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)
Title: Re: asservissement de position
Post by: B83s on Apr 06, 2015, 10:06 pm
Ce serait trop simple ... Mais tu n'es pas loin...

Regardes dans la section référence du site ... Et tu trouveras
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 09, 2015, 01:28 pm
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.
Title: Re: asservissement de position
Post by: unisev on Apr 09, 2015, 03:18 pm
...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 !
Title: Re: asservissement de position
Post by: B83s on Apr 09, 2015, 03:44 pm
attention aux parenthèses ...

if (angle > consigne-5 && angle < consigne+5)
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 09, 2015, 06:54 pm
Je viens de réessayer et effectivement ça marche comme ça, je ne sais pas ce que j'avais fait de mal avant. Merci !

J'ai une question : ça ne pose pas de problème si dans mon loop (à la fin du loop) je donne une vitesse à mon moteur, mais si avant, toujours dans le loop je mets un if avec dedans un vitesse nulle du moteur ?
Title: Re: asservissement de position
Post by: B83s on Apr 09, 2015, 08:32 pm
Quote
ai une question : ça ne pose pas de problème si dans mon loop (à la fin du loop) je donne une vitesse à mon moteur, mais si avant, toujours dans le loop je mets un if avec dedans un vitesse nulle du moteur ?
Euh ... tu peux répéter ( reformuler) ta question ? Ou mettre ton dernier code parce que la ce n'est pas facile à suivre ....
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 09, 2015, 09:00 pm
Oui désolé :
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.651*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.651*mesure_brute+329; // calcul angle actuel
  Serial.println(angle);
  delay(1000);

 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+5)
 {
   digitalWrite(M1, HIGH);
   Serial.println("HIGH");
 }
 if (angle<consigne-5)
 {
   digitalWrite(M1, LOW);
   Serial.println("LOW");
  }
 if (angle >= consigne-5 && angle <= consigne+5)
  {
  Serial.println("ARRET");
  analogWrite(E1,0);  // celui-ci est dans le loop et dans le if
  }
      }
 analogWrite(E1,70); // et celui-ci est uniquement dans le loop
 
delay(20);
  }
 
   


J'ai mis un petit "celui-ci..." à côté de ce qui me pose problème. Je voulais savoir si mettre 2 vitesses différentes dans un même loop pouvait poser problème ?
Title: Re: asservissement de position
Post by: B83s on Apr 09, 2015, 09:34 pm
Si tu parles d'un problème de fonctionnement ... Oui comme ça, ça ne va pas marcher ...

Conseil: essaie de bien aligner les accolades ... (Il y a une fonction de formatage du programme dans l'IDE (rassures toi, ça ne l'efface pas ...) ... Ca permet d'avoir de des pseudo paragraphes qui aident à la lecture ...

Et maintenant regarde ce que ton programme fait quand tu entres dans la condition if (angle >... && angle <...)
   Tu arrêtes ton moteur ... On est d'accord

Mais ensuite ton programme poursuit avec ... ?

PS tu as un delay(1000) et un delay(20) dans le loop ... Un seul suffit, et si ton moteur tourne vite, un délai trop long te feras rater la zone d'arrêt (pendant le delai le micro fait une pause, mais la commande du moteur continue ...) .. C'est à toi de voir pour une pause idéale
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 09, 2015, 09:52 pm
Merci ! ça fait beaucoup plus propre, je ne savais pas que cette fonction existait.

Oui le delay(1000) c'est en faisant du copier/coller de ce qui a au-dessus, j'ai oublié de le mettre en commentaire, c'est le delay(20) qui est le bon.
Je vais voir quel delay sera l'idéal alors.

Justement je ne sais pas, vu que c'est une boucle je dirai que, quand mon moteur s'est éteint, si la valeur de angle dépasse la zone >consigne-5 et <consigne+5, il va alors se remettre en marche pour re-rentrer dans l'intervalle voulu et s'arrêter à nouveau, mais à priori ce n'est pas ce qu'il fait avec mon programme là ?
Title: Re: asservissement de position
Post by: B83s on Apr 09, 2015, 10:11 pm
Ben non !

Il n'y a rien à deviner dans un programme ... Il s'exécute, une instruction apres autre

Quand tu sors de la condition d'arrêt ... Le programme passe à quelle ligne ?

N'oublie pas ... La valeur d'angle n'est actualisée qu'au début du loop ... Elle ne changera pas après
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 09, 2015, 10:24 pm
Il passe à la suivante alors ?

Dans le if (angle>consigne-5 && angle<consigne+5), il faut peut etre que je mette un while ?
Title: Re: asservissement de position
Post by: B83s on Apr 10, 2015, 09:38 am
oui il passe à la ligne suivante qui est ... analogWrite(E1,70);
et ça va remettre le moteur en marche ! tu ne verras même pas que ton moteur s'est arreté...

ton programme est vraiment simple ... il n'y a pas 36 choses à faire :
- mesurer l'angle
- 2 vérifications pour gérer le réglage
- 3 vérifications pour gérer le fonctionnement

Code: [Select]

loop
mesurer angle

si bouton1 {
    activer sens 1
    tourner
    consigne = angle
}
sinon si bouton2 {
    activer sens 1
    tourner
    consigne = angle
}
sinon si ange < consigne -5 {
    activer sens1
    tourner
}
sinon si angle > consigne +5 {
    activer sens2
    tourner
}
sinon si angle >= consigne -5 et angle <= consigne+5 {
    ne pas tourner
}
petite pause
//fin du loop !




ça commence à être un peu plus clair la ??
tu as le matériel sous la main pour tester les choses ???
Title: Re: asservissement de position
Post by: unisev on Apr 10, 2015, 09:40 am
Si j'ai bien compris, on peut traduire ce que tu veux en pseudo-code :

Code: [Select]

SI (l'angle est proche de la consigne)
  {
  ne rien faire
  }
SINON
  {
  écrire le bon angle
  }


SINON c'est la commande ELSE
Title: Re: asservissement de position
Post by: B83s on Apr 10, 2015, 09:46 am
oui je ne vais pas vous écrire le code non plus ... sinon vous n'apprendrez rien
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 10, 2015, 10:44 am
Il faudrait alors que je mette  analogWrite(E1,70); avant le if où je demande au moteur de s'arrêter s'il est dans l'intervalle voulu ?
Title: Re: asservissement de position
Post by: B83s on Apr 10, 2015, 10:48 am
tu mets analogWrite(E1,70); dans chaque condition qui fait tourner le moteur ...
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 10, 2015, 11:09 am
Oui ca marche ! Moi j'étais entrain d'essayer de rajouter des else...

Voici le programme :

Code: [Select]

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

const int Voie_0 = 0;
int mesure_brute; // Enlever =0 ?????
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.72 * mesure_brute + 368;
  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.72 * mesure_brute + 368; // calcul angle actuel
  Serial.println(angle);
  //delay(1000);

  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 + 5)
    {
      digitalWrite(M1, HIGH);
      Serial.println("HIGH");
      analogWrite(E1, 70);
    }
    if (angle < consigne - 5)
    {
      digitalWrite(M1, LOW);
      Serial.println("LOW");
      analogWrite(E1, 70);
    }
    if (angle >= consigne - 5 && angle <= consigne + 5)
    {
      Serial.println("ARRET");
      analogWrite(E1, 0);

    }


  }


  delay(20);
}



Il y a juste un petit soucis, quand mon moteur est arrêté parce que la valeur de l'angle est dans l'intervalle voulu, je n'arrive pas le faire touner à l'aide de l'inverseur, saurais-tu comment remédier à cela ?
Title: Re: asservissement de position
Post by: B83s on Apr 10, 2015, 02:20 pm
c'est pourtant simple !

ton moteur est dans l'intervalle ... il s'arrete : ok
tu actionnes ton inverseur ... mais à aucun moment tu ne dis au moteur de repartir ...

il manque des analogWrite(E1, 70); dans les if de l'inverseur ! je te l'avais déjà indiqué ce matin il me semble ....

Code: [Select]
loop
mesurer angle

si bouton1 {
    activer sens 1
    tourner            <<<<<<<<<<<<< il y a écrit quoi ici ?
    consigne = angle
}
sinon si bouton2 {
    activer sens 1
    tourner            <<<<<<<<<<<<< il y a écrit quoi ici ?
    consigne = angle
}
sinon si ange < consigne -5 {
    activer sens1
    tourner
}
sinon si angle > consigne +5 {
    activer sens2
    tourner
}
sinon si angle >= consigne -5 et angle <= consigne+5 {
    ne pas tourner
}
petite pause
//fin du loop !
Title: Re: asservissement de position
Post by: unisev on Apr 10, 2015, 03:22 pm
Moi je crois que j'ai pas forcément bien compris le besoin au départ  :smiley-confuse:
Title: Re: asservissement de position
Post by: Stephanois57 on Apr 10, 2015, 06:01 pm
UniseV, le besoin de départ c'est de demander un angle qui ferra office de consigne, et de le conserver quelque soit les "perturbations". C'est un asservissement de position. C'est dommage que je ne peux pas publier de vidéo, j'aurai pu te montrer le résultat "final" (ou presque) afin que tout le monde puisse parfaitement comprendre.

B83s, je te remercie, le programme fonctionne enfin comme je le souhaite pour le moment !
Je suis désolé d'avoir posé des questions bêtes, mais comme tu as pu le remarquer, je suis vraiment novice en programmation, je partais avec aucune base. Encore merci !

J'ai juste une dernière question, c'est surtout pour ma culture personnelle : sais-tu comment fonctionne le système de vitesse du moteur dans le programme ? Car je peux le faire varier de 0 à 255, donc ça doit être codé sur 8 bits en base 2 je pense ? Et par exemple, quand je dis analogWrite(E1, 70), le "70" comment est-il interprété par la carte ? (70 équivaut à 1000110 en base 2 je crois)
Title: Re: asservissement de position
Post by: B83s on Apr 10, 2015, 08:57 pm
Ouf on y arrive !

Il faut que tu te renseignes sur le PWM (Pulse Width Modulation) ou MLI ( in franchement) pour avoir ta réponse

http://arduino.cc/en/Tutorial/PWM

En arduino 0% c'est 0 et 100% c'est 255... Comme tu l'avais compris, c'est codé sur 8 bits en arduino ...
avec 70 tu es en gros à 35% de la puissance max

Title: Re: asservissement de position
Post by: Stephanois57 on Apr 10, 2015, 09:25 pm
Oui j'ai mis du temps… Mais le résultat est là !

D'accord, le lien que tu m'as envoyé est très clair.

Pour le moment je n'ai plus de questions, tu m'as très bien guidé et fait part de ton savoir. Si jamais j'ai encore une petite question pour laquelle je ne trouve pas de réponse, je reviendrai vers toi.

Merci encore pour ton aide ( et ta technique d'aide très instructive ) !
Title: Re: asservissement de position
Post by: Stephanois57 on May 03, 2015, 03:16 pm
Bonjour,

Je reviens juste ici pour une toute petite explication : sur le lien que tu m'as envoyé, il y a une série de graphe, avec toujours sur l'axe des ordonnées une tension de 5V. Je voudrais savoir, moi qui alimente mon moteur par une petite batterie 12V, si dans ce cas, je remplace 5V par 12V dans le graphique, ou alors si le 5V je dois le garder, auquel cas, a quoi correspond il ?

Merci d'avance
Title: Re: asservissement de position
Post by: B83s on May 03, 2015, 05:11 pm
Les graphes sont en 5v car l'arduino ne peut sortir que 5v sur ses broches ... Et encore pas pour alimenter directement un moteur...

Si tu utilises un shield moteur ou un montage perso avec mosfet ou transistor ... Le signal arduino en 5v est la commande qui sert à piloter ton monteur en 12v ...

En gros, quand ta carte arduino envoie 5v, le shield envoie 12v au moteur et 0v sinon ....
Title: Re: asservissement de position
Post by: Stephanois57 on May 03, 2015, 05:45 pm
D'accord merci beaucoup, c'est exactement ce que je voulais savoir. Merci !