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 !!
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
-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
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 !
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 )
-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
-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
Mais une bonne nouvelle malgrès tout 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 !!
Plus qu'a terminer le programme !
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