//Injection_Logger_AFR_281019 //Lit AFR, enrée sur le - bobine //4 fois plus de creneaux en entrée donc l'isr_Cible en tient compte //N et AFR ecrits sur une carte SD et les affiche sur Sphone, toutes les AffPer secondes unsigned long AffPer = 2; //Periode de l'affichage sur Sphone en secondes unsigned long DureeDef = 10;//Dures du log d'un run en secondes, quand non specifiée (mode 'L") #include"TimerOne.h" #include #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 //Cible AàC sur D2, Interruption 0 #define AFR A1 //0 à 5V fourni par sonde Innovate #define Led 13 //Celle de l'Arduino #define CS 4 //Chip Select du circuit de carte SD volatile byte Cycle = 0; //Flag de detection de la cible de PMH. "Volatile" indispensable!? volatile unsigned long prec_H = 0; //Compteur de µs float D720 = 0; // Durée du cycle en cours en µs, 720°vilo, 2 tours int 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 AffF = 0; //Flag On pour l'affichage au Sphone, Off en mode dialogue int RunActif = 0; //N° de run, 1,2,... byte RunF = 0; //Flag etat d'un run: 0pas de run, 1 en cours, 2 en pause unsigned long RunD = 0; //En µs durée requise unsigned long 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'estle nom du fichier contenant le run "RunNb.xls" ex 21.xls char carLu; // Stock le car lu String L = ""; //Accumule les carLu unsigned long AffPerMic = 0;//Periode d'affichage en µs byte CtC = 0; //Compteur de creneaux en entrée unsigned long AccC = 0; //Accumule 4 creneaux //************************************************************* void AffLigne()//Sur Sphone et PC { //Serial.println("****Essais injection Logger****"); BT.println("****Essais injection Logger****"); Serial.println(); BT.println(); Serial.print(F("N t/mn ")); Serial.println(N); BT.print(F("N t/mn ")); BT.println(N); Serial.print(F("AFR ")); Serial.println(AFRv); BT.print(F("AFR ")); BT.println(AFRv); } void Dialog() { if (BT.available() <= 0)return; //Pas de car de dialogue tapé, sortir AffF = 0; //QQchose a été tapé. Arreter l'affichage durant le dialogue carLu = BT.read();//Lit le car tapé char carS = carLu; //Sauver ce car while (BT.available() != 0)carLu = BT.read(); //Purge BT.println(carS); switch (carS) //d pour Durée, a pour Arret, l pour Log sans specifier de durée { case 'd': LireDuree(); if (RunD != 0)Log(); break; //Si duree valable lance le log du run case 'a': RunTerminer(); break; case 'l': RunD = DureeDef * 1000000; Log(); break; //Lance un run de durée par défaut default : Serial.println(); BT.println(); Serial.println("?"); BT.println("?"); delay(3000); //Erreur } AffF = 1;//Fin de dialogue relancer l'affichage des lignes } void isr_Affic() //Toutes les AffPer µs, affiche au Sphone { Timer1.stop(); if (AffF == 1)AffLigne();//Affichage OK, pas en mode dialogue Timer1.initialize(AffPerMic);//en µs, reinit } void isr_Cible() { delayMicroseconds(500);//Anti rebond CtC++;// Vaudra donc 1,2,3,4,5 if (CtC != 5) { AccC = AccC + (micros() - prec_H); //Cumule un creneau prec_H = micros(); //Nouvelle heure de reference } else //fin du cycle { D720 = AccC; AccC = 0; //reset CtC = 0; //reset Cycle = 1; //Flag de detection de cible } } void Lec_AFR() { AFRu = analogRead(AFR); AFRv = map(AFRu, 0, 1023, 74, 221); // AFR valeur entre 7.4 et 22.1 } void LecFic()//Lit un enregistrement de fichier { //Lire le numero de run RunNb, seul enregistrement du fichier NextR.txt 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 // Serial.print("RunNb= "); BT.println("RunNb= "); // Serial.println(RunNb); BT.println(RunNb); } myFile.close(); } void LireDuree() { //Dure non valable, on sort avec Rund=0 BT.println("Lancer un run"); Serial.println("Lancer un run"); BT.println("Duree en secondes (0 pour sortir, 3600 maxi): "); Serial.println("Duree en secondes (0 pour sortir, 3600 maxi): "); LireVal(); //On entre soit 2 par ex pour 2s soit 0 pour sortir if ((Val == 0) || (Val > 3600)) { //0 veut dire sortir tt de suite. Limite 1h Serial.println(); BT.println(); Serial.println("?"); BT.println("?"); delay(3000); RunD = 0; //Erreur ;//0 ou plus d'une heure, ignorer on sort } else RunD = 1000000 * Val; } void LireVal() //Au clavier du Sphone //Attend une ligne de car terminée par CR ou LF et la convertit en entier Val { while (1) { //On en sortira par CR ou LF // while (Serial.available() == 0); //Attendre un car pour le moniteur while (BT.available() == 0); //Attendre un car // carLu = Serial.read(); //Lit ce car pour le moniteur carLu = BT.read(); //Lit ce car delay(100); //Indispensable if ((carLu == 13 ) || (carLu == 10)) break;//Sortir L = L + carLu; //cumuler } Val = L.toInt(); // convertir en entier // while (Serial.available() != 0)carLu = Serial.read(); //Purge pour le moniteur while (BT.available() != 0)carLu = BT.read(); //Purge } void Log() { //Prepare les fichiers et met RunF=1 { //Lire le numero de run RunNb, seul enregistrement du fichier NextR.txt LecFic();// 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); Serial.print("Duree en s "); Serial.println(RunD / 1000000); BT.print("Duree en s "); BT.println(RunD / 1000000); 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(" INJECTION Alpine A110 1600S"); myFile.println("; ; ; ; ;"); //Leading blank line String header = "Nt/mn ;TPS en %;D14 mics;D23 mics;Cor mics ;AFR ";// les entêtes de colonnes myFile.println(header);// ensuite les lignes seront ajoutées par EcrireLigne() Dcum = 0; //Calcul de la durée RunF = 1; //Run en cours } AffF = 1; //Re autoriser l'affichage des lignes sur le Sphone } void PrepLigne() //Lecture de toutes les entrées { while (Cycle == 0); Cycle = 0; //reset du flag N = 120000000 / D720; //N en t/mn Lec_AFR(); Ligne = String(N) + ";" + String(AFRv); if (RunF == 1) //Run en cours { myFile.println(Ligne); Dcum = Dcum + D720; if (Dcum > RunD)RunTerminer(); } } void RunTerminer() { BT.println(F("Run termine: numero et duree en s ")); Serial.println(F("Run termine: numero et duree en s ")); BT.println(RunNb); Serial.println(RunNb); BT.println(Dcum / 1000000); Serial.println(Dcum / 1000000); myFile.close();//Enregistre le fichier des lignes delay(5000); RunF = 0; //Pas de run en cours } void setup() { Serial.begin(115200); //Pour moniteur PC BT.begin(115200); //Pour Sphone, Bluetooth BT.println(F("Hello world")); Serial.println(F("Hello world")); attachInterrupt(0, isr_Cible, RISING); //D2,capteur Hall saturé, 0 quand cible detectée Timer1.attachInterrupt( isr_Affic);//Affiche au Sphone toutes les AffPerµs // pinMode(Cible, INPUT_PULLUP); //Vient du capteur Hall pinMode(Cible, INPUT); //Vient du creneau bobine - Serial.print(F("Initializing SD card...")); BT.print(F("Initializing SD card...")); if (!SD.begin(CS)) { //SD.begin(4) = 1 si carte OK*************************** Serial.println(F("initialization failed!")); BT.println(F("initialization failed!")); } else { BT.println(F("initialization OK")); Serial.println(F("initialization OK")); } delay(5000); // Créer le fichier des numeros de log s'il n'existe pas if (SD.exists("NextR.txt") ) { //************************************* Serial.println(F("NextR.txt exists.")); BT.println(F("NextR.txt exists.")); } else { myFile = SD.open("NextR.txt", FILE_WRITE);//Le creer myFile.println(String( 1) );//Avec RunNb =1 myFile.close(); } AffPerMic = AffPer * 1000000; //Periode d'affichage en µs AffF = 1;//Afficher au Sphone } void loop() { PrepLigne(); Dialog(); }