Besoin d un petit coup de main :D

Salut tout le monde il y a quelque chose qui cloche dans mon code de programmation Arduino Uno , en faite j essaie de mesurer le nombre de tours d une roue dont je lui est colle 4 aimant avec un capteur a effet hall.

#include <Wire.h>
volatile unsigned long beginntime;
volatile unsigned long periode ;
volatile unsigned endtime;
unsigned int nbtour ;
volatile unsigned int impulse;

void setup() {
Serial.begin(9600);
pinMode(2,INPUT);
pinMode(2,INPUT_PULLUP);
nbtour=0;


attachInterrupt(0,timer,RISING); //reagiere auf steigende Flanken auf PIN 2

}
void timer (){
  beginntime=millis();
  periode=(beginntime-endtime);
  endtime =beginntime;
  impulse++;//( ce compteur c est pour la prochaine Etape pour compter la moyenne apres chaque tours ( apres la detektion des 4 aimants )  )
}
void loop(){
  if ( periode >=0){
    nbtour= 30*1000/periode;
    Serial.println(" nbtour ");
    Serial.print(nbtour);
  }
  
  
}

Mon probleme c est qu au debut j recoit les 4 premieres valeurs fausses et apres un petit bout de temps le compteur se remet a donner des 0 .
Vos avis me serviraient enormement .
Merci

speedtest.PNG

teste2.PNG

hello
alors 18 dents ou 4 tops au tour ?

prg déjà donné ICI en #7, (mais il faut lire les réponses que tu sollicites)

unsigned long top_1ere_dent; // le temps debut pour la deuxiemer messure
volatile unsigned long top_18eme_dent; // le temps ecoule
volatile byte  nombre_dents; // compteur de dents
int vitesse; //nombre de tours par minute
unsigned long temps_au_tour;
void setup() 
{
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
vitesse=0;
top_18eme_dent=0;
nombre_dents=0;
attachInterrupt(0,isr_impulsion,FALLING) ;// 
}

void isr_impulsion(){nombre_dents++;}

void loop() 
{
  if (nombre_dents==1){top_1ere_dent=millis();}
  if (nombre_dents==18)
      {
        top_18eme_dent=millis(); // le temps ecoule
        nombre_dents=0;
        temps_au_tour = (top_18eme_dent-top_1ere_dent);
        vitesse = (60000/temps_au_tour);
        Serial.print("vitesse tr/mn : ");Serial.println(vitesse); // le nombre de tours
      }
      }

Salut , en faite je vais devoir le realiser sur une roue dente de 18 dents mais tout d abord je dois effectuer la mesure sur une roue avec 4 aimant pour pouvoir bien modifier et bien ajuste mon programme , ce que je fais la maintenant c est juste des test pour verifier la valeur des mesures .
je dois calculer le nombre de tours pour chaque detection du capteur et apres je deverais calculer la moyenne.
Mon calcule doit consister sur le calcul a chaque changement d etat ( attachinterrupt) et apres la detectiond des 4 ou bien des 18 dents je ferais d en sorte de calculer la moyenne .
Es ce que vous avez compris le concept ?

18 dents = 18 interruptions pour 1 tour
4 aimants= 4 interruptions pour 1 tour

dans le prg, au lieu de

if (nombre_dents==18) tu mets if (nombre_dents==4)

je dois calculer le nombre de tours par rapport a un seul passage d une dent a une autre tout d abord et non pas apres un passage de 4 dents par exemple , a la premier detection mon programme calculera cb le nombre de tour par rapport a la premiere interruption

ok, (verifié avec un générateur de fréquences)

unsigned long top_depart; // le temps debut pour la deuxiemer messure
unsigned long top_fin; // le temps ecoule
volatile byte  nombre_tops; // compteur de dents
long vitesse; //nombre de tours par minute
unsigned long temps_estime_au_tour;
int nb_cames = 18; //mettre 18 ou 4
void setup() 
{
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
vitesse=0;
top_fin=0;
nombre_tops=0;
attachInterrupt(0,isr_impulsion,FALLING) ;// 
}

void isr_impulsion(){nombre_tops++;}

void loop() 
{
  if (nombre_tops>=1)
      {
        top_fin=micros(); 
        temps_estime_au_tour = (((top_fin-top_depart) * nb_cames)/1000);
        vitesse = (60000/temps_estime_au_tour);
        Serial.print("temps_estime_au_tour ");
        Serial.print((temps_estime_au_tour));
        Serial.print("_ms   nombre tr/mn : ");
        Serial.println(vitesse);     
        nombre_tops=0;top_depart=micros();
      } 
 }

C est exactement ce que je viens de faire , mais ce que je comprends pas c est en divison sur le nombre de dents totale je recois des valeurs fausse , non pas dans mon code uniquement mais pareil avec ton code aussi je viens de la verifier

temps_estime_au_tour = (((top_fin-top_depart) * nb_cames)/1000); fausse

temps_estime_au_tour = (((top_fin-top_depart) /1000) ; ca marche
et en multipliant par 30 et non pas par 60 :confused:

Merci enormement de m avoir donner de ton temps

fausse ne veut rien dire,

quelle fréquence appliques tu sur D2 et quelle valeur s'affiche sur cette ligne?

temps_estime_au_tour = (((top_fin-top_depart) * nb_cames)/1000); fausse

Serial.print("temps_estime_au_tour ");Serial.print((temps_estime_au_tour));

temps_estime_au_tour = (((top_fin-top_depart) /1000) ; ca marche
et en multipliant par 30 et non pas par 60 :confused:

nous parlons du même code ?

quelle est ta façon de tester?

je verifie la valeur nb tour a l aide d un tachometre optique et je compare avec les resultats que j ai sur mon moniteur
avec ton code je recois 160tr/min au lieu de 400 tr/min et avec le mien aussi :S

il y a un problème chez toi

chez moi : générateur de fréquences sur 40 hertz et nb dents = 4 dans prg

donc période=25ms entre 2 dents donc pour 4 dents il faudra 100ms et 4 dents c’est 1 tour.

1 seconde / 100ms = 10 tours par seconde. et pour 1 minute il faut multiplier par 60

10*60=600 tr par minute

je te joins le prg tel qu’il est( affichage modifié)
et une copie d’écran

unsigned long top_depart; // le temps debut pour la deuxiemer messure
unsigned long top_fin; // le temps ecoule
volatile byte  nombre_tops; // compteur de dents
long vitesse; //nombre de tours par minute
float temps_estime_au_tour;
int nb_cames = 4; //mettre 18 ou 4
void setup() 
{
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
vitesse=0;
top_fin=0;
nombre_tops=0;
attachInterrupt(0,isr_impulsion,FALLING) ;// 
}

void isr_impulsion(){nombre_tops++;}

void loop() 
{
  if (nombre_tops>=1)
      {
        top_fin=micros(); 
        temps_estime_au_tour = (((top_fin-top_depart) * nb_cames)/1000);
        vitesse = (60000/temps_estime_au_tour);
        Serial.print("temps_estime_au_tour ");
        Serial.print((temps_estime_au_tour));
        Serial.print(" ms ");
        Serial.print(vitesse);Serial.println(" tr/mn");     
        nombre_tops=0;top_depart=micros();
      } 
 }

et avec 18 dents

voir copie écran

Oui oui j en ai pour environ 186 ms une valeur de 300 tr/min , c est plus logique je crois que mon tachometre est pourri je vais essayer d ici lundi d avoir un autre .
en faite je compte faire la moyenne apres chaque tours cela veut dire apres 4 detection ; j essayer la de declare une variable save =0 et :
if (nouvcompteur <=4){
save= save+vitesse;

}
moyenne= save/4;

je te remercie enormement de ton Aide !

attention

si tu dois avoir des vitesses de rotation importantes, il faudra alléger l'affichage sur l'écran

par exemple n'afficher que la valeur de la vitesse mais virer tout ce qui est texte

ok Merci beaucoup et bon week end mon ami :wink: