Asservissement en force Arduino avec capteur de force et servomoteur

Bonjour,

Je me présente : Eléanor Chaillou, étudiante en CPGE en deuxième année.

Mon projet : dans le cadre de mon cursus, je dois préparer un TIPE. Pour moi, il s'agit d'assurer l'asservissement en force d'un doigt bionique à l'aide d'un servomoteur Fitech 9g FS90 et d'un capteur de force FSR402.

Je suis arrivée au point où j'ai réussi à faire contrôler le servomoteur et le capteur de force de manière indépendante.

Mon montage : un doigt dont la position est commandée par le servomoteur et qui appuie plus ou moins sur un capteur de force. Tout est alimenté par un Arduino.

Mon problème : j'indique ma consigne de force que j'aimerais obtenir dans mon moniteur série. Mon doigt est censé plus ou moins avancer en fonction de la valeur renvoyée par le capteur de force. Néanmoins, même si la consigne est largement dépassée, le doigt continue d'avancer.

Mon code : (mélange entre Internet et ce que j'ai écrit)

/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 https://www.arduino.cc/en/Tutorial/LibraryExamples/Sweep
*/
#define FORCE_SENSOR_PIN A1 // the FSR and 10K pulldown are connected to A0

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  int analogReading = analogRead(FORCE_SENSOR_PIN);
  // int analogReadingBefore;
 
  Serial.print("Force sensor reading = ");
  Serial.print(analogReading);
  Serial.print("\n");
  // print the raw analog reading
  delay(1000);
 int angle = 90;

 myservo.write(angle);
 
while (Serial.available() > 0) {

   // look for the next valid integer in the incoming serial stream:
  int consigne = Serial.parseInt();
  while (analogReading!=consigne)
 {
   if (analogReading<consigne){
    angle+=10;
    myservo.write(angle);
    int analogReading = analogRead(FORCE_SENSOR_PIN);
    Serial.print("Force sensor reading = ");
    Serial.print(analogReading);
    Serial.print("\n");
    delay(50);
    }
   if (analogReading>consigne) {
    angle-=50;
    myservo.write(angle);
    int analogReading = analogRead(FORCE_SENSOR_PIN);
    Serial.print("Force sensor reading = ");
    Serial.print(analogReading);
    Serial.print("\n");
    delay(50);
   }
   }
 
   delay(10);
   
   char mon_caractere = Serial.read(); //pour purger la memoire de Serial
  // Serial.flush();                     // idem, mais ne fonctionne pas ! ;-(
  }                   // waits 15 ms for the servo to reach the position
}

Pourriez-vous m'aider, s'il vous plaît ? Merci d'avance pour vos réponses

Bonjour,

Je note que tu fais afficher la valeur d'analogReading plusieurs fois mais jamais la valeur de la consigne.
Es-tu certaine qu'elle soit bonne et bien interprétée?
Tu testes une égalité stricte entre la consigne et la mesure. En théorie c'est possible mais dans la vie les mesures sont entachées de bruit. Donc tu vas faire en permanence trop fort, trop faible, ....
Et comme tu fais +10 dans un sens et -50 dans l'autre dès que tu appuies un peu fort tu relâches, ....
Ce serait sans doute mieux d'avoir des incréments/décréments qui soient proportionnels à l'écart avec la consigne.

Attention aussi à la portée de tes variables. Tu as 3 variables analogReading cela te joue des tours. Typiquement la variable analogReading du while n'est pas la même que celle des 2 if. Et celle du while n'est mise à jour que lorsque tu sors du while.

La logique de l'ensemble me semble bizarre.
L'asservissement ne se produit que si le programme reçoit un caractère.
La réception de la consigne et l'asservissement devraient être 2 tâches distinctes.
L'asservissement devrait toujours tourner sur la consigne en cours.
Si la partie réception de la consigne reçoit une consigne valide alors la nouvelle consigne vient remplacer la consigne en cours.

Imagine que ton doigt bionique presse sur un hypothétique objet qui change de volume dynamiquement (comme un animal qui respire par exemple) il faut adapter la force en permanence même si tu ne reçois plus de consigne sinon tu vas écraser l'objet ou bien le laisser glisser.

Salut,
C'est mon coté automaticien en géni climatique qui parle.
Pour quoi ne pas utiliser une boucle PID afin de piloter le servomoteur.
c'est ce que je trouve le plus précis et comme l'a dit fdufnews ça corrigerait automatiquement les changements de volume tous les x temps à déterminer.

Bonsoir

+1

Avant d'aller à la correction PID une commande proportionnelle (P) serait déjà un pas en avant important , cela nécessite d'évaluer en boucle l'erreur (=écart entre consigne et réalité) puis de doser la correction d'après l'erreur . Tenir aussi compte dans la réaction de l'inertie probable du servo et de la masse qu'il déplace (doigt)

:woman_student:S'agissant d'un TIPE en seconde année de CPGE il serait rentable de passer un peu de temps à se documenter sur les asservissements pour guider un tant soit peu la démarche et moins perdre de temps en divagations évitables....

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.