//Logger_Carbu_AFR_010521 //Dérivé de Injection_LoggerV3.0_071220Mod_050321 //Alterne log/arret par toute touche du clavier //Peut sauter des étincelles avant d'ecrire la SD //LogNetin K :log après K=1 ou 2 (chaque tour moteur) ou 3 ou 4 ...étincelles, //N<7000 evite parasite sur front montant //Pas ce pb sur front descendant //Mesure Nt/mn et AFR //Transmet ces données via Bluetooth et possibilté d'enregistrement sur carte SD //Affiche sur Sphone, toutes les AffPer secondes //Les 2 modes à entrer au clavier du smartphone //'l' l_og ( l_ancer le log) .Le log continuera jusqu'à l'entrée de "a" au clavier //'a' a_rreter le log //La carte SD contient un seul fichier texte, NextR.txt qui contient //une unique valeur,i, le N° du prochain Run. //Ensuite les fichiers de Run se nomment i.csv, avec i++ à chaque Run, au format Excel //Polling sur Cible, pas d'IT //Pour ajouter un champs:AffLigne(), puis dans LogPrep() voir StringHeader //puis dans PrepLigne() ajouter à Ligne=.. /////////////////////////1 VALEURS AJUSTABLE/////////////////////////// unsigned long AffPer = 2; //Periode de l'affichage sur Sphone en secondes #define LogNetin 4 //log après 1 ou 2 ou 3 ou 4 ...étincelles //////////////////////////////////////////////////////////////// #include"TimerOne.h" #include //Pour carte SD #include #include //Pour Bluetooth BT File myFile; //Un objet myFile de type File est créé SoftwareSerial BT(7, 8); // RX,TX respectivement vers le HC05/06 à 115200bps #define Cible 2 //D2 front montant pour une étincelle, fonctionne mal ave le descendant #define AFR A1 //0 à 5V fourni par sonde lambda large bande Innovate #define CS 9 //Chip Select du circuit de la carte SD #define LedRun 4 //Led ON pendant un run unsigned long prec_H = 0; //Compteur de µs float T = 0; // Entre deux éticelles, typique 5ms à 6000t/mn unsigned long N = 0; //N en t/mn byte AFRv = 0; //Valeur de AFR entre 74 et 221 int AFRu = 0; //AFR en unités 0-1023 byte RunF = 0; //Flag etat d'un run: 0pas de run, 1 en cours float Dcum = 0; //Cumul pour calcul durée d'un run. String Ligne = ""; //Sera ecrite dans la SD signed long Val = 0; //Entier tapé au clavier int RunNb = 0; //N° de run, toujours croissant, initialisé depuis NextR.txt String RunFile = ""; //C'est le nom du fichier contenant le run "RunNb.xls" ex 21.xls char carLu; // Stock le car lu float AffPerMic = 0;//Periode d'affichage en µs byte LogPrem = 1; // Flag de Premier log, pour initialiser la carte SD unsigned long CtAff = 0; //Compteur pour affichage unsigned long Temps = 0; //le temps durant le run unsigned long Hdr = 0; //Heure début de run en ms char careLu;//car relu de la carte SD unsigned long CtC = 0;//Compteur de car relus int CtEtin = 0; //Compteur d'étincelle comparé à LogNetin //************************************************************* void setup() ///////////////////////////////////////////////////// { Serial.begin(115200); //Pour moniteur PC Serial.println("Hello"); Serial.println(); BT.begin(115200); //Pour Sphone, Bluetooth BT.println(F("****************************")); BT.println(F("Logger pour AFR")); Serial.println(F("Hello world")); BT.println(F("****************************")); // Tst_BT(); //Boucle infinie pour test liaison BT BT.println(F("l pour Lancer le log")); BT.println(F("a pour Arreter le log")); delay(5000); pinMode(Cible, INPUT_PULLUP); //Vient du moins bobin, front montant AffPerMic = AffPer * 1000000; //Periode d'affichage en µs pinMode(LedRun, OUTPUT);// } //********************************************* void AffLigne()//Sur Sphone et PC////////////////////////////////////// { //Serial.println("****Essais Logger AFR****"); BT.println("****Essais Logger AFR****"); Serial.println(); BT.println(); Serial.print(F("N t/mn ")); Serial.println(N); BT.print(F("N t/mn ")); BT.println(N); BT.print(F("AFR ")); BT.println(AFRv); if (RunF == 1) { BT.print(F(" Run N° ")); BT.println(RunNb); //N° de run BT.print(F("En cours ")); BT.println(); } } void Dialog()/////////////////////////////////////////////////////// { if (BT.available() <= 0)return; //Pas de car de dialogue tapé, sortir carLu = BT.read();//Lire le car tapé char carS = carLu; //Sauver ce car while (BT.available() != 0)carLu = BT.read(); //Purge BT.println(carS); if (RunF == 0)LogPrep(); else RunTerminer(); // switch (carS) //a pour Arret, l pour Log sans specifier de durée // { // case 'a': RunTerminer(); break;//Arret du run // case 'l': LogPrep(); break; //Lance un run // default : Serial.println(); BT.println(); Serial.println("?"); BT.println("?"); delay(3000); return; //Erreur, mais continuer run // } } void InitSDcard()///////////////////////////////// { Serial.print(F("Initializing SD card...")); BT.println(F("Initialisation de la carte SD")); if (!SD.begin(CS)) { //Chip Select = 1 si carte OK*************************** Serial.println(F("initialization failed!")); BT.println(F("Initialisation impossible, vérifier la carte SD")); BT.println(F("Relancer le programme")); while (1); //Rester bloqué ici } else { BT.println(F("initialization OK")); Serial.println(F("initialization OK")); } delay(2000); // Créer le fichier des numeros de log s'il n'existe pas if (SD.exists("NextR.txt") ) { //************************************* Serial.println(F("NextR.txt existe")); BT.println(F("NextR.txt existe")); } else { myFile = SD.open("NextR.txt", FILE_WRITE);//Le creer myFile.println(String( 1) );//Avec RunNb =1 myFile.close(); } LogPrem = 0; //Pour ne pas revenir dans cette fonction } void Lec_AFR()/////////////////////////////////////////// { AFRu = analogRead(AFR); //1v correspond à 2.92 points d'AFR + 7.4 AFRv = map(AFRu, 0, 1023, 74, 221); // AFR valeur entre 7.4 et 22.1 } void LecRunNb()///////////////////////////////////////////////////// { //Lire depuis NextR.txt le numero RunNb du prochain Run myFile = SD.open("NextR.txt");//Ouvert pour lecture seulemnt et non WRITE char carLu; // Stock le car lu String L = ""; //Accumule les car reçus de la carte SD if (myFile) { while (myFile.available()) { carLu = myFile.read();//Lecture de 1 car delay(100); //Indispensable ? if ((carLu == 13 ) || (carLu == 10)) break;//Sortir L = L + carLu; //cumuler } RunNb = L.toInt();//Conversion en entier de la chaine de caractères } myFile.close(); } void LogPrep()//////////////////////////////////////////////////////////// { if (LogPrem == 1)InitSDcard(); //Initialiser la carte SD, bloquera si problème //Lire le numero de run RunNb, seul enregistrement du fichier NextR.txt LecRunNb();// SD.remove("NextR.txt");//MàJ du N° de run, effacer l'ancien fichier // car on veut écrire en première position myFile = SD.open("NextR.txt", FILE_WRITE);//Le recreer myFile.println(String(RunNb + 1) );//Avec RunNb++ myFile.close(); Serial.print("Lancement du Run "); Serial.println(RunNb); BT.print("Lancement du Run "); BT.println(RunNb); BT.println("Run en cours"); Serial.println("Run en cours"); delay(3000); //Création du nouveau fichier pour le run qui démarre, d'abord son nom, ex "21.xls" RunFile = String(RunNb) + ".csv";//Composer le nom du fichier run à demarrer myFile = SD.open(RunFile, FILE_WRITE); myFile.println(" Logging N et AFR www.loutrel.org "); myFile.println("; ; ; ; ; ; ; ; ; ; ; ;"); //Leading blank line String header = "Temps ms;Nt/mn ;AFR";// les entêtes de colonnes myFile.println(header);// ensuite les lignes seront ajoutées par EcrireLigne() Dcum = 0; //Calcul de la durée Hdr = millis(); //Heure de début de run Temps = millis() - Hdr; //Temps ecoulé en ms depuis le debut du run RunF = 1; //Demarre Run digitalWrite(LedRun, 1); delay(1000); // myFile.close();//Enregistre le fichier des lignes******************************************************************** // Serial.println(header); while(1); } void PrepLigne() //Lecture de toutes les entrées, affichage ou stockage////////////////////////////////// { while (digitalRead(Cible) == 0); //attente du passage à 1 de la cible T = micros() - prec_H; // Cible arrivée prec_H = micros(); //Nouvelle heure de reference N = 30000000 / T; //N en t/mn if (N < 7000) { Lec_AFR(); CtAff = CtAff + T; //cumul les temps if (CtAff >= AffPerMic) { //Afficher toutes les AffPer secondes CtAff = 0; AffLigne(); } if (RunF == 1) //Run en cours { CtEtin++; //une étincelle de plus if (CtEtin == LogNetin) //Log après LogEtin étincelle, si atteint on ecrit la SD { Ligne = String(Temps) + ";" + String(N) + ";" + String(AFRv) + ";"; myFile.println(Ligne); //Ecrire la carte SD, sans la fermer CtEtin = 0; //Reset } Dcum = Dcum + T; //Pour afficher la duree en fin de run Temps = millis() - Hdr; //Temps ecoulé en ms depuis le debut du run // delay(1); Dialog(); //Voir si arret demandé } } while (digitalRead(Cible) == 1);//Option:oui ou non attendre fin du 1 de la cible c'estpareil! } void RunTerminer()//////////////////////////////////////////////////////////// { myFile.close();//Enregistre le fichier des lignes myFile = SD.open(RunFile); //Le reouvrir pour compter les car while (myFile.available()) { //La relire en entier careLu = myFile.read(); CtC++;//Compter les car // Serial.write(myFile.read());// Recopie la ligne courante ************ } myFile.close();//End of File encountered, stop reading**************** BT.println(F("Run termine: numero, duree en s, nb de caractères ")); Serial.println(F("Run termine: numero et duree en s ")); BT.println(RunNb); Serial.println(RunNb); BT.println(Dcum / 1000000); Serial.println(Dcum / 1000000); BT.println(CtC); Serial.println(CtC); //Si <200 rien d'enregistré! delay(5000); RunF = 0; //Pas de run en cours digitalWrite(LedRun, 0); } void loop() ////////////////////////////////////////////////////////////////////////// { PrepLigne();//Attend cible puis affiche N et AFR Dialog(); //Voir si car entré au clavier } void Tst_BT() //Ceci est un test de BT, à lancer depuis setup()/////////////////// { int BTdata = 0; //**************Vers PC Serial.println("Bonjour "); Serial.println("Le caractere entre sur l'Android doit se retrouver ci dessous"); //***************Vers module BT.println(" "); BT.println(" "); BT.println("Bonjour sur Android"); BT.println(" "); BT.println("HC05, la led doit clignoter 2 flash, 1s Off, 2flash..."); BT.println(" "); BT.println("HC06, led On fixe"); BT.println(""); BT.println("Entrer un caractere "); BT.println("S'il se retouve sur le PC, tout va bien..."); while (1) { if (BT.available()) //Car pret en entrée sur Serie soft? { BTdata = BT.read(); //oui, le clavier Android BT a émis un car BT.println(" ");//Aller à la ligne sur sphone Serial.write(BTdata);//ecrire le car sur le PC Serial.println(); } } }