Télémétrie sur quad 350 Banshee à l'aide d'arduino

Bonjour à tous,

MISE A JOUR : Le capteur avant et arrière sera un capteur à réluctance variable comme les capteur PMH en automobile, donc besoin d'aide pour la programmation etc... car il donne une tension sinusoïdale

Ma première passion étant le mx (quad, motos cross) donc circuit terre, je possède d'ailleurs un 350 Banshee et ma deuxième l'électronique et plus particulièrement en pansant par arduino j'ai donc décidé de réunir mes deux passions pour faire un projet :smiley: !

La télémétrie consiste à prendre tout une série de mesure en course, mais moi la mesure principale dont j'ai besoin de votre aide c'est pour l'antipatinage.

Je vous explique :
J'aimerais mesurer ma vitesse de rotation de mes roues arrière et en même temps la vitesse de rotation de mes roues avant, pour conclure que si il y a une différence de plus de 10tr/min entre les deux c'est qu'il y a patinage. (Jusque la tout le monde me suit ? J'essaye de faire simple et en même temps précis)

Le problème c'est que l'arduino ne peut pas mesurer ces deux vitesses en mêmes temps ... donc pour une simple question d'expérience professionnel on va d'abord mesurer la vitesse de rotation des roues arrières puis celle à l'avant.

vitesse maximum des roues avant et arrière : 2500 tr/min

Pour faire une petite comparation :
-la vitesse des roues avant me donne la vitesse réele de mon véhicule
-la vitesse des roues arrière me donne la vitesse de mon véhicule si il y à 0% de patinage
Donc sachant que c'est sur terre et qu'il y a toujours du patinage je met une tolérance de 10tr/min

Passons maintenant à la partie Acquisition de donnée :
-vitesse roue arrière :
Roue dentée (60 dents) avec capteur fourche optique comme ça j'ai une sortie 0 ou 1 !

-vitesse roue avant :
C'est la que ça ce complique .... Je pensais faire comme l'arrière mais à l'avant sachant que les roues sont directionnelles et avec la terre et les cailloux je pense que ça n'ira pas ... Donc quel solution avez vous à me proposer ?
Je pensais passé par un module GPS mais il me faut des retour d'expérience pour savoir si c'est assez précis (Je me servirai uniquement de l'info vitesse)

Partie Programme :
Dans un premier temps j'ai fait un programme avec pour capteur une fourche optique à l'arriere et une à l'avant (c'st pour voir ce que ça donné mais à l'avant il faudra trouver autre chose)

volatile int NbTopsFanAV;
volatile int NbTopsFanAR;
int CalcAV;
int CalcAR;
int fourcheoptiqueAV = 2;
int fourcheoptiqueAR = 3;

void setup()//
{ 
  pinMode(fourcheoptiqueAV, INPUT);
  pinMode(fourcheoptiqueAR, INPUT);
  attachInterrupt(0, rpmAV, CHANGE);
  attachInterrupt(1, rpmAR, CHANGE);
  pinMode(13, OUTPUT);
} 

void rpmAV (){ 
  NbTopsFanAV++;  
} 

void rpmAR (){ 
  NbTopsFanAR++;
} 

void loop(){
    NbTopsFanAR = 0;
  sei();
  delay (1000);
  cli();
  CalcAR = (NbTopsFanAR * 60); 
  
  NbTopsFanAV = 0;
  sei();
  delay (1000);
  cli();
  CalcAV = (NbTopsFanAV * 60);
  
    if (CalcAR-CalcAV >= 10)
  {
    digitalWrite(13, HIGH);
  }
  else
  {
    digitalWrite(13, LOW);
  }

}

Le problème attendre 1 sec pour calculer la vitesse des roues arrière et 1 sec de plus pour calculer la vitesse des roues avant c'est beaucoup trop long ...

Donc si vous avez des idées ou même des solutions je suis preneur :slight_smile:

Merci à tous d'avoir pris le temps de me lire !!

bonjour,
pour l'avant, c'est une idée comme ca, pourquoi ne pas mettre un capteur sur l'étrier de frein à disque avec un capteur optique.
au passage d'un trou, on a 1, sinon 0
une coquille pour protéger le capteur situé derrière l'étrier, les plaquettes retirent la boue à chaque tour, donc le trou est en principe libre.
sur le même principe, percage d'un trou dans le disque avec un aimant qui va passer devant le capteur à chaque tour.

quand au GPS pour savoir si tu patine, je vois pas comment tu peux faire :slight_smile:

Les ABS utilisent des capteurs magnétiques et une roue dentée et il doit y avoir une bonne raison. Comme par exemple que c'est insensible à la poussière et à la boue.

bonjour
là le gps est parfaitement inexploitable pour resoudre le probleme :grin:

une approche "assez" simple serait peut etre d'utiliser en amont des convertisseurs en F to V , genre TC940X

Déjà merci à tous d'avoir répondu :slight_smile:

infobarquee:
bonjour,
pour l'avant, c'est une idée comme ca, pourquoi ne pas mettre un capteur sur l'étrier de frein à disque avec un capteur optique.
au passage d'un trou, on a 1, sinon 0
une coquille pour protéger le capteur situé derrière l'étrier, les plaquettes retirent la boue à chaque tour, donc le trou est en principe libre.
sur le même principe, percage d'un trou dans le disque avec un aimant qui va passer devant le capteur à chaque tour.

quand au GPS pour savoir si tu patine, je vois pas comment tu peux faire :slight_smile:

Le probleme avec le capteur optique c'est qu'il faut un emeteur et un recepteur donc un d'un coté du disque et un de l'autre coté cela m'embete un peu .. si il y aurait que d'un coté cela m'arrangerai mais avec le capteur optique c'est pas possible enfin je ne pense pas...

fdufnews:
Les ABS utilisent des capteurs magnétiques et une roue dentée et il doit y avoir une bonne raison. Comme par exemple que c'est insensible à la poussière et à la boue.

Admettons que je mettre une roue dentée au niveau de mon moyen avant (c'est tout à fait possible) mais ce que tu appels capteur magnétique ce sont les inductif à 2 fils qui crée leur propre tension en fonction du passage de la dent ou ce sont les capteur à effet hall à 3 fils qui neccessite obligatoire un aimant ?

Artouste:
bonjour
là le gps est parfaitement inexploitable pour resoudre le probleme :grin:

une approche "assez" simple serait peut etre d'utiliser en amont des convertisseurs en F to V , genre TC940X

Je n'ai pas très bien compris l'interet d'utilisé un convertisseur fréquence/tension avant l'arrivé dans Arduino

Je vais vous expliquez pourquoi le module GPS est une alternative à la mise en place d'un capteur à l'avant :
Admettons ma roue avant fait 1tr en 1sec : 1tr/sec, si le developpé de ma roue fait 1m cela veut dire que je fais 1m en 1sec : 1m/sec ce qui est facile à convertir en km/h (info du GPS)
Je fais le même prinpie pour l'arrière, je compare ma vitesse arrière (km/h) à celle du GPS (km/h) et si je patine ma vitesse arrière sera plus grande que ma vitesse GPS
Tout le monde à compris le principe ?

mallomotors:
...
Admettons que je mettre une roue dentée au niveau de mon moyen avant (c'est tout à fait possible) mais ce que tu appels capteur magnétique ce sont les inductif à 2 fils qui crée leur propre tension en fonction du passage de la dent ou ce sont les capteur à effet hall à 3 fils qui neccessite obligatoire un aimant ?

Artouste:
bonjour
là le gps est parfaitement inexploitable pour resoudre le probleme :grin:

une approche "assez" simple serait peut etre d'utiliser en amont des convertisseurs en F to V , genre TC940X

Je n'ai pas très bien compris l'interet d'utilisé un convertisseur fréquence/tension avant l'arrivé dans Arduino

Je vais vous expliquez pourquoi le module GPS est une alternative à la mise en place d'un capteur à l'avant :
Admettons ma roue avant fait 1tr en 1sec : 1tr/sec, si le developpé de ma roue fait 1m cela veut dire que je fais 1m en 1sec : 1m/sec ce qui est facile à convertir en km/h (info du GPS)
Je fais le même prinpie pour l'arrière, je compare ma vitesse arrière (km/h) à celle du GPS (km/h) et si je patine ma vitesse arrière sera plus grande que ma vitesse GPS
Tout le monde à compris le principe ?

En vrac
Sur le pourquoi du GPS inexploitable là :grin:
documente toi sur les "xDop" GPS :grin:

pour les capteurs utilisés en meca "milieu hostile" , la captation est souvent faite avec des capteurs à reluctance magnetique"
un lien rapidement parcouru -andré abadia-articles techniques-: Le capteur inductif à réluctance variable
sur le pourquoi passer (eventuellement) par un un FCV = tu decharge le MCU de l'integration du signal, tu n'a "juste qu'a" lire des valeurs V "presentées"

Donc petite mise à jour :
-Dans un premier temps on oublie le module GPS :stuck_out_tongue:
-Dans un deuxième temps pour la suite du projet on va prendre un capteur à réluctance variable idem au capteur PMH en automobile, avec surement un trigger de schmitt derrière pour passer d'un signal sinusoidale à un signal rectangulaire de même fréquence que le sinusoidale

Donc petite question :
Grâce à ce type de capteur est-ce possible de mesure une vitesse de rotation faible ?
Car lors du démarrage avec le quad mes roues arrières vont patiner mais mes roues avant auront un régime de rotation très faible ...

Encore un grand merci à tous !!

Le problème c'est que l'arduino ne peut pas mesurer ces deux vitesses en mêmes temps ...

Ah bon ....
Deux capteurs qui génèrent des fronts reliées sur deux PIN avec interruption, tu fais un comptage simultané ds capteurs des deux roues et tu moulines le tout avec un timer pour obtenir une vitesse de rotation. Je suis convaincu que ça fonctionne.

Le problème avec le capteur optique c'est qu'il faut un émetteur et un récepteur donc un d'un coté du disque et un de l'autre coté cela m’embête un peu .. si il y aurait que d'un coté cela m'arrangerai mais avec le capteur optique c'est pas possible enfin je ne pense pas...

Pas obligatoirement, des capteurs intègrent l'émission optique et la réception optique. Un peu comme une fourche optique.

avec surement un trigger de schmitt

Simple question : deux diodes pour écrêter le signal (en 0 / +5V) sur l'arduino ne pourrait-il pas suffire ? (voir page 75 doc ATMEL328) . Ainsi on laisse VIL et VIH transformé le sinus en carré. (voir page 313 datasheet ATMEL 328)
J'ai souvenir d’avoir déjà utilisé cette méthode.

Bon courage pour ton projet

Merci pour ta réponse :slight_smile:

De toute façon pour le principe du capteur optique on a dit qu'on laissé de côté cette solution, on va partir sur un capteur à réluctance variable style capteur PMH en automobile.

On ma dit que sachant que l'arduino avait qu'un seul processeur on ne pouvait donc pas faire deux chose en même temps.... mais peut être comme tu le dit avec les interruptions c'est peut être différent ... Quelqu'un pour confirmer ?

En revanche j'ai bien trouvé le Datasheet avec les donées de VIL et VIH page 333 maisj'ai pas trouvé la doc dont tu me parle (page 75) ... si tu pouvais m'aider :slight_smile:

Et personne ne sais si le capteur à réluctance variable fonctionne bien même à faible vitesse de rotation ?

De toute façon pour le principe du capteur optique on a dit qu'on laissé de côté cette solution, on va partir sur un capteur à réluctance variable style capteur PMH en automobile.

Pas de soucis, c’était simplement à titre informatif.

On ma dit que sachant que l'arduino avait qu'un seul processeur on ne pouvait donc pas faire deux chose en même temps.

TRUE !!
Un seul processeur mais cadencé à 16Mhz !!! donc tu peux faire du pseudo "multi tâche"
Dans la routine d'IT, tu ne mets que des valeurs à incrémenter et tu traiteras plus tard dans un loop.
Et peu de chance que deux IT arrive pile au même moment. Et même si c'est le cas, tu as une priorité et zou tralalou !!

En revanche j'ai bien trouvé le Datasheet avec les donées de VIL et VIH page 333 maisj'ai pas trouvé la doc dont tu me parle (page 75) ... si tu pouvais m'aider smiley

Page 75 tu as le schémas d'entrée des PIN I/O de l'arduino et notamment deux diodes qui protége cette étage en écrêtant le signal entre 0V et +5V. En gros tu mets une sinusoïde -1V / +6V , sur ton entré tu auras un "carré" (ou plutôt un sinus avec la tête coupée) 0V / +5V.
Je dis carré au sens ou tu as les tensions VIL et VIH.

Et personne ne sais si le capteur à réluctance variable fonctionne bien même à faible vitesse de rotation ?

Faut voir la datasheet du capteur. Voir la plage de fréquence

Oui oui je me douté bien que c'était à titre informatif

J'avais qu'avec une cadence de 16Mhz même si il ne peut pas traité deux chose en même temps vu sa cadence ultra rapide ça sera quasiment du simultané :stuck_out_tongue: Merci à toi !

En automobile le capteur PMH donc à RV sa tension varie entre 250mV et 1V au ralenti soit envrion 1 000-1 500tr/min et moi ma vitesse de rotation de mes roues sera de grand GRAND maximum 2500tr/min donc la tension sinusoïdale variera entre 250mV et je pense maximum 2V 2,5V donc utilisé VIL et VIH ne conviendrait pas alors si ?!

utilise un capteur inductif pour la roue avant et un autre pour la roue arriere.
chacun sur une entrée interruptive.
pour l'arduino uno, il s'agit des pin 2 et 3, qui déclent les interruption 0 et 1.
remet a zero le codeur apres un temps defini.

en gros, ça donne:

void setup() {
  ...
  attachInterrupt(0, ICodeur, CHANGE); // sur pin2, front montant et descendant
  ...
}
void loop() {
  delay(1000);
  Vitesse = CodeurVal;
  CodeurVal = 0;
  vitesse = CodeurVal / nb_pt_par_tours * 60  // en tours par minutes
  Serial.println(Vitesse);
}

void ICodeur() {
  CodeurVal++;
}

En automobile le capteur PMH donc à RV sa tension varie entre 250mV et 1V au ralenti soit envrion 1 000-1 500tr/min et moi ma vitesse de rotation de mes roues sera de grand GRAND maximum 2500tr/min donc la tension sinusoïdale variera entre 250mV et je pense maximum 2V 2,5V donc utilisé VIL et VIH ne conviendrait pas alors si ?!

tu peux amplifier, mais autant utiliser le trigger qui fera tout ça en un étage :slight_smile:

jean-I:
utilise un capteur inductif pour la roue avant et un autre pour la roue arriere.
chacun sur une entrée interruptive.
pour l'arduino uno, il s'agit des pin 2 et 3, qui déclent les interruption 0 et 1.
remet a zero le codeur apres un temps defini.

en gros, ça donne:

void setup() {

...
 attachInterrupt(0, ICodeur, CHANGE); // sur pin2, front montant et descendant
 ...
}
void loop() {
 delay(1000);
 Vitesse = CodeurVal;
 CodeurVal = 0;
 vitesse = CodeurVal / nb_pt_par_tours * 60  // en tours par minutes
 Serial.println(Vitesse);
}

void ICodeur() {
 CodeurVal++;
}

J'ai aussi fait ce même type de programme avec les interruptions regarde : (mais je pense qu'il y a quelques petites choses qui vont pas dans le mien ...

volatile int NbTopAV;
volatile int NbTopAR;
int CalcAV;
int CalcAR;
int AV = 2;
int AR = 3;

void setup()//
{ 
  pinMode(AV, INPUT);
  pinMode(AR, INPUT);
  attachInterrupt(0, rpmAV, CHANGE);
  attachInterrupt(1, rpmAR, CHANGE);
  pinMode(13, OUTPUT);
} 

void rpmAV (){ 
  NbTopAV++;  
} 

void rpmAR (){ 
  NbTopAR++;
} 

void loop(){
    NbTopAR = 0;
  sei();
  delay (1000);
  cli();
  CalcAR = (NbTopAR * 60); 
  
  NbTopAV = 0;
  sei();
  delay (1000);
  cli();
  CalcAV = (NbTopAV * 60);
  
    if (CalcAR-CalcAV >= 10)
  {
    digitalWrite(13, HIGH);
  }
  else
  {
    digitalWrite(13, LOW);
  }

}

Mais le problème c'est qu'il attend 1sec pour le calcul à l'AV et 1sec pour le calcul à l'AR soit un total de 2sec avant que ma led (indicateur de patinage) s'allume or ce délai est beaucoup trop long pour moi :frowning:

derder9161:

En automobile le capteur PMH donc à RV sa tension varie entre 250mV et 1V au ralenti soit envrion 1 000-1 500tr/min et moi ma vitesse de rotation de mes roues sera de grand GRAND maximum 2500tr/min donc la tension sinusoïdale variera entre 250mV et je pense maximum 2V 2,5V donc utilisé VIL et VIH ne conviendrait pas alors si ?!

tu peux amplifier, mais autant utiliser le trigger qui fera tout ça en un étage :slight_smile:

Donc puisqu'il faudra convertir ce signal sinusoidale en signal rectangulaire on utilisera un trigger :smiley:

pepe:
Bonjour

mallomotors:
En automobile le capteur PMH donc à RV sa tension varie entre 250mV et 1V au ralenti soit envrion 1 000-1 500tr/min et moi ma vitesse de rotation de mes roues sera de grand GRAND maximum 2500tr/min donc la tension sinusoïdale variera entre 250mV et je pense maximum 2V 2,5V donc utilisé VIL et VIH ne conviendrait pas alors si ?!

Les signaux avec de tels niveaux de tension (faibles et variables) doivent être impérativement préconditionnés pour être traités comme des signaux logiques (i.e. niveaux VOL et VOH), ou bien convertis pour être traités comme des signaux numériques (i.e. plusieurs bits représentatifs).

En effet, une amplitude inférieure au volt implique nécessairement une amplification, compte tenu du fait qu'un simple écrêtage (comme indiqué plus haut) n'est pas envisageable. Toutefois, l'électronique incluse dans l'ATmega de l'Arduino pourrait éventuellement en réaliser une partie.

Il faudrait quoi qu'il en soit connaître les spécifications du capteur utilisé (datasheet ?) afin de le mettre en œuvre correctement. Il serait aussi important de précisé si le capteur est utilisé simultanément dans un autre circuit.

Et même avec un trigger de Schmitt on est obligé de passer par un amplificateur avant ? C'est vrai que 250mV c'est faible il faudra l'amplifié ..

Et non le capteur sera utilisé uniquement pour ça donc il n'est pas utilisé simultanément dans un autre circuit

Pour le capteur utilisé y'en existe plein mais lequel choisir ... Aucune idée mais ça sera un capteur inductif 2 fils (donc qui fourni sa propre tension)

Un ptit peu d'aide pour choisir le capteur ne serait pas de refus :slight_smile:

PS : Pour info je possède l'arduino ATMega 2560 R3

Dans ton code tu utilises 2 compteurs et ensuite tu fais la différence

  CalcAR = (NbTopAR * 60); 
  
  NbTopAV = 0;
  sei();
  delay (1000);
  cli();
  CalcAV = (NbTopAV * 60);
  
    if (CalcAR-CalcAV >= 10)

Si tu n'utilises pas leur valeurs par ailleurs, il serait bien plus simple de n'avoir qu'un compteur. Incrémenté dans une des routines de traitement d'IT et décrémenté dans l'autre.

Si tu maintiens l'usage de 2 compteurs il n'est pas nécessaire de faire la calcul sur 2 fois une seconde.
Tu remets les 2 compteurs à zéro, tu actives les IT et tu attends une seconde. L'ATmega est capable de gérer 2 IT qui ne sont pas particulièrement rapide.

Autre problème
CalcAR = (NbTopAR * 60);
CalcAV = (NbTopAV * 60);
if (CalcAR-CalcAV >= 10)

Cela revient à écrire
(NbTopAR * 60) - (NbTopAV * 60) >= 10
qui peut s'écrire
(NbTopAR-NbTopAV) * 60 >= 10
ce qui donne
(NbTopAR-NbTopAV) >= 10/60=1/6
Tes variables sont des entiers donc la comparaison ne peut pas fonctionner puisque l'écart cherché est inférieur à 1

De toutes les façons avec ça comme donnée d'entrée
NbTopAR * 60 et NbTopAV * 60
La plus petite différence que tu pourras chiffrer sera >= à 60.

si tu ne veut pas un code bloquant, il ne faut pas utiliser delay, mais la fonction millis par exemple.
l'utilisation de sei et cli n'est pas primordial dans ton cas. l'interdiction des interruption ne devrai avoir cours que lors des modif des valeur codeurs (tu peut eventuelement meme t'en abstenir selon la precision):

  ...
  cli();
  CalcAR = (NbTopAR * 60); 
  NbTopAR = 0;
  sei();
  delay (1000);
  ...

ai bien en tete qu'au niveau assembleur, un code de type "CalcAV = (NbTopAV * 30);" sera compilé en plusieur instructions machine, et pourrai etre interrompu en cours de traitement. c'est pourquoi il vaut mieu ecrire si tu n'utilise pas sei et cli:
CalcAV = NbTopAV;
NbTopAV = 0;
CalcAV = CalcAV * 30;

les codeurs étant interruptifs, une seule boucle de 1 secondes suffit pour les deux.
tu peut meme passer par une fenetre glissante de 10x.01 secondes, pour etre reactif en "quasi-live-time".
l'interrution en CHANGE suppose 2 appels par tour, du coup, le *60 pour avoir des tours minutes ne devrai pas etre bon (en supposant que tu ai un top par tour).

volatile int NbTopAV;
volatile int NbTopAR;
int CalcAV;
int CalcAR;
int AV = 2;
int AR = 3;
unsigned long TimeCapture = 0;

void setup()//
{ 
  pinMode(AV, INPUT);
  pinMode(AR, INPUT);
  attachInterrupt(0, rpmAV, CHANGE);
  attachInterrupt(1, rpmAR, CHANGE);
  pinMode(13, OUTPUT);
} 

void rpmAV (){ 
  NbTopAV++;  
} 

void rpmAR (){ 
  NbTopAR++;
} 

void loop(){
  //TimeCapture = millis();  //maj au 1er passage dans le if ci dessous
  if (millis() >= (TimeCapture+1000)) {  // forcement vrai au 1er passage
    cli();
    CalcAR = (NbTopAR * 30); 
    NbTopAR = 0;
    CalcAV = (NbTopAV * 30);
    NbTopAV = 0;
    sei();
    TimeCapture = millis();
  }
  //  delay (1000);

    if (CalcAR-CalcAV >= 60)
  {
    digitalWrite(13, HIGH);
  }
  else
  {
    digitalWrite(13, LOW);
  }

}

bien vu fdufnews.
pour un suivi de la différence, il faudra quand meme re-mettre a zero reguilerement, sous peine d'avoir une erreur qui ne sera jamais rattrapée.

mallomotors:
...

Pour le capteur utilisé y'en existe plein mais lequel choisir ... Aucune idée mais ça sera un capteur inductif 2 fils (donc qui fourni sa propre tension)

Un ptit peu d'aide pour choisir le capteur ne serait pas de refus :slight_smile:

bonjour
là tu prend le probleme à l'envers = le choix du 'meilleur" capteur decoulera du choix mecanique.

la resolution utilisable decoulera du chois de la roue dentée = pluss le nombre de dents sera elevé, plus la resolution sera grande

et entre un top/tour et x tops/tour , il y des compromis pragmatiques à faire

fdufnews:
Dans ton code tu utilises 2 compteurs et ensuite tu fais la différence

  CalcAR = (NbTopAR * 60); 

NbTopAV = 0;
 sei();
 delay (1000);
 cli();
 CalcAV = (NbTopAV * 60);
 
   if (CalcAR-CalcAV >= 10)



Si tu n'utilises pas leur valeurs par ailleurs, il serait bien plus simple de n'avoir qu'un compteur. Incrémenté dans une des routines de traitement d'IT et décrémenté dans l'autre.

Si tu maintiens l'usage de 2 compteurs il n'est pas nécessaire de faire la calcul sur 2 fois une seconde.
Tu remets les 2 compteurs à zéro, tu actives les IT et tu attends une seconde. L'ATmega est capable de gérer 2 IT qui ne sont pas particulièrement rapide.

Autre problème
CalcAR = (NbTopAR * 60);
CalcAV = (NbTopAV * 60);
if (CalcAR-CalcAV >= 10)

Cela revient à écrire
(NbTopAR * 60) - (NbTopAV * 60) >= 10
qui peut s'écrire
(NbTopAR-NbTopAV) * 60 >= 10
ce qui donne
(NbTopAR-NbTopAV) >= 10/60=1/6
Tes variables sont des entiers donc la comparaison ne peut pas fonctionner puisque l'écart cherché est inférieur à 1

De toutes les façons avec ça comme donnée d'entrée
NbTopAR * 60 et NbTopAV * 60
La plus petite différence que tu pourras chiffrer sera >= à 60.

Merci pour ta réponse ! A mon avis je ne connais pas et maîtrise pas toutes les finalités des interruptions sur Arduino donc si quelqu'un a un lien ou un fichier qui developpe plus en profondeur les interruptions sur Arduino je suis preneur !! :slight_smile:

Donc pour répondre à tes questions :
-Non je n'utilise pas ces valeurs par ailleurs, donc si tu pouvais m'en dire plus sur incrémenter et décrémenter je ne dirais pas non :wink:
-Si tu dis que l'usage des deux compteurs n'est pas obligatoire je suis d'accord pour changer de méthode

Et pour le problème que tu as trouvé aucun soucis j'avais mis la valeur de 10 comme ça mais une fois monté sur la machine j'avais prévu un nombre compris entre 60 et 100 donc le problème est résolu :smiley:

jean-I:
si tu ne veut pas un code bloquant, il ne faut pas utiliser delay, mais la fonction millis par exemple.
l'utilisation de sei et cli n'est pas primordial dans ton cas. l'interdiction des interruption ne devrai avoir cours que lors des modif des valeur codeurs (tu peut eventuelement meme t'en abstenir selon la precision):

  ...

cli();
 CalcAR = (NbTopAR * 60);
 NbTopAR = 0;
 sei();
 delay (1000);
 ...




ai bien en tete qu'au niveau assembleur, un code de type "CalcAV = (NbTopAV * 30);" sera compilé en plusieur instructions machine, et pourrai etre interrompu en cours de traitement. c'est pourquoi il vaut mieu ecrire si tu n'utilise pas sei et cli:
CalcAV = NbTopAV;
NbTopAV = 0;
CalcAV = CalcAV * 30;

les codeurs étant interruptifs, une seule boucle de 1 secondes suffit pour les deux.
tu peut meme passer par une fenetre glissante de 10x.01 secondes, pour etre reactif en "quasi-live-time".
l'interrution en CHANGE suppose 2 appels par tour, du coup, le *60 pour avoir des tours minutes ne devrai pas etre bon (en supposant que tu ai un top par tour).



volatile int NbTopAV;
volatile int NbTopAR;
int CalcAV;
int CalcAR;
int AV = 2;
int AR = 3;
unsigned long TimeCapture = 0;

void setup()//
{
 pinMode(AV, INPUT);
 pinMode(AR, INPUT);
 attachInterrupt(0, rpmAV, CHANGE);
 attachInterrupt(1, rpmAR, CHANGE);
 pinMode(13, OUTPUT);
}

void rpmAV (){
 NbTopAV++;  
}

void rpmAR (){
 NbTopAR++;
}

void loop(){
 //TimeCapture = millis();  //maj au 1er passage dans le if ci dessous
 if (millis() >= (TimeCapture+1000)) {  // forcement vrai au 1er passage
   cli();
   CalcAR = (NbTopAR * 30);
   NbTopAR = 0;
   CalcAV = (NbTopAV * 30);
   NbTopAV = 0;
   sei();
   TimeCapture = millis();
 }
 //  delay (1000);

if (CalcAR-CalcAV >= 60)
 {
   digitalWrite(13, HIGH);
 }
 else
 {
   digitalWrite(13, LOW);
 }

}




bien vu fdufnews.
pour un suivi de la différence, il faudra quand meme re-mettre a zero reguilerement, sous peine d'avoir une erreur qui ne sera jamais rattrapée.

Merci à toi aussi pour ta réponse !!

-Dans un premier temps je voulais un code non bloquant car je passé par deux boucle de 1sec ce qui était trop long pour moi mais maintenant (grâce à vous tous :D) que je sais que je peux faire le même programme mais avec une seule boucle de 1sec cela me convient ! :slight_smile:
Je connaissais la fonction millis() mais de la manière dont tu l'as utilisé dans mon code je connaissais pas mais je trouve ça très interessant !! +1 pour ma culture générale (euh... arduino :stuck_out_tongue: )

-Deuxièmement tu dis que je peux me passer des sei() et cli() donc dans le même code si je supprime ces deux fonctions il n'y aura pas de problème ?

-La fênetre glissante 10x.01 ...Hmmmm tu peux m'en dire plus ? je ne connais pas du tout :open_mouth:

-Oui exact concernant le *30 mais je paufinerai ça à la fin du programme enfin quand la structure sera présente

J'ai pas très bien compris quand tu parles de remettre à zero la différence etc... il peut ce passer quoi comme problème qui ne sera jamais rattrapable ? Genre il faudrait à chque fois avec de faire les calcul remettre CalcAR et CalcAV à 0 ?

pepe:
Tout dépend de l'amplitude du signal d'entrée et de l'hystérésis du trigger.

À titre d'exemple, voici ce qu'on peut faire avec l'ATmega328 d'un Arduino Uno sans aucun circuit actif supplémentaire : le schéma suivant montre comment réaliser 4 entrées multiplexées avec trigger de Schmitt, pour des capteurs inductifs isolés (en cas de masse imposée, des condensateurs sont insérés en série avec les capteurs).

L'hystérésis des triggers est réalisée par commutation logicielle des résistances de rappel internes, et les seuils sont détectés tour à tour par la fonction "comparateur" du micro-contrôleur. La lecture et le basculement des triggers sont réalisés par polling, à une cadence pouvant attendre 500000 lectures par seconde.

Ce type de solution est parfaitement envisageable si les traitements réalisés par ailleurs dans le programme sont suffisamment rapides et présentent des délais contrôlés.

Malheureusement, sur l'Arduino Mega, le signal AIN0 n'est pas disponible sur les connecteurs. Le comparateur devrait dans ce cas utiliser la référence interne (VBG) sur son entrée +, ce qui impose de fixer la tension du point commun du circuit externe à une valeur équivalente avec une précision compatible avec l'amplitude des signaux.

Il me paraît prématuré d'annoncer des caractéristiques électriques alors que la référence du capteur n'est pas encore définie.

Il me paraît d'ailleurs tout aussi prématuré de fixer sa technologie, alors que celle-ci n'est pas nécessairement la mieux adaptée. Un simple capteur inductif qui fournit sa propre tension, c'est 0 V à l'arrêt, et donc une absence d'information au démarrage et à basse vitesse.

bonjour
là tu prend le probleme à l'envers = le choix du 'meilleur" capteur decoulera du choix mecanique.

la resolution utilisable decoulera du chois de la roue dentée = pluss le nombre de dents sera elevé, plus la resolution sera grande

et entre un top/tour et x tops/tour , il y des compromis pragmatiques à faire

Je vous donne plus d'information concernant les caractéristique dimentionnelle et technique du capteur :

ATTENTION : J'ai plus plusieurs mesure sur mon Banshee et ça va changer le capteur à choisir ...
Etant donné que les roues sont de petites tailles l'espace entre l'ensemble moyeu/pivot/étrier/disque est bien trop inssufisant pour monté en plus une roue dentée et un capteur au dessus face à ces dents :frowning:
Mais une bonne nouvelle malgrès tout :slight_smile: Sur mes disques de frein avant comme arrière il y a 8 ouvertures (voir fichier joint)

Donc je reviens sur une décision du début et pourquoi pas utiliser la fourche optique, j'en ai déjà deux chez moi j'ai essayé et ça va nickel !! :smiley:

Plus qu'a terminer le programme ! :wink:

Voici des capteurs qui me convienne d'un point de vue montage, qu'est-ce que vous en pensez ? (Le Datasheet est dans fiche technique) :
-Style réflecteur optique :
*Réflecteur optique ITR9908 - Interrupteurs optiques | GO TRONIC
*http://www.gotronic.fr/art-reflecteur-optique-tcrt5000-21002.htm

-Style fourche optique :
*Interrupteur optique GP1A57HRJ00F Sharp - Interrupteurs optiques | GO TRONIC
*Interrupteur optique LTH301-32 - Interrupteurs optiques | GO TRONIC

Je possède actuellement 2 capteurs comme ceci à la maison :
*Capteur de vitesse de rotation par fourche optique

Comme je l'ai dit plus haut, le problème des fourches optiques c'est qu'elle ne sont pas du tout copines avec la poussière et la boue. Donc tu risques de perdre assez rapidement l'information de vitesse.

les capteurs optiques, ça marchera... chez toi, dans ton garage. tu auras tot ou tard (plus tot que tard) des problemes du a l'obturation par des poussieres, terre, boues. ce sera jute bon pour un test.

si tu utilise sei() et cli(), tu as interdiction des IT entre
CalcAR = (NbTopAR * 30);
NbTopAR = 0;
il peut y avoir un top codeur entre, et tu l'aura perdu.

si tu te passe des sei() et cli(), tu pourrai avoir un top codeur entre
CalcAR = (NbTopAR * 30);
NbTopAR = 0;
et tu l'aura perdu quand meme car tu remet NbTopAR a 0.
dans ton cas, c'est loin d'etre grave.

vu que tu vas forcement perdre des top, tu finira par avoir un ecart (glissement) entre AR et AV. il vaut donc mieux remettre les compteur a zero regulièrement (0.5 à 1 sec?)
idem si tu compte par différence, une fois que t'as glissé, qu'est ce qui vas te recaler l'écart à zéro?

la fenetre glissante de 10x100ms sera du genre:

unsigned long ValCodeurAR[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int index = 0;
...
    //if (millis() >= (TimeCapture+1000)) {  // forcement vrai au 1er passage
    if (millis() >= (TimeCapture+100)) {  // 100ms
    ...
    ValCodeurAR[index] = NbTopAR;
    NbTopAR = 0;
    index++;
    if (index>=10) {index=0;}
    CalcAR =ValCodeurAR[0]+ValCodeurAR[2]+ValCodeurAR[3]+...+ValCodeurAR[7]+ValCodeurAR[8]+ValCodeurAR[9];
    CalcAR = (CalcAR * 30); 
...

tu reagis ainsi a 100ms, en fonction de ce qui c'est passé sur la derniere seconde.