Go Down

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

Stephanois57

#30
Apr 09, 2015, 06:54 pm Last Edit: Apr 09, 2015, 06:54 pm by Stephanois57
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 ?

B83s

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

Stephanois57

#32
Apr 09, 2015, 09:00 pm Last Edit: Apr 09, 2015, 09:10 pm by Stephanois57
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 ?

B83s

#33
Apr 09, 2015, 09:34 pm Last Edit: Apr 09, 2015, 09:41 pm by B83s
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

Stephanois57

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

B83s

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

Stephanois57

Il passe à la suivante alors ?

Dans le if (angle>consigne-5 && angle<consigne+5), il faut peut etre que je mette un while ?

B83s

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

unisev

#38
Apr 10, 2015, 09:40 am Last Edit: Apr 10, 2015, 09:41 am by UniseV
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
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

oui je ne vais pas vous écrire le code non plus ... sinon vous n'apprendrez rien

Stephanois57

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 ?

B83s

tu mets analogWrite(E1,70); dans chaque condition qui fait tourner le moteur ...

Stephanois57

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 ?

B83s

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 !

unisev

Moi je crois que j'ai pas forcément bien compris le besoin au départ  :smiley-confuse:
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 !

Go Up