Calcul d'une vitesse avec un capteur inductif

Bonjour à tous !

Je mène un projet sur un gyropode pour ma dernière annéee de lycée. On m'impose de calculer la vitesse (en km/h) et la distance parcourue (en km) puis de l'afficher sur un écran graphique. Je travaille avec une carte Arduino Mega 2560, un TFT Screen Touch V2.0 et un capteur inductif npn (imposé pour pouvoir répondre à ma problématique).

En ce qui concerne la distance, j'ai relevé le nombre de passage puis multiplié la valeur obtenue par le périmètre de la roue (pour l'instant rien de très compliqué).
En revanche, pour la vitesse, après de multiple essais et d'aide sur internet, je ne trouve toujours pas le moyen de pouvoir calculer la vitesse.

Serait-il possible d'avoir de l'aide avec un code explicatif ou une aide quelconque afin de m'aider dans la réalisation de mon projet ?

Bonne journée et merci ! :smiley:

fonction millis() à chaque passage .. différence ...temps , et tu as ta distance donc la vitesse !

BrUnO14200:
fonction millis() à chaque passage .. différence ...temps , et tu as ta distance donc la vitesse !

La fonction millis() ne permet pas normalement de renvoyer le nombre de millisecondes depuis le début du programme ?

Bonjour,

Hakken:
La fonction millis() ne permet pas normalement de renvoyer le nombre de millisecondes depuis le début du programme ?

Oui, et quand tu fais la différence entre deux valeurs tu as la durée.

Salut,

Il faut que tu détermine le nombre de tours de la roue (nb impulsions capteur ) sur une seconde, soit en utilisant millis() entre deux fronts montant ou passer par une interruption, puis connaissant la fréquence de rotation en tr/s tu pourras déterminer la vitesse en m/s ou km/h.

Va voir sur sur post, le principe reste le même.
http://forum.arduino.cc/index.php?topic=92398.0

@+

hameau:
Salut,

Il faut que tu détermine le nombre de tours de la roue (nb impulsions capteur ) sur une seconde, soit en utilisant millis() entre deux fronts montant

Lorsque j'utilise la fonction millis(), même en lui disant de se remettre à 0 une fois l'impulsion passée à basse, le compteur continue d'augmenter et ce indéfiniment.

hameau:
passer par une interruption

Mes recherches étaient portées dessus mais je n'y suis toujours pas arrivé à comprendre le principe de la fonction...

hameau:
Va voir sur sur post, le principe reste le même.
Mise en fonction d'un Anémomètre - Français - Arduino Forum

J'ai lu et essayé d'adapter et utiliser le code selon ma problématique et mesures mais aucun résultat...

Je suis novice dans Arduino donc je peux être long à la détente et je reste... perdu.
Pouvez-vous m'expliquer "en détail" afin de m'aider ?

Merci

pepe:
Bonjour

Il faudrait préciser si l'on te demande de donner la vitesse moyenne à la fin du parcours ou bien la vitesse instantanée.

Excusez-moi, il s'agit du calcul de la vitesse instantanée, j'ai oublié de le préciser !

En d'autres termes, je dois relever le temps de l'impulsion Haute avec micros() (comment?) puis faire la relation v = d/t avec comme valeur la distance le périmètre de ma roue et le temps la valeur obtenue ?

pepe:
C'est en quelque sorte une pendule, pas un chronomètre.

Déjà j'allais dans le mur donc c'est bon à savoir ! :smiley:

millis() / micros() tout dépend aussi de la vitesse attendue (surtout la précision)

Bonjour !

Tout d'abord merci pour vos réponses qui m'ont été déjà d'une grande aide.
Lors de mon affichage sur l'écran du moniteur série, je ne retrouve aucun problème. Néanmoins, lorsque j'envoie une valeur sur mon TFT Screen Touch V2.0 de Seeed Studio, la valeur ne s'écrit pas. Il faut que j'actualise l'affichage pour que la valeur change d'elle-même. Auriez-vous un moyen que ça s'actualise automatiquement sans qu'on ai besoin de rappuyer sur l'écran ?

Mon code à l'heure actuel, pour visualiser mon erreur :

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>
#include <SeeedTouchScreen.h>
#define VITESSE 340
#include <SoftwareSerial.h>

/*On utilise dans notre projet une Arduino Mega 2560.
On adapte alors la carte.*/

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
#define YP A2   
#define XM A1   
#define YM 54   
#define XP 57   

#endif

int captroue = 22;
int passage = 0;
int etat = 0;
int mes = 0;
int distance = 7;
const int USTrig = 8; // Déclencheur sur la broche 8
const int USEcho = 9; // Réception sur la broche 9
const int buzzer = 13;
unsigned long ancienTemps;  // mémorisation de la dernière mesure de temps
unsigned long periode;      // mémorisation de la période calculée
char ancienEtatCapteur;     // mémorisation du dernier état du capteur
const unsigned long periodeMax = 5000000 ; /* période maximale, en microsecondes, correspondant à 
l'affichage d'une vitesse nulle */
const unsigned long constanteVitesse = 13571680; /* dépend du diamètre de la roue et des unités d'affichage
de la vitesse (par exemple 113097336 fois le diamètre de la roue en mètres pour une vitesse
exprimée en dixièmes de km/h) */

TouchScreen ts = TouchScreen(XP,YP, XM, YM);

void setup() {
  Serial.begin(9600);
  pinMode(captroue, INPUT);
  pinMode(USTrig, OUTPUT); 
  pinMode(USEcho, INPUT);
  pinMode(buzzer, OUTPUT);
  ancienEtatCapteur = digitalRead(captroue);
  periode = periodeMax;
  
  TFT_BL_ON;
  Tft.TFTinit();
  
  Tft.drawString("Ewee-PT",60,10,3, YELLOW);
  Tft.drawHorizontalLine(60,34,128,YELLOW);
  
  Tft.drawString("Etat de la batterie",10,65,2,WHITE);
  
  Tft.fillRectangle(55,92,129,40, WHITE); //Dessin du fond de la batterie
  Tft.fillRectangle(184,110,2,4, WHITE);
  
  Tft.drawHorizontalLine(60,140,120, RED);
  
//=================Boutton Distance=================//

  Tft.fillRectangle(5,150,70,50,RED);
  Tft.drawString("Dist.",10,175,2,WHITE);
  
  
//=================Boutton Vitesse=================//
  
  Tft.fillRectangle(85,150,70,50,BLUE);
  Tft.drawString("Vit.",90,175,2,WHITE);
  
//=================Boutton Obstacle=================//
  
  Tft.fillRectangle(165,150,70,50,GREEN);
  Tft.drawString("Auto.",170,175,2,WHITE);
  
  Tft.drawString("Projet Ewee des STI2D2",0,310,1,WHITE);

}

#define MINPRESSURE 10    //Il va relever toute les pressions
#define MAXPRESSURE 1000  //0 serait trop sensible au minimum

void loop() {
  
  //=Compte le nombre de passage et affiche la distance parcourue=//   
   
  if(passage < 10000){
  boolean mes = digitalRead(captroue); // mesure du capteur
  delay(5);                            // Temps d'attente de 5ms
  boolean etat = mes;                  // Retranscription de la mesure par HIGH ou LOW
  if (etat == LOW)                     // Si l'état est bas
  {passage ++;                         // On rajoute +1 au nombre de passage
   delay(50);}                         // temps d'attente de 50ms pour ne pas créer de fausse mesures
  }
  else
  {}
  
  float distance = 0.3768 * passage;   //Distance = périmètre X nb de Passages
  
//======Calculer et afficher la vitesse instantanée======//

// teste si un front montant est survenu sur l'entrée capteur
  char nouvelEtatCapteur = digitalRead(captroue);
  if (nouvelEtatCapteur && !ancienEtatCapteur) {
    // calcule le temps écoulé depuis le précédent front
    unsigned long nouveauTemps = micros();
    periode = nouveauTemps - ancienTemps;

    // mémorise l'heure pour le prochain calcul
    ancienTemps = nouveauTemps;
  }
  ancienEtatCapteur = nouvelEtatCapteur;

  // calcul de la vitesse
  int vitesse;
  if (periode>=periodeMax){
    vitesse = 0;}
  else
    {vitesse = constanteVitesse/periode;
     vitesse = vitesse / 10;} 

//========Définition des dimensions de l'afficheur========//
  
  Point p = ts.getPoint();

    p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
    
    //Code afin de tester le tactile de l'écran
    /*if (p.z > __PRESURE) {
     Serial.print("Raw X = "); Serial.print(p.x);
     Serial.print("\tRaw Y = "); Serial.print(p.y);
     Serial.print("\tPressure = "); Serial.println(p.z);}*/
     
//==========Afficher un texte pour chaque bouton==========//
    
    if (p.y > 153 && p.y < 197 && p.x > 8 && p.x < 72) { //Si on détecte une pression dans cette zone :
     
     Tft.fillRectangle(1,207,239,83,BLACK); //Affiche un rectangle noir afin de clear les écritures
     Tft.drawString("Distance :",5,210,2,RED);
     Tft.drawFloat(distance, 2, 60, 240, 3, RED);
     Tft.drawChar('m', 220, 243, 2, RED);}
     
     if (p.y > 153 && p.y < 197 && p.x > 88 && p.x < 153) { //Si on détecte une pression dans cette zone :
     
     Tft.fillRectangle(1,207,239,83,BLACK); //Affiche un rectangle noir afin de clear les écritures
     Tft.drawString("Vitesse :",5,210,2,BLUE);
     Tft.drawFloat(2.16, 2, 60, 240, 3, BLUE);
     Tft.drawString("km/h", 190, 243, 2, BLUE);}
     
     if (p.y > 153 && p.y < 197 && p.x > 168 && p.x < 232) { //Si on détecte une pression dans cette zone :
     
     Tft.fillRectangle(1,207,239,83,BLACK); //Affiche un rectangle noir afin de clear les écritures
     Tft.drawString("Autonomie :",5,210,2,GREEN);
     Tft.drawNumber(2, 60, 240, 3, GREEN);
     Tft.drawString("hrs", 200, 243, 2, GREEN);}

La fin de mon code est utilisé pour les valeurs qu'ont mes collègues à relevés (il s'agit d'un projet de groupe). N'étant que novice (et j'ai peur de dire une bêtise), il faudrait que je créer des autres void afin de ne pas ralentir le système ?

Pour le TFT, j'aurais pensé à la fonction "while". Mais elle ne serait active que lorsque j'appuie sur le bouton choisi donc j'avoue que ça me pose une colle...

Merci pour votre aide en tout cas qui m'est très utile que ce soit pour trouver la solution mais aussi les explications afin de comprendre mes erreurs ! :slight_smile: