Bonjour,
je débute avec Arduino et je vous expose mon projet/problème.
je souhaite réaliser un compteur pour un deux-roues.
je voudrais y faire figurer :
*la température du moteur (facile avec une sonde dédiée).
*le régime moteur (capteur à effet Hall N°1)
*la vitesse du deux-roues (capteur à effet Hall N°2)
l'affichage se fera sur un écran de type Nextion.
je souhaite utiliser les interruptions, mais j'ai des difficultés à gérer deux interruptions en parallèle. Le capteur N°1 devrait mesurer une fréquence max de 14000 impulsions par minute tandis que le capteur N°2 aurait une fréquence max de 1200 impulsion par minute .
je travaille sur arduino pro micro (sparkfun), mais je peux utiliser aussi nano, uno ou mega (je ne suis pas sectaire).
Je ne vois pas trop ton problème. Les deux interruptions sont indépendantes, donc qu'il y en ait une ou deux c'est la même gestion.
En fait une interruption peut retarder légèrement l'autre (c'est pour ça que le traitement doit être le plus court possible), mais ça ne devrait pas avoir de conséquences.
La question qu'il faut se poser, compte tenu des fréquences des signaux à mesurer est est ce qu'il vaut mieux mesurer la fréquence ou la période pour avoir une meilleure résolution.
Merci pour ta réponse rapide Kamil,( et bravo pour la petite coccinelle de Gottlieb)
je craignais que, compte tenu des différences de fréquences, l'interruption N°1 n'"étouffe" la N°2 et n'empêche arduino de détecter les valeurs du capteur N°2.
J'ai déjà fait des essais avec des ventilateurs de pc en guise de capteur Hall, mais sans succès.
Que penses-tu de la commande detachInterrupt lors des phases de calcul ? est-ce une bonne option ou la fréquence de l'arduino (16MHz) permet-elle de faire le travail sans interruption du recueil de données ?
Non, il ne faut pas faire de detachInterrupt
Ton interruption va durer quelques microsecondes, voire quelques dizaines. Il faudrait que la fréquence l'autre signal soit supérieure à 100 kHz pour manquer des fronts.
Ta fréquence maxi est de 14000 impulsions par minute soit une période de l'ordre de 4 ms (si je ne me suis pas trompé), l'autre interruption a largement le temps de s’exécuter.
La question qu'il faut se poser, compte tenu des fréquences des signaux à mesurer est est ce qu'il vaut mieux mesurer la fréquence ou la période pour avoir une meilleure résolution
Bonjour,
peut-être en fonction des parasites :
s'il y en a peu, ils auront une faible incidence sur la mesure de fréquence
s'il y en a beaucoup, il vaut peut-être mieux mesurer les périodes pour pouvoir éliminer les valeurs incohérentes (voir les corriger si possible)
Je pensais faire la mesure sur une periode donnée ( par exemple 300ms mais je peux moduler). Mes isr ne consistant qu'à incrémenter un compteur (++)).
puis calculs pour frequences , affichage, vitesse....
Mes isr ne consistant qu'à incrémenter un compteur (++)
pas besoin, il y a des fonctions arduino pour cela
il ne resterait qu'à calculer pour avoir la fréquence
(et comme dit enlever auparavant une éventuelle valeur incohérente)
Ta fréquence maxi est de 14000 impulsions par minute soit une période de l'ordre de 4 ms
kamil ne s'est pas trompé, donc la fonction millis manquerait peut-être de précision pour déterminer la période entre 2 impulsions
il faudrait donc utiliser la fonction micros, qui charge assez l'avr, mais à vue de nez il restera assez de ressources pour ton appli
pour ta mesure à 1200/60 Hz la fonction millis sera suffisante
pour vérifier la cohérence des mesures, je suggère de faire une moyenne et d'éliminer les éventuels suspects : cela résoudrait également le problème - que tu crains, mais moi pas - des interférences entre les 2 interruptions
Je crois que je m'y perds un peu dans les solutions possibles ( interrupt, pas interrupt, timers, pulsein...).
Puis-je utiliser la fonction milli ou micro dans mon ISR ?
A mon avis, le plus simple avec des signaux pas trop rapides est d'utiliser les interruptions, soit pour mesurer la fréquence soit la période.
Oui tu peux utiliser millis() ou micros() dans les interruptions (pas pour faire des delais bien évidemment).
voilà une ébauche sommaire de mon code.
Les calculs ne sont pas finalisés, c'est juste pour le principe:
/////////////////
/// Nextion ///
/////////////////
#include <Nextion.h>// librairies Nextion
#include <SoftwareSerial.h>//librairie Nextion
SoftwareSerial nextion(8,9);//Tx pin 0 et Rx pin 1 Arduino
Nextion myNextion(nextion,9600);
//Rayon en mm pour la vitesse de translation
boolean front_rpm;
boolean front_pneu;
// Variable contenant la vitesse du moteur en rotations par minute
unsigned long rpm=0;
unsigned long vitesse=0;
long chrono_depart = 0; // valeur de départ du chrono
// Gestion de l'interruption 0 pin 3 rpm
void gere_int0() {
front_rpm=true;
}
// Gestion de l'interruption 1 pin 2 pneu
void gere_int1() {
front_pneu=true;
}
void setup ()
{ // Initialisation du port série
Serial.begin(9600);
myNextion.init();
chrono_depart = micros();
// l'interruption zero correspond à la pin 3
// on enregistre tous lorsque la broche passe de
//l'état HAUT vers l'état BAS (front descendant)
attachInterrupt(0,gere_int0,FALLING); //pin 3 interrupt0
attachInterrupt(1,gere_int1,FALLING); // pin 2 interrupt 1
}
void loop()
{
//changement de front rpm
if (front_rpm)
{
rpm=millis() - chrono_depart;
front_rpm=false;
//nombre d'impulsions par seconde
rpm =rpm*1000000 ;
// Affichage sur le port série
Serial.println("N="),Serial.print(rpm),Serial.print(" RPM, ");
myNextion.setComponentValue ("n1", rpm);
//Serial.print("V="),Serial.print(ms),Serial.println(" m/s");
chrono_depart=millis();
}
//changement de front pneu
if (front_pneu){
vitesse=millis() - chrono_depart;
front_pneu=false;
//nombre d'impulsions par seconde
vitesse = vitesse*1000000
// Affichage sur le port série
Serial.println("v="),Serial.print(vitesse),Serial.print(" m/s, ");
myNextion.setComponentValue ("n0", vitesse);
//Serial.print("V="),Serial.print(ms),Serial.println(" m/s");
chrono_depart=millis();
}
}
j'ai "élagué" le code au max, mais les résultats ne me semblent pas à la hauteur de mes espérances...
les valeurs retournées manquent de précision, j'ai donc effectué les mesures sur 500 ms, mais sans plus de succès.
Sinon, s'il n'y a pas de changement de sens, il y a des fonctions spécifiques du micro-contrôleur qui permettent de compter directement les impulsions (il faut regarder la datasheet du micro).
Je travaille sur des arduino pro micro de chez sparkfun.
Quelles sont ces fonctions specifiques dont tu parles dans ton dernier post 3Sigma ?
Dans mon code, je declenche un chrono avec millis après avoir déclaré mes interruptions. Quand mon chrono est à 500ms, je stoppe les interruptions, calcule les vitesses, affiche tout ça et réactive les interruptions.
Mais les resultats sont moyens....
cyberfwed:
Je travaille sur des arduino pro micro de chez sparkfun.
Quelles sont ces fonctions specifiques dont tu parles dans ton dernier post 3Sigma ?
cyberfwed:
Dans mon code, je declenche un chrono avec millis après avoir déclaré mes interruptions. Quand mon chrono est à 500ms, je stoppe les interruptions, calcule les vitesses, affiche tout ça et réactive les interruptions.
Mais les resultats sont moyens....
Pourquoi désactiver les interruptions ? Ca ne sert à rien.
Quand tu dis que les résultats sont moyens, concrètement ça signifie quoi ?