Go Down

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

Stephanois57

Mar 27, 2015, 08:43 pm Last Edit: Mar 27, 2015, 08:44 pm by Stephanois57
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 !

infobarquee

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

AUCUNE AIDE PAR MP

Stephanois57

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 !

vohu

#3
Mar 28, 2015, 05:08 pm Last Edit: Mar 28, 2015, 05:09 pm by vohu
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

B83s

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
   

Stephanois57

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" ?

B83s

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

Stephanois57

#7
Mar 28, 2015, 08:42 pm Last Edit: Mar 29, 2015, 06:24 pm by Stephanois57
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 ?   

Stephanois57

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 !

B83s

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

Stephanois57

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 ?

B83s

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 ...

Stephanois57

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 ?

B83s

 :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 ...

Stephanois57

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 ?

Go Up