Go Down

Topic: compteur de vitesse  (Read 530 times) previous topic - next topic

kamill

Et ça donne combien pour tempsTrouve?

Belo

Quand j'affiche tempstrouve ba ça me donne le temps en ms entre chaque passage de l'écran

lesept

#17
Aug 16, 2019, 10:44 am Last Edit: Aug 16, 2019, 12:00 pm by lesept
Peut-être devrais-je faire plusieurs calculs au lieu d'un gros ? 
( au lieu de ça :   vitesse = (perimetre /(tempstrouve / 1000)) * 3.6;

Et remplacer par ça :

vitesse = perimetre / tempstrouve;
vitesse = vitesse * 3600;

J'ai essayé comme au dessusmais ça m'affiche que 0.00 dés que je passe l'aimant
Ton problème est de faire une division en flottant. Mais si tes nombres sont des int et que tu ne précises pas que tu veux un flottant, ta division sera entière.
Pour ça plusieurs solutions, la plus simple est de dire explicitement que tu veux du flottant

Code: [Select]
vitesse = perimetre * 1.0 / tempstrouve;
vitesse = vitesse * 3600.0;


Sinon tu peux faire un cast, une promotion, qui va changer temporairement un int en float, le temps de l'opération

Code: [Select]
vitesse = (float) perimetre / tempstrouve;
vitesse = vitesse * 3600;
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

kamill

#18
Aug 16, 2019, 11:11 am Last Edit: Aug 16, 2019, 11:11 am by kamill
Peut-être devrais-je faire plusieurs calculs au lieu d'un gros ? 
( au lieu de ça :   vitesse = (perimetre /(tempstrouve / 1000)) * 3.6;
...
Il faut faire le calcul en flottant
Code: [Select]
vitesse = (perimetre /(tempstrouve / 1000.0)) * 3.6

Belo

#19
Aug 16, 2019, 02:24 pm Last Edit: Aug 16, 2019, 03:04 pm by Belo
D'accord, maintenant ça y est, j'ai la vitesse en km/h.
Et finalement j'ai changé le vitesse en int car je ne souhaite pas de nombres à virgule.

J'ai réalisé un second programme qui m'affiche cette vitese mais sur un écran oled cette fois-ci, je travaille pour mesurer la distance et l'afficher et travaille avec l'EEPROM ( j'essaye ) pour afficher dans un second menu la distance totale et d'autres trucs ( vitesse max ...).

J'aurais sans doute besoin d'aide pour l'EEPROM car je n'ai jamais utilisé celle-ci mais ayant lu des tutos, je pense que ça devrait le faire....

lesept

Tu risques de perdre en précision, reste en flottant pour le calcul et affiche avec zéro chiffre après la virgule

Code: [Select]
Serial.print (vitesse, 0);
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Belo

#21
Aug 16, 2019, 04:09 pm Last Edit: Aug 16, 2019, 04:33 pm by Belo
OK c'est fait. J'ai fait un code qui affiche la vitesse et la distance sur l'écran oled ( sans les unitées de km et km/h )mais mon écriture prend trop de temps donc je ne peux pas mesurer plus de 11km/h.  Comment-y remédier ? :smiley-sad:


Mais si par exemple j'enlève l'écriture de la distance, je peux mesurer jusqu'à 21 km/h

lesept

A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Belo

J'avais oublié !!! désolé
Code: [Select]

#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );



void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
 
}

void loop() {

unsigned long temps = millis();
int perimetre = 2;  //entrer le périmètre de la roue en m, le périmètre est égal à   pi*diamètre     ou      pi*2* rayon                       !!!!! EN METRE !!!!!
static unsigned long dernierPassage;
static bool flagMesure = false;
int tempstrouve;
float vitesse;
float distance;

  if (analogRead(A0) <= 410  || analogRead(A0) >= 615) { //si un aimant pole nord ou un aimant pole sud passe devant le capteur
    if (flagMesure)
    { tempstrouve = temps - dernierPassage;
      dernierPassage = temps;
      vitesse = (perimetre / (tempstrouve / 1000.0)) * 3.6; //donne la vitesse en km/h grace à v = d/t
      flagMesure = false;     // pour attente cycle suivant
      distance = distance + (perimetre / 1000.0);

      display.clearDisplay();   //efface l'écran pour le réactualiser
    }
  }
  else
  {
    flagMesure = true;  // prêt pour une nouvelle mesure
  }

display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(40, 2);  //essai donc placement on s'en fout
display.print(distance, 1);
display.display();

display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 2);  //essai donc placement on s'en fout
display.print(vitesse,0);
display.display();



}




lesept

Il faut exécuter les commandes d'affichage uniquement lorsque tu fais le calcul de la vitesse, pas à chaque tour de la loop. C'est ça qui te ralentit

Il est possible que ton clear display finisse par faire clignoter l'affichage... Mais on verra plus tard
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Belo

#25
Aug 16, 2019, 06:22 pm Last Edit: Aug 16, 2019, 07:08 pm by Belo
Maintenant que j'ai mis tout ça dans le if et avec les calculs, je peux monter à 21km/h max.


lesept

Je peux t'aider à optimiser ton code, mais j'aurais besoin de savoir ce que donnent les valeurs du analogRead. Peux-tu faire tourner ta roue et afficher ces valeurs ?
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Belo

Déjà, pour que ce soit plus clair, mon capteur n'est pas monté, je passe juste un aimant "à la main" comme ça en essayant d'être régulier et de faire varier la vitesse.  Tout est monté sur breadboard avec un arduino uno.

Mon analogRead me donne environ 515 sans aimant, cela oscille un peu mais c'est normal, c'est comme ça sur la fiche technique. En fait quand le champs magnétique est à peu près nul, il donne 2.5v en sortie.

Quand je passe un aimant pôle sud à environ 1-2 cm, ça descend en dessous de 2v environ ( d'où le 410 ( 1024/5 = 204.8  et 204.8*2 = environ 410)).
Quand je passe un aimant pôle nord à environ 1-2 cm,  ça monte eau dessus de 3v environ ( d'où le 615 ( 1024/5 = 204.8  et 204.8*3 = environ 815)).

Attention, tant que je laisse l'aimant devant le capteur, sa tension reste de <2v ou >3v.

C'est un capteur analogique du coup, pas comme la majorité des autres capteurs à effet hall ou comme les capteurs reed (switch magnétique, équivalent capteur ILS si j'ai bien compris... :smiley-confuse: ).

lesept

21km/h ça fait près de 6 m/s donc 3 tours de roue par seconde. C'est très peu, à mon avis tu dois monter bien plus haut. Comment evalues tu cette valeur ?
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

lesept

#29
Aug 16, 2019, 11:20 pm Last Edit: Aug 16, 2019, 11:22 pm by lesept
Alors voila un code, que je pense un peu plus optimisé

Code: [Select]
/*
   Compteur de vitesse
   Lesept 08/2019
*/
#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );

// Définir ici les seuils min et max du analogRead
#define valMin 410
#define valMax 615
// Définir ici les coordonnées pour l'effacement du texte
// x : abscisse min, y : ordonnée min, w : largeur, h : hauteur du rectangle
// Voiri :https://learn.adafruit.com/adafruit-gfx-graphics-library/graphics-primitives
#define xDist 40
#define yDist 20
#define wDist 40
#define hDist 20
#define xVit  00
#define yVit  20
#define wVit  40
#define hVit  20

const int valMoy = (valMin + valMax) / 2;
const int seuil = (valMax - valMin) / 2;
const int perimetre = 2;  //entrer le périmètre de la roue en m, le périmètre est égal à   pi*diamètre     ou      pi*2* rayon                       !!!!! EN METRE !!!!!
bool flagMesure = false;
unsigned long tempstrouve = 0;
unsigned long dernierPassage = 0;
float vitesse = 0;
float distance = 0;

void Affiche (float distance, float vitesse) {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.fillRect (xDist,yDist,wDist,hDist,BLACK);
  display.setCursor(40, 2);  //essai donc placement on s'en fout
  display.print(distance, 1);

  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(0, 2);  //essai donc placement on s'en fout
  display.fillRect (xVit,yVit,wVit,hVit,BLACK);
  display.print(vitesse, 0);
 
  display.display();
}

void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  Affiche (distance, vitesse);
}

void loop() {
  int diff = abs(analogRead(A0) - valMoy);
  if (diff >= seuil) { //si un aimant pole nord ou un aimant pole sud passe devant le capteur
    if (flagMesure) {
      tempstrouve = millis() - dernierPassage;
      dernierPassage = millis();
      vitesse = (perimetre / (tempstrouve / 1000.0)) * 3.6; //donne la vitesse en km/h grace à v = d/t
      flagMesure = false;     // pour attente cycle suivant
      distance = distance + (perimetre / 1000.0);
      Affiche (distance, vitesse);
    }
  }
  else
  {
    flagMesure = true;  // prêt pour une nouvelle mesure
  }
}


Au lieu d'effacer l'écran entier à chaque fois, je trace un rectangle aux endroits ou tu affiches la distance et la vitesse. Ces endroits sont définis par
Code: [Select]
#define xDist 40
#define yDist 20
#define wDist 40
#define hDist 20
#define xVit  00
#define yVit  20
#define wVit  40
#define hVit  20

Mais il faut que tu trouves les bonnes valeurs sur ton écran.

Pour le capteur, j'ai modifié le test afin de ne plus avoir de OU. Le principe c'est de calculer la distance de la valeur mesurée à la moyenne. Par exemple, si un passage correspond à une valeur mesurée inférieure à 400 ou supérieure à 600 (c'est plus facile à voir avec des nombres entiers), on peut faire
Code: [Select]
if (valeur <=400 || valeur >= 600)
mais on peut aussi se dire que la distance de la valeur à 500 doit être supérieure à 100, ce qui donne
Code: [Select]
diff = abs(valeur - 500);
if (diff >= 100)

500 est la valeur moyenne de 400 et 600, et 100 et la moitié de la distance entre 400 et 600.

Si vraiment c'est encore trop lent (mais il faudrait le tester sur une vraie roue,en vraie grandeur) on peut  afficher les valeurs moins souvent, par exemple toutes les secondes. On pourra voir ça plus tard...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Go Up