/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**************** PROGRAMME de MESURE **********************
************ régime moteur et temps de marche cumulé **********
librairies Tachometer & EEPROM
objectif mesure régime de rotation de 1600 a 3600 t/mn
temps de marche en heure et minutes
version mesure du temps avec millis
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
// Librairies
#include <Tachometer.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
Tachometer tacho; // création d'objet tacho de type tachymetre
// Définir un objet (lcd1) de type LiquidCrystal_I2C
LiquidCrystal_I2C lcd1 (0x27, 20, 4); // adresse I2C du LCD1 : 0x27 sur 4 lignes de 20 chars
int inputPin = 2; // borne entrée (borne alternateur W ! 14V AC)
int currInput = 0; // Mem état courant entrée
int prevInput = 0; // Mem état précédent entrée
int outputPin = 13; // borne sortie
bool Marche = false; // Mémoire Marche
bool auxMarche = false; // Mémoire auxiliaire Marche (Front Montant)
// variables pour Temporisation arrêt
unsigned long prevTime = 0; // Temps précédent
unsigned long currTime = 0; // Temps courant = millis
unsigned long Tempo = 1000; // valeur Temporisation arret
// variables pour mesure du Temps de Marche
int Seconde = 0; // base de temps
int Minute ; // total minutes du temps de Marche
int Heure ; // total heures du temps de Marche
unsigned long previousMillis = 0; // Temps précédent
unsigned long currentMillis; // Temps courant = millis
const long interval = 1000; // 1000 ms = 1 s
char str_Temps[20]; // chaine de 20 caractères pour affichage temps de marche sur LCD
char str_Regime[20]; // chaine de 20 caractères pour affichage régime de rotation sur LCD
int address = 0; // adresse de base EEPROM
void setup() {
Serial.begin(9600); // Initialise serial communication
pinMode(inputPin, INPUT_PULLUP); // ! faire un pulldown matériel pour implantation réelle
pinMode(outputPin, OUTPUT); // sortie pour Test et simulation
// mise en place d'une interruption sur Front Descendant
attachInterrupt(digitalPinToInterrupt(inputPin), isr, FALLING);
//tacho.setWindow(20); // Définition du nombre de révolutions (tick) pour le calcul de la moyenne (par defaut 10)
//tacho.setTimeout(2000); // temps d'attente d'interruption (ms), apres quoi la rotation est considéré commme arrété
lcd1.init(); // Initialiser l'écran LCD
lcd1.backlight(); // Allumer l'éclairage de l'écran
lcd1.clear(); // Effacer le LCD
lcd1.setCursor(0, 0); // Placer le curseur à la position caractère, ligne
lcd1.print("Temps de Marche"); // Afficher le msg sur LCD
// Rechargement valeur temps sauvegardées en EEPROM au reset de la carte
Heure = EEPROM.read(address);
Minute = EEPROM.read(address + 1);
// ======================================
// Pour une implantation réelle
// d'abord initialisez une fois l'EPROM a 0 h 0 mn dans le setup d'un autre programme
// a lancer une fois avant de charger le code de ce programme
// sinon l'EPROM est remplie de 255 par défaut (tout les bits a 1)
// int zero = 0;
// EEPROM.write(address, zero);
// EEPROM.write(address + 1, zero);
// ======================================
// 4 lignes programme suivantes pour simulaton seulement ++++++++++++++++
// !!!! a supprimer pour implantation réelle !!!
Heure = 1 ; // valeur quelconque pour test
Minute = 25 ; // valeur quelconque pour test
EEPROM.write(address, Heure);
EEPROM.write(address + 1, Minute);
// fin de pour simulation seulement ++++++++++++++++++++++++++++++++++++++
}
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
// Gestionnaire d'interruption
void isr() {
tacho.tick(); // nous informons la bibliotheque du Front Descendant sur entrée
}
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
void loop() {
currInput = digitalRead(inputPin); // memoriser etat entrée
currTime = millis(); // maj Temps courant
// =============== AFFICHAGE Régime sur LCD ========================
static uint32_t tmr;
if (millis() - tmr > 1000) { // toute les secondes maj régime de rotation
tmr = millis();
lcd1.setCursor(0, 2); // Placer le curseur à la position caractère, ligne
lcd1.print("Regime:");
lcd1.setCursor(8, 2); // Placer le curseur à la position caractère, ligne
sprintf(str_Regime, "%4u t/mn ", tacho.getRPM()); // composition de la chaine formaté
lcd1.print(str_Regime); // affiche Régime (str_Regime) sur LCD
//Serial.println(tacho.getRPM()); // RPM
//Serial.println(tacho.getHz()); // frequence en Hz
//Serial.println(tacho.Us()); // période en microseconde
// =============================================================
}
// oooooooooo Test Marche ooooooooooooooooooooooooooooooooo
if (prevInput == 0 && currInput == 1) { // test Front montant sur entrée
Marche = true; // Set Marche a vrai
digitalWrite(outputPin, HIGH); // Set sortie a 1
prevTime = currTime; // maj temps précédent
}
if (currTime - prevTime >= Tempo && currInput == 0) { // si entré a 0 et Temporisation finie
Marche = false; // Set Marche a faux = Arret
digitalWrite(outputPin, LOW); // Set sortie a 0
}
// oooooooooooooooooooooooooooooooooooooooooooooooooooooo
// Si Front montant sur Marche (démarrage) alors rechargement valeur sauvegardé en EEPROM
if (Marche == true & auxMarche == false) {
Heure = EEPROM.read(address);
Minute = EEPROM.read(address + 1);
}
currentMillis = millis(); //maj Temps courant = millis
if (currentMillis - previousMillis >= interval) { // chaque seconde
previousMillis = currentMillis; // mise a jour temps courant
updateClock(); // appel fonction calcul temps
}
// XXXXXXXXX a supprimé dans montage réel XXXXXXXXX
if (Marche == true ) { // si Marche est vrai ( = en marche)
// Serial.print("Temps de marche: ");
// Serial.print(Heure);
// Serial.print(" h ");
// Serial.print(Minute);
// Serial.println(" mn");
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
if (Marche == false) { // si Marche est faux ( = arret)
EEPROM.write(address, Heure); // Sauver heures temps de marche en EEPROM
EEPROM.write(address + 1, Minute); // Sauver minutes temps de marche en EEPROM
}
// =============== AFFICHAGE TEMPS LCD ========================
sprintf(str_Temps, "%2u h %2u mn ", Heure, Minute); // composition de la chaine formaté
lcd1.setCursor(3, 1); // Placer le curseur à la position caractère, ligne
lcd1.print(str_Temps); // affiche Temps de Marche (str_Temps) sur LCD
// =============================================================
prevInput = currInput; // mise a jour etat précédent entrée
auxMarche = Marche ; // mise a jour auxMarche por Front montant
}
// ===== Routine mesure temps =====
void updateClock() {
if (Marche == true) {
Seconde = Seconde + 1;
if (Seconde > 59) {
Seconde = 0;
Minute = Minute + 1;
}
if (Minute > 59) {
Minute = 0;
Heure = Heure + 1;
}
}
}
// ===================================ON
OFF