asservissement de position

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

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)

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

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)

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

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

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.

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

attention aux parenthèses ...

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

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 ?

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

Oui désolé :

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 ?

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

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

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

Il passe à la suivante alors ?

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

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

Si j'ai bien compris, on peut traduire ce que tu veux en pseudo-code :

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

SINON c'est la commande ELSE

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

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 ?

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