Compteur Distance

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");
}

Bonjour,

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.

anti-rebond ?

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.

68tjs:
.quvaise pression des pneus :slight_smile:

Clavier US ? :slight_smile:

Non clavier Bépo ,

Je recommence :
Echauffement des pneus, mauvais diamètre :slight_smile:

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

Ok merci pour vos réponses,
Je vais essayer de faire ce que vous m'avez dit et je vous dirait si j'y suis arrivé.

J'ai modifié ma réponse #5...

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:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);

volatile float distance = 0;
volatile int compt = 0;

void startLCD()
{
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Distance:");
}

void setup()
{
  Serial.begin(115200);
  pinMode(2, INPUT); // capteur hall
  attachInterrupt(0, compteur, RISING); // interupt du bouton
  startLCD(); 
}

void compteur()
{
  compt++;
}

void loop()
{
  calcul();
  writeLCD();
}

void calcul()
{
  distance = 0 ;
  distance = compt * 0.204; // 0.204 = périmetre roue
}

void writeLCD() //OK
{
  lcd.setCursor(0, 0);
  lcd.print("Distance: ");
  lcd.print(distance,2);
  lcd.print(" m");
}

Merci d'avance.

Tu peux déjà simplifier ton code :

  • Seule la variable compt doit être volatile
  • 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.

Merci :slight_smile:
je vais essayer de faire cela et je vais voir, en espérant que cela résout le problème.
je tiendrai au courant quand j'y arriverai.

Bonjour,

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.

peut-on utiliser le pull-up interne sur une entrée interruption ?
INPUT_PULLUP

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