Bonjour,
Pour un de mes projets j'essaie de réaliser un compteur de distance à l'aide d'un capteur à effet hall.
J'ai pour cela achété un capteur à effet hall, une carte Arduino Uno et un ecran LCD I2C pour afficher la donné.
J'ai positionné un aimant sur ma roue et le capteur à effet hall devant l'aimant.
J'ai bien avancé sur le programme, cependant ma distance affiché n'est pas precise.
Voici le programme que k'ai écrit:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
float distance = 0;
float tps;
long hre;
long minute;
long min;
long sec;
long seconde;
void startLCD()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Distance:");
lcd.setCursor(0, 1);
lcd.print("Temps:");
lcd.setCursor(5, 2);
lcd.print("COMPTEUR");
}
void setup()
{
Serial.begin(115200);
pinMode(2, INPUT); // capteur hall
attachInterrupt(0, dist, RISING); // interupt du bouton
startLCD();
}
void dist()
{
distance = distance + 0.204; // 0.204 = périmètre roue
}
void loop()
{
writeLCD();
temps();
}
void temps() //OK
{
tps = millis();
seconde = tps / 1000;
sec = seconde - ( minute* 60);
minute = seconde / 60;
min = minute - ( hre * 60 );
hre = seconde / (3600*1000);
lcd.setCursor(0, 1);
lcd.print("Temps:");
lcd.print(hre);
lcd.print(":");
lcd.print(min);
lcd.print(":");
lcd.print(sec);
}
void writeLCD() //OK
{
lcd.setCursor(0, 0);
lcd.print("Distance: ");
lcd.print(distance,2);
lcd.print(" m");
}
Qu'est ce que tu entends par la distance n'est pas précise?
Avec ton programme elle aura une résolution de 0.204 m et la précision dépend de la précision du périmètre et du glissement de la roue sur le sol.
bonjour .
en fonction de quoi trouvez vous que :
"cependant ma distance affiché n'est pas précise".
avez vous calculé l 'imprécision théorique absolue ? ( n'est pas un coefficient).
avez vous étalonné votre "odomètre" sur une distance connue afin de déterminer
l' existence d 'un coefficient de précision ? ( en ayant bien sur préalablement soustrait
la distance d' imprécision maximum absolue).
Bonjour,
J'ai mesuré le rayon de ma roue, j'ai grâce à cela calculé le périmètre. Je pense qu'ici il n'y a pas de problème.
Cependant lorsque j'essaye d'avancer, la distance est précise au début et ensuite au lieu de m'ajouter 0.204 m pour un tour, ça arrive que ça en ajoute 0.408 m .
Pour être sur de la distance j'ai un repère à coté.
Merci d'avance.
La variable modifiée dans la fonction appelée par l'interruption doit être déclarée en volatile
volatile float distance = 0;
Comme c'est un float, tu risques quand même d'avoir des collisions, c'est à dire que l'interruption peut modifier la variable pendant qu'elle sera utilisée.
Au lieu de calculer la distance dans la fonction appelée par l'interruption, tu devrais incrémenter un compteur de tours de roue, et calculer la distance au moment de l'afficher.
Je recommence :
Echauffement des pneus, mauvais diamètre
@macogu
Fais une série de serial.print aux endroits stratégiques du programme pour afficher la valeur des variables, tu trouvera l'endroit de l'erreur et la cause (sérieuse cette fois) du doublement de la distance.
Et quand tu aura trouvé n'oublie pas de retirer tous les serial.print inutiles.
Bonjour,
J'ai bien modifié le programme avec les informations que vous m'avez donné, mais ça ne marche toujours pas. J'ai toujours à des périodes aléatoires le périmètre qui s'ajoute deux fois au lieu d'un...
J'ai pourtant essayé avec une roue plus grosse et sur une longue distance connue.
D’où pourrait venir le problème? Du matériel?
Je vous remets le programme ici:
Dans calcul(), pas besoin d'initialiser distance à 0 puisque tu lui affectes une valeur juste après
Tu affiches "distance" dans startLCD : pas besoin de l'afficher une seconde fois dans writeLCD : positionne directement ton curseur où il faut et affiche uniquement la distance et le "m"
Pour le reste, je ne sais pas vraiment.
La ligne
attachInterrupt(0, compteur, RISING); // interupt du bouton
devrait être
attachInterrupt(digitalPinToInterrupt(2), compteur, RISING); // interupt du bouton
mais je ne sais pas si ça changera quelque chose.
Tu peux aussi essayer de tester avec d'autres modes :
LOW to trigger the interrupt whenever the pin is low,
CHANGE to trigger the interrupt whenever the pin changes value
RISING to trigger when the pin goes from low to high,
FALLING for when the pin goes from high to low.
Est ce qu'il y a un pullup sur le capteur à effet hall?
Comment est ce que tu fais tourner la roue? Si tu avances à la main, tu fais peut être des vibrations en avançant.
Quel est le nombre de tours/seconde (environ)
Si tu as bien un pullup sur le capteur et que tu avances régulièrement, tu peux tenter de faire un filtrage soft.
bonjour,
merci pour ta réponse.
qu'est ce qu'un pull-up kamill ?
je fais tourner ma roue à la main, mais il n'y a pas de vibration
j'avance pas vite, à 5 tr/s grand max
c'est à dire un filtrage soft ?
Un pullup c'est une résistance reliée au +5V afin d'avoir un signal correct. C'est indispensable avec les capteurs à effet hall que je connais.
Un filtrage soft consiste à ne pas prendre en compte les événements qui sont trop rapprochés les uns des autres.
Oui, on peut.
La résistance de pullup interne est de l'ordre de 30-50kΩ alors que la valeur recommandée pour les capteurs à effet hall est en général de 10k, mais ça devrait fonctionner.
Bonjour,
Merci pour votre aide j'ai enfin réussi à résoudre le problème !!
J'ai mis un filtrage soft pour éviter les rebonds, et plus aucun soucis
Pour le pullup je l'avais déjà fait avant mais merci