Go Down

Topic: [Débutant] Faire fonctionner un capteur de flexion (Read 173 times) previous topic - next topic

PaulJardin

Bonjour à tous !  :)

Je suis débutant en Arduino, et pour un projet d'école j'aimerai faire fonctionner un capteur de flexion. Je veux simplement que le moniteur affiche le degré de fléchissement du capteur. Pour vous montrer ce que j'ai réalisé, je l'ai refait sur Fritzing et je j'envoie une capteur d'écran en pièce jointe de ce message. Mon montage est exactement identique, sauf que j'ai une deuxième résistance juste en dessous de la première résistance (je n'ai pas la place de l'ajouter sur Fritzing).

Mes deux résistances sont de 10.000 Ohms et mon capteur de flexion est un FS7954.

Voici mon code (tiré de SparkFun) :

Code: [Select]
const int FLEX_PIN = A0;

const float VCC = 5;
const float R_DIV = 20000.0;  //Parce que j'ai 2 résistances de 10 000 Ohms

const float STRAIGHT_RESISTANCE = 25000.0; // Sur le site où j'ai acheté mon capteur de flexion, ils mettent que la résistance au repos est de 25 000 Ohms
const float BEND_RESISTANCE = 125000.0; // Sur le site où j'ai acheté mon capteur de flexion, ils mettent que la résistance maximale (donc à 90°) est de 125 000 Ohms

void setup()
{
  Serial.begin(9600);
  pinMode(FLEX_PIN, INPUT);
}

void loop()
{
  int flexADC = analogRead(FLEX_PIN);
  float flexV = flexADC * VCC / 1023.0;
  float flexR = R_DIV * (VCC / flexV - 1.0);
  Serial.println("Resistance: " + String(flexR) + " ohms");

  float angle = map(flexR, STRAIGHT_RESISTANCE, BEND_RESISTANCE,
                   0, 90.0);
  Serial.println("Bend: " + String(angle) + " degrees");
  Serial.println();

  delay(3000);
}


Si quelqu'un peut m'expliquer ce qui ne va pas dans le code et/ou le montage je suis preneur, car les valeurs indiquées sont bizarres. Comme je n'ai pas trouvé de DataSheet pour mon capteur de flexion, j'ai aussi essayé d'échanger les deux bouts de mon capteur de flexion (simplement en le retournant) mais cela ne marche pas non plus.

Désolé si l'erreur vous semble bête, mais j'ai vraiment cherché longtemps avant de me décider à poster ici.

Merci d'avance ! :)

J-M-L

Votre image:


Vous savez expliquer cette formule?
Code: [Select]
float flexR = R_DIV * (VCC / flexV - 1.0);
ça c'est pour la théorie

Ensuite il serait bon de dessiner où exactement en dessous vous avez la seconde résistance, car n'oubliez pas que tous les trous d'une colonne d'un même côté de la breadboard sont reliés... => don combien vaut La résistance équivalente de vos 2 résistances ?
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

PaulJardin

Bonjour et merci de votre réponse :)

Alors oui je comprends la formule sauf le "-1" mais comme elle était comme ça sur un site "sérieux" (https://learn.sparkfun.com/tutorials/flex-sensor-hookup-guide/all) je me suis dit que ça devait être bon.

En ce qui concerne ma 2ème résistance, elle est comme ceci (en imaginant évidemment que les bouts rentrent bien dans les trous) :


Et selon moi, comme mes deux résistances sont en série dans mon montage, la résistance équivalente vaut 10 000 + 10 000 = 20 000 Ohms.

J-M-L

Sauf pour le -1 ce n'est pas une réponse... faudra savoir expliquer à la soutenance...
Regardez la formule d'un pont diviseur de  tension



R1 serait votre flex, R2 votre résistance en bas. La forumule dit


Pouvez vous écrire R1 en fonction de R2, U et R2 ?

-----

Relisez mon commentaire: tous les trous d'une colonne sont connectés...
ça ressemble donc plus à cela:


        A0
         |
         |           --------------
Flex ----O--- Ra ---|             |----- GND
                     ---- Rb ------


Est-ce que Ra et Rb sont vraiment purement en série ? En prenant comme résistance du fil quasiment 0, qu'elle est vraiment la résistance équivalente ?
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

PaulJardin

D'accord merci !

Donc en prenant la formule Req = (Ra*Rb)/(Ra+Rb) on trouve que Req = 5 000 Ohms !
Mais je ne sais pas trop, j'ai l'impression qu'il devait y avoir une autre erreur qu'uniquement cela dans mon montage et/ou mon code, car je trouvais des choses vraiment étranges et éloignés de la réalité.

Et pour le -1, je suis désolé j'ai vraiment cherché mais je n'arrive pas à trouver son utilité...

PaulJardin

Désolé du double post mais je voulais rajouter que d'ailleurs au départ j'avais testé avec uniquement une seule résistance de 10 000 Ohms et donc dans mon code j'avais mis seulement
Code: [Select]
const float R_DIV = 10000.0; et pourtant je trouvais quand même des choses fausses, donc l'erreur ne doit pas venir (uniquement en tout cas) de là  :smiley-confuse:

savoriano

float flexV = flexADC * VCC / 1023.0;

Si flexV est la tension de ton flexion allors

float flexV = VCC - (flexADC * VCC / 1023.0);

Avec ta formule tu trouve la V au pôles de ta resistence de 20000ohm
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

PaulJardin

Merci de vos réponses.  :)

J'ai donc enlevé ma 2ème résistance (mon montage est donc exactement le montage sur la photo, et la résistance est une résistance de 10 000 Ohms) :



De plus j'ai donc modifié mon code pour obtenir ceci :

Code: [Select]
const int FLEX_PIN = A0;

const float VCC = 5;
const float R_DIV = 10000.0; // Ma résistance de 10 000 Ohms
const float STRAIGHT_RESISTANCE = 25000.0; // Résistance du capteur de flexion au repos
const float BEND_RESISTANCE = 125000.0; // Résistance quand il est à 90°

void setup()
{
  Serial.begin(9600);
  pinMode(FLEX_PIN, INPUT);
}

void loop()
{
  int flexADC = analogRead(FLEX_PIN);
  float flexV = VCC - (flexADC * VCC / 1023.0);
  float flexR = R_DIV * (VCC / flexV - 1.0);
  Serial.println("Resistance: " + String(flexR) + " ohms");

  float angle = map(flexR, STRAIGHT_RESISTANCE, BEND_RESISTANCE,
                   0, 90.0);
  Serial.println("Bend: " + String(angle) + " degrees");
  Serial.println();

  delay(3000);
}


Cependant cela ne marche toujours pas, et j'obtiens des nombres impossibles (des degrés qui changent sans que je touche à mon capteur de flexion, ou bien des valeurs négatives, ou alors des valeurs très hautes et supérieurs à 90°, ...).

Je n'arrive vraiment pas à trouver la solution !

J-M-L

J'attends toujours le calcul d'explication...

Sinon mesurez vous même STRAIGHT_RESISTANCE et BEND_RESISTANCE au multimètre... ou avec A0 et la bonne formule (que je vous laisse trouver)

Postez une photo de votre breadboard (ou on voit bien où est votre résistance)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

PaulJardin

D'accord je n'avais pas compris. J'envoie tout ça demain (le calcul + la photo) car je vais me coucher. En tout cas merci beaucoup pour votre aide :)

Et je n'ai pas de multimètre, pour Straight_Resistance et Bend_Resistance j'ai juste regardé les détails sur GoTronic où j'ai acheté mon capteur de flexion :



J'ai donc mis 25000 pour Straight-Resistance et 125 000 pour Bend-Resistance.

J-M-L

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

savoriano

#11
May 20, 2019, 01:39 am Last Edit: May 20, 2019, 01:40 am by savoriano
Je ne comprends pas cette formule
 float flexR = R_DIV * (VCC / flexV - 1.0);

pour moi flexR =

flexR =( flexV / Rv ) * R_DIV

où RV = flexADC * VCC / 1023.0

donc
flexR =( flexV / (flexADC * VCC / 1023.0) ) * R_DIV

Moi je ferais ca! tu peux essayer! Dis moi si je me trompe: c'est fort possible

 
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

biggil

Il faut distinguer :
- j'obtiens des valeurs bizarres mais stables (indiquant une erreur de montage ou de programmation)
- j'obtiens des valeurs fluctuantes (indiquant un problème électrique) 

Tu es dans quel cas ?

J-M-L

Je pense qu'il obtient des valeurs négatives ou au delà de 90 parce que
Code: [Select]
float angle = map(flexR, STRAIGHT_RESISTANCE, BEND_RESISTANCE, 0, 90.0);définit simplement une fonction de transfert linéaire affine et quand flexR est plus petit que STRAIGHT_RESISTANCE alors on sera sous 0, et quand flexR est plus grand que BEND_RESISTANCE alors on sera au delà de 90

Idéalement il faut 
1. trouver La bonne formule pour flexR (elle est correcte mais faut savoir l'expliquer... SVP).
2. injecter des mesures précises dans la formule
3. avoir les bonnes constantes STRAIGHT_RESISTANCE et BEND_RESISTANCE
4. Prévoir les cas extrême (éventuellement utiliser constrain()
5. Et bien sûr tout brancher et alimenter correctement (notamment si 2 résistances, comprendre comment une breadboard fonctionne)

Je pense que
-  STRAIGHT_RESISTANCE et BEND_RESISTANCE sont faux.
- passer par la tension en float alors qu'on peut faire la règle de trois bêtement sur les valeurs de analogRead() (en connaissant la valeur lue quand on est droit et courbé) fait perdre de la précision et rapidité
- qu'il faudrait quand même vérifier si la résistance varie linéairement avec la courbure ou si la fonction de transfert est un peu plus complexe, donc faire des essais pour voir si à 10°, 20°,30°,40°,45°,50°,60°,70°,80°,90° on est bien sur des valeurs qui évoluent linéairement entre la borne MIN et MAX

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

savoriano

Install ce code
Code: [Select]
const int FLEX_PIN = A0;

const float VCC = 5;
const float R_DIV = 10000.0; // Ma résistance de 10 000 Ohms
const float STRAIGHT_RESISTANCE = 25000.0; // Résistance du capteur de flexion au repos
const float BEND_RESISTANCE = 125000.0; // Résistance quand il est à 90°

void setup()
{
  Serial.begin(9600);
  pinMode(FLEX_PIN, INPUT);
}

void loop()
{
  int flexADC = analogRead(FLEX_PIN);
  Serial.println("flexADC: " + String(flexADC));
  float flexV = VCC - (flexADC * VCC / 1023.0);
  Serial.println("flexV: " + String(flexV));
  float flexR = R_DIV * (VCC / flexV - 1.0);
  Serial.println("Resistance: " + String(flexR) + " ohms");

  float angle = map(flexR, STRAIGHT_RESISTANCE, BEND_RESISTANCE,
                   0, 90.0);
  Serial.println("Bend: " + String(angle) + " degrees");
  Serial.println();

  delay(3000);
}


Fais tourner un peux et fais un copié collé du monitor ici
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

Go Up