Bonjour à tous,
Je suis sur un petit labo pour un tachymètre basé sur une sonde IR Model FC-51
Datasheet: http://silicontechnolabs.in/upload/I...0datasheet.pdf
J'ai testé une multitude de code basé sur attachInterrupt(0,isr,RISING);
le résultat RPM est instable, les écarts sont parfois énorme entre la précédent donné et la suivante.
J'ai trouvé sur code ici "Construction d'un tachymètre-dwellmètre"
http://forums.futura-sciences.com/el...wellmetre.html
Son fonctionnement est le suivant :
============================== ==============================
Le programme se base sur le statut du signal PIN OUT Digital
============================== ==============================
Echelle Temps utilisé : MicroSeconde : 1 Seconde = 1000000 MicroSeconde
Le calcul se base sur tempsDebutImpuls et tempsFinImpuls pour chaque état du PIN signal FC-45.
Le temps entre chaque signal est trouvé.
RPM est calculé -- toursMinute = 60000000/(dureeOn + dureeOff)
Une moyenne des 6 dernières valeurs toursMinute est effectuée pour plus de stabilité RPM
J'ai ajouté ceci :
Une moyenne des 7 dernières valeurs pour chaque variable dureeOn et dureeOff est effectuée pour afficher 0, lors de l'arrêt de l'interface en rotation en position sur repère ou hors repère.
Le code modifié :
J'ai effectué le labo sur un ventilo alimenté séparément.Code:// Branchements : // * LCD RS - UNO digital 7 // * LCD E - UNO digital 8 // * LCD DB4 - UNO digital 9 // * LCD DB5 - UNO digital 10 // * LCD DB6 - UNO digital 11 // * LCD DB7 - UNO digital 12 // * LCD R/W to ground // * LCD VSS to ground // * LCD VCC to 5V // * 100K resistor: // * Pin 1 to +5V // * Pin 3 to ground // * Pin 2 to LCD VO // * LCD LED- to ground // * LCD LED+ Résistance 220 Ohm to +5V - LED+[RRBBM]+5V // Capteur de proxymité IR FC-51 // * Pin VCC to +5V // * Pin GND to ground // * Pin OUT to UNO Digital 2 // Réglage depuis le potentiomètre "LED clignote au rythme des coupures du faisceau" // ============================================================ // Le programme se base sur le statut du signal PIN OUT Digital // ============================================================ // Echelle Temps utilisé : MicroSeconde : 1 Seconde = 1000000 MicroSeconde // Le calcul se base sur tempsDebutImpuls et tempsFinImpuls pour chaque état du PIN signal FC-45. // Le temps entre chaque signal est trouvé. // RPM est calculé -- toursMinute = 60000000/(dureeOn + dureeOff) // Une moyenne des 6 dernières valeurs toursMinute est effectuée pour plus de stabilité RPM // Une moyenne des 7 dernières valeurs pour chaque variable dureeOn et dureeOff est effectuée pour afficher 0 // lors de l'arrêt de l'interface en rotation en position sur repère ou hors repère. #include <LiquidCrystal.h> LiquidCrystal lcd(7,8,9,10,11,12); int PIN = 2; int inputState; int prevInputState=0; // configuration de l'état PIN unsigned long tempsDebutImpuls = 0; // valeur entier positif unsigned long tempsFinImpuls = 0; // valeur entier positif unsigned long dureeOn = 0; // valeur entier positif unsigned long dureeOff = 0; // valeur entier positif // RPM --> 6 Variables pour Moyenne moyTours float toursMinute = 0; int moyTours = 0; int moyTours0 = 0; int moyTours1 = 0; int moyTours2 = 0; int moyTours3 = 0; int moyTours4 = 0; int moyTours5 = 0; // 7 Variables pour Moyenne dureeOn unsigned int tM = 0; // valeur entier positif 0 à 65 535 unsigned int mT = 0; unsigned int mT0 = 0; unsigned int mT1 = 0; unsigned int mT2 = 0; unsigned int mT3 = 0; unsigned int mT4 = 0; unsigned int mT5 = 0; unsigned int mT6 = 0; unsigned int OldmT = 0; // Contiendra la dernière valeur mT unsigned int x; // variable dureeOn et dureeOff pour la fonction mDuree() int i = 1; // compteur pour affichage int min_microsec = 30; // 0.003 sec. int max_microsec = 300000; // 0.3 sec. String String1; const int maxRPM = 3000; // Bar expriment moyTours en % - valeur max // Caractères personnalisés byte DIV_0_OF_5[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B00000, B00000 }; // 0 / 5 byte DIV_1_OF_5[8] = { B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 }; // 1 / 5 byte DIV_2_OF_5[8] = { B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 }; // 2 / 5 byte DIV_3_OF_5[8] = { B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 }; // 3 / 5 byte DIV_4_OF_5[8] = { B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 }; // 4 / 5 byte DIV_5_OF_5[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 }; // 5 / 5 void setup() { lcd.begin(16, 2); setup_progressbar(); pinMode(PIN, INPUT); Serial.begin(9600); } void loop() { // Détection Etat PIN inputState = 0 - pas de Détection inputState = 1 inputState = digitalRead(PIN); // Détection d'un front montant if (inputState == HIGH && prevInputState == 0){ tempsDebutImpuls = micros(); dureeOff = micros()- tempsFinImpuls; prevInputState = 1; x = dureeOff; mDuree(); // Lecture entre 100 et 100000 t/min if (dureeOff > min_microsec && dureeOff < max_microsec){ moyennes(); } } // Détection d'un front descendant if (inputState == LOW && prevInputState == 1){ tempsFinImpuls = micros(); dureeOn = micros()- tempsDebutImpuls; prevInputState = 0; x = dureeOn; mDuree(); // Lecture entre 100 et 100000 t/min if (dureeOn > min_microsec && dureeOn < max_microsec){ moyennes(); } } // Compteur d'affichage if(i==1){affichage();} i ++; // On affiche sur le LCD toutes les 40'000 boucles loop if(i==40000){i=1;} } // Calcule des moyennes lors des changements d'état de l'entrée void moyennes(){ toursMinute = 60000000/(dureeOn + dureeOff); // Calcul RPM sur 1 minutes moyTours5 = moyTours4; moyTours4 = moyTours3; moyTours3 = moyTours2; moyTours2 = moyTours1; moyTours1 = moyTours0; moyTours0 = toursMinute; moyTours = (moyTours0 + moyTours1 + moyTours2 + moyTours3 + moyTours4 + moyTours5)/6; } // Calcule de la moyenne sur les 7 dernières valeurs" dureeOn void mDuree(){ tM = x; mT6 = mT5; mT5 = mT4; mT4 = mT3; mT3 = mT2; mT2 = mT1; mT1 = mT0; mT0 = tM; mT = (mT0 + mT1 + mT2 + mT3 + mT4 + mT5 + mT6)/7; } void affichage(){ //displayBar(moyTours); // Front descendant // Si Moyenne dureeON = Old Moyenn dureeOff & Etat = 0 (hors repère) if (inputState == 0 && prevInputState == 0 && OldmT == mT) { moyTours = 0; } // Front montant // Si Moyenne dureeON = Old Moyenn dureeOn & Etat = 1 (hors repère) if (inputState == 1 && prevInputState == 1 && OldmT == mT) { moyTours = 0; } // timeout: On efface l'affichage si on n'a pas d'activité à l'entrée après 400 ms if ( (micros()- tempsDebutImpuls >= 400000)|| (micros()- tempsFinImpuls >= 400000)) { lcd.clear(); } lcd.clear(); lcd.setCursor(0, 0); lcd.print("RPM Tachometer "); lcd.setCursor(0, 1); lcd.print(moyTours); // Barre variable expriment RPM - // 25 = 20colonnes + 5 // map(value, fromLOW, fromHIGH, toLOW, toHIGH); // map (valeur, limite_basse_source, limite_haute_source, limite_basse_destination, limite_haute_destination); byte numOfBars=map(moyTours,0,maxRPM,0,25); lcd.setCursor(6, 1); if (moyTours!=0) { for (byte i=0; i<=numOfBars; i++) { lcd.setCursor(i+6,1); // En fonction du nombre de colonnes restant à afficher if (numOfBars == 0) { // Case vide lcd.write((byte) 0); } else if (numOfBars >= 5) { // Case pleine lcd.write(5); numOfBars -= 5; } else { // Derniére case non vide lcd.write(numOfBars); numOfBars = 0; } } } // Etat PIN lcd.setCursor(12, 1); String1 = "PIN"; lcd.print(String1 + inputState); // Serial.println('\n'); // Nouvelle ligne // Serial.println('\r'); // Retour chariot // Serial.println('\v'); // Tabulation vertical // Serial.println('\t'); // Tabulation horizontal // char buffer[200]; // Taille du cache pour les variables // sprintf(buffer,"RPM :%i\tEtat PIN2 :%i\t mT :%i\t dureeOn :%i\t dureeOff :%i\t tempsDebutImpuls :%i\t tempsFinImpuls :%i",moyTours,inputState,mT,dureeOn,dureeOff,tempsDebutImpuls,tempsFinImpuls); //sprintf(buffer,"tM :%i\tmT :%i\t mT0 :%i\tmT1 :%i\tmT2 :%i\tmT3 :%i\tmT4 :%i\tmT5 :%i",tM,mT,mT0,mT1,mT2,mT3,mT4,mT5); // Serial.println(buffer); // contient la prèdétente valeur mT afin de comparer avec mT OldmT = mT; } void setup_progressbar() { // Enregistre les caractères personnalisés dans la mémoire LCD lcd.createChar(0, DIV_0_OF_5); lcd.createChar(1, DIV_1_OF_5); lcd.createChar(2, DIV_2_OF_5); lcd.createChar(3, DIV_3_OF_5); lcd.createChar(4, DIV_4_OF_5); lcd.createChar(5, DIV_5_OF_5); }
Voici les vidéos :
https://www.youtube.com/watch?v=6Y8Nk7cgobg
https://www.youtube.com/watch?v=VRvulx0yXas
Jusque-là, tous va bien …
En remplaçant le ventilateur par un moteur DC de DVD ou un autre moteur DC type 775, le RMP par en cacahouète. Les écarts sont énormes puis des valeurs rpm négative aussi.
Est-ce que les aimants (champs magnétique) aurai une influence sur le capteur?
Une idée?
-----