//Injection_V3.1_140121 //Détails sur http://www.loutrel.org/Injection.php //Choix du mode normal ou dépannage #define Depannage 0 // 0 mode normal, 1 dépannage pour ignorer les entrées Tmot, Tair et potar //ainsi que le traitement des accélérations //Definition du mode d'injection byte InjMode = 1; // 1 Semi-sequentielle 14/23,2 Batch //3 Semi-sequentielle 13/42,4 Sequentielle 3421,5 Sequentielle 4213 //Si un potentiomètre est connecté, il peut être utilisé pour modifier un paramètre selectionné //************Cas SANS Logger connecté,on affecte en statique( à la compilation) le potar à l'UNE de ces 6 fonctions: byte PotAffect = 6;// Absence de Potar 7, sinon le modifier selon la fonction désirée //6 variation de la duréed'injection Dinj en % //5 selection d'un mode d'injection parmi cinq //4 pour varier PapDotPla %/s //3 pour varier CorAccMax //2 pour varier NcycleAcc //1 pour varier DelSeq délai avant injection Sequentielle 4213 //0 pour varier Dinj de + ou - DinjDel ms, par potar //*************Cas AVEC Logger connecté, l'utilisateur via le Logger et le clavier du Sphone émet PotAffectLog //PotAffectLog remplace alors DYNAMIQUEMENT PotAffect byte PotAffectLog = 7; // 7 conserver PotAffect, sinonimposer les fonctions ci dessus // Coupe quand N>2000 et TPS<=5%, //A la mise du contact injection d'amorçage de 50ms, equivalent à 1 jet de pompe de reprise de carburateur //Sous demarreur, suivant la temperature du moteur (Tmt) enrichissement de 500%(0°C) à 0%(70°C) //Post demarrage, c'est à dire après la première explosion, pendant NCyclePost ( 50 à 300) cycles, 130% fixe //Ensuite à tous les regimes enrichissement decroissant jusqu'à Tmot = 70°C //En acceleration, enrichissement variable(<130%) sur 40 tours //Detection de la cible au PMH allumage du cylindre 2 //Dinj extrait de TabDinj 11x11( merci G. Alquier, entre autre pour cette table) //Dinj interpollée sur 4 cases //Corrections multiplicatives en % //Injecteur de 240cc/mn soit 4cc/s,0.25s=250ms par cc. //Mesuré sur carbu Weber DCOE 45, un jet de pompe de reprise 35/100mm = 0.2cc //50ms = 0.2cc pour une acceleration, et au demarrage, 3 jets = 0.6cc soit 150ms //*************Eventuellement ajustables****************** #define Vp5 4.92 //En V, tension réelle de valeur théorique +5V pour les conversions analogiques #define Ndem 400 //t/mn On admet quel'on est sous demarreur si N < Ndem, typique 400 #define Damorce 50 //ms A chaque mise de contact sauf si papillon >TPSdenoie. 0.2cc pour 50ms #define Dbp 150 //Durée d'injection en ms pour chaque impulsion sur le Bouton Poussoir 0.6cc pour 150ms #define TPSdenoie 70 //% mode denoyage si TPS >TPCdenoie, pas d'injection à la mise du contact ou sous demarreur #define CorPost 130 // % enrichissement durant les NCyclePost tours suivant le demarrage,c'est à dire le postdemarrage //Pap à zero, mesuré 0.3V sur AP soit 61 u sous 5V, pris 40 par securité //0.5V 5%, 3.9V 100% Rappel 5V = 1023 u, V+5 est la réalité #define APumin 40 // unité quand papillons au minimum absolu, 0.3V pour 7805=5V, théorie 61 #define APumax 794 // unité quand papillons au maximum, 3.88V pour 7805=5V #define NCyclePost 50 //Nombre de cycles enrichis en postdemarrage, ex 300 #define Rtm 1000 //Resistance talon sonde température moteur, en ohms #define Rta 1000 //Resistance talon sonde température air, en ohms //Comme pour une injection Lucas on attend 10 degrés avant l'ouverture de la soupape d'admission, //Par exemple si AOA = 50°, attente de 180 - 50 -10 =120 //******************************************************* #include"TimerOne.h" //Coupe les injecteur 1 et 4 #include //Coupe les injecteur 2 et 3 #define Cible A2 //Cible AàC ,entrée numerique #define I1 9//Inj 1 activé par D9 #define I2 13//Inj 2 activé par D13 #define I3 7// Inj 3 activé par D7 #define I4 A3//Inj 4 activé par A0 #define AP A4 //Potar angle papillon.Sera traduit en TPS % Throttle Position Sensor, entrée analogique #define PotCor A0 //Potar pour correction manuelle d'injection, entrée analogique #define AFR A6 //0 à 5V fourni par la sonde lambda linéaire Innovate, entrée analogique, non utilisé ici #define Smot A5 //Sonde de temperature moteur, entrée analogique #define Sair A7 //Sonde de température air ambiant, entrée analogique #define Vbat A1 //Tension de la batterie, entrée analogique #define BP 2 //Bouton Poussoir pour injecter essence, entrée numerique #define T0 0 // les TPS % ,lignes de TabDinj #define T1 3 #define T2 8 #define T3 15 #define T4 25 #define T5 35 #define T6 50 #define T7 65 #define T8 80 #define T9 90 #define T10 100 #define N0 700 // les t/mn,colonnes de TabIDinj #define N1 1100 #define N2 1500 #define N3 2100 #define N4 2700 #define N5 3300 #define N6 3900 #define N7 4500 #define N8 5100 #define N9 5600 #define N10 6000 // Cette table correspond à des durées d'injection pour une //température moteur de 70°C et d'air aspiré à 20°C //Des corrections seront donc à apporter //Elle reflète le remplissage du moteur en fonction du régime et de la charge byte TabDinj [11][11] = { //Durées d'injection brutes en unités de 100µs //6 13 18 22 28 33 38 43 47 50 Hz f Hz = N/120 //7 11 15 21 27 33 39 45 51 56 60 t/mn *100 {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20}, //TPS% 0 {22, 22, 23, 23, 24, 24, 24, 24, 24, 24, 24}, //3 {26, 27, 27, 28, 28, 29, 29, 29, 29, 29, 29}, //8 {31, 32, 32, 33, 34, 35, 35, 35, 35, 35, 35}, //15 {38, 39, 40, 41, 43, 44, 46, 46, 46, 46, 46}, //25 {45, 46, 47, 49, 51, 53, 54, 55, 55, 55, 55}, //35 {45, 48, 52, 55, 58, 61, 65, 67, 68, 68, 69}, //50 {45, 48, 51, 54, 59, 64, 70, 73, 75, 75, 75}, //65 {45, 49, 51, 55, 61, 65, 72, 76, 79, 80, 82}, //80 {45, 48, 51, 56, 61, 67, 72, 77, 81, 83, 84}, //90 {45, 48, 52, 55, 61, 67, 73, 79, 82, 84, 86} //100 }; byte Pap = 0; //Papillon (ligne)pour entrer dans TabDinj, de 0 à PapMax byte Reg = 0; //Regime (colonne) pour entrer dans TabDinj, de 0 à RegMax byte PapMax = 10; //Dernière ligne ici 10 byte RegMax = 10; //Dernière colonne ici 10 byte Prem = 1 ;//Flag pour ignorer la première injection int long unsigned K = 0; //Pour fonction d'attente DelayK() Kµs float TPS = 0; //Throttle Position Sensor, donc AP converti entre 0 et 100% float DinjCor = 1 ; //correctif global de durée d'injection float CorDem = 1; //correctif sous demarreur float CorPostDem = 1; //correctif pour les 15s suivant le demarrage float CorAcc = 1; // correctif type pompe de reprise durant une acceleration float CorPot = 1; //correctif modulation de l'injection par potard ex 50 à 120% float CorTmot = 1; //correctif temperature moteur float CorTair = 1; //correctif temperature air int long unsigned prec_H = 0; //Heure precedente en µs float D720 = 0; // Durée du cycle en cours en µs, 720°vilo, 2 tours float D180 = 0; //180 deg en µs float N = 0; //N en t/mn float Dinj = 0; //Durée d'une injection en µs, pour les TIMERs int Dsup = 0; //en ms, injection supplementaire,à la mise du contact ou BP int APu = 0; //AP en unités 0-1023 Angle Papillon int AFRu = 0; //AFR en unités 0-1023 Air to Fuel Ratio int PotCoru = 0; //PotCor en unités 0-1023 int Vbatu = 0; //Vbat en unités 0-1023 int Vmu = 0; //temperature moteur en unités 0-1023 int Vau = 0; //temperature air en unités 0-1023 float Vmv = 0; //temperature moteur en volts float Vav = 0; // temperature air en volts float Vbatterie = 0; //A partir de Vbat float CT = 0; //Coefficient des TPS% pour interpollation float CN = 0; //Coefficient des Nt/mn pour interpollation int micro_delay = 0; // Pour attendre K µs <16000µs int milli_delay = 0; // ::::::::::::::::::::: au delà float TPSprec = 0; //TPS du cycle precedent pour detecter un acceleration float PapDot = 0; //Dérivée de TPS par rapport au temps, typique 200% en acceleration, ignorée si < 25% int CtAcc = 0; //Compteur de cycles enrichis pendant une acceleration int CtCyclePost = 0; ///Compteur de cycles enrichis post demarrage float Rm = 0; //Resistance de la sonde Tmoteur, en ohms float Ra = 0; //Resistance de la sonde Tair, en ohms int DegM = 0; // Température moteur en degrès int DegA = 0; // Température air en degrès float Sv1 = 0; //Sauve Dinj brut float Sv2 = 0; //Sauve Dinj corrigé byte FI1342 = 0; //Flag pour les isr , injection semiseq 13_42 à 360 deg int PapDotPla = 250; //Vitesse d'ouverture papillon en %/s , au delà Plafonnement de CorAcc à CorAccMax, ex 250 float Pente = 0; //C'est (CorAccMax - 100.)/PapDotPla, pente de la courbe d'acceleration voir TestAcc() byte NCycleAcc = 20; //Nombre de cycles enrichis pendant une acceleration, ex 20 byte CorAccMax = 130; //Plafonnement de la correction d'acceleration en %, ex 130 byte DelSeq = 0; //En Sequentielle 4213, délai avant injection de I4 float DinjDel = 0; //Delta + ou - 3ms par potar sur Dinj, code 0 void setup()///////////////////////////////////////////////////////////////////////////////// { Serial.begin(115200); //Pour moniteur PC Serial.println("Hello"); Serial.println(); pinMode(Cible, INPUT_PULLUP); //Vient du capteur Hall, detection sur front descendant pinMode(I1, OUTPUT); //Grilles des 4 IGBT pinMode(I2, OUTPUT); pinMode(I3, OUTPUT); pinMode(I4, OUTPUT); pinMode(BP, INPUT_PULLUP); //BP d'injection d'essence pinMode(4, INPUT_PULLUP); //Ces 3 entrée pilotées par le Logger pour affecter le potar pinMode(5, INPUT_PULLUP); pinMode(6, INPUT_PULLUP); //Simule "Coup d'accelerateur, pompe de reprise carbu" à chaque démarrage. Dsup = Damorce; //Preparer un jet de 0.2cc environ if (TPS <= TPSdenoie)InjSup(); //sauf si accelerateur au plancher= denoyage Timer1.attachInterrupt(isr_Fin_14); //Tmr1 coupera l'injection I1 et I4 // Pour Timer2 qui coupera l'injection I2 et I3 voir InjMode() Prem = 1; //Flag pour ignorer la première injection CtAcc = 0; //Compteur de cycles en acceleration CtCyclePost = 0; //Compteur de cycles moteur post demarrage } //***********************FONCTIONS************************************** void CalcReg()//////////////////////////////////////////////////////////////// //Calcul le numero de colonne en fonction du régime N //ainsi que le coefficient CN pour interpoller Dinj dans la table { // N10 limite supérieure, on commence à comparer à N9 if (N > N9) { Reg = 9;//Reg numero de colonne dans TabDinj CN = (N - N9) / (N10 - N9); // Pour interpollation return; } if (N > N8) { Reg = 8; CN = (N - N8) / (N9 - N8); return; } if (N > N7) { Reg = 7; CN = (N - N7) / (N8 - N7); return; } if (N > N6) { Reg = 6; CN = (N - N6) / (N7 - N6); return; } if (N > N5) { Reg = 5; CN = (N - N5) / (N6 - N5); return; } if (N > N4) { Reg = 4; CN = (N - N4) / (N5 - N4); return; } if (N > N3) { Reg = 3; CN = (N - N3) / (N4 - N3); return; } if (N > N2) { Reg = 2; CN = (N - N2) / (N3 - N2); return; } if (N > N1) { Reg = 1; CN = (N - N1) / (N2 - N1); return; } Reg = 0; CN = (N - N0) / (N1 - N0); } void CalcPap()////////////////////////////////////////////////////////// //Calcul le numero de ligne en fonction du TPS //ainsi que le coefficient CT pour interpoller { // T10 limite supérieure, on commence à comparer à T9 if (TPS > T9) { Pap = 9; CT = (TPS - T9) / (T10 - T9); // Pour interpollation return; } if (TPS > T8) { Pap = 8; CT = (TPS - T8) / (T9 - T8); return; } if (TPS > T7) { Pap = 7; CT = (TPS - T7) / (T8 - T7); return; } if (TPS > T6) { Pap = 6; CT = (TPS - T6) / (T7 - T6); return; } if (TPS > T5) { Pap = 5; CT = (TPS - T5) / (T6 - T5); return; } if (TPS > T4) { Pap = 4; CT = (TPS - T4) / (T5 - T4); return; } if (TPS > T3) { Pap = 3; CT = (TPS - T3) / (T4 - T3); return; } if (TPS > T2) { Pap = 2; CT = (TPS - T2) / (T3 - T2); return; } if (TPS > T1) { Pap = 1; CT = (TPS - T1) / (T2 - T1); return; } Pap = 0; CT = (TPS - T0) / (T1 - T0); } void DelayK()//////////////////////////////////////////////////////////// { if (K < 14000) { // delayMicroseconds est limité à 16383µs delayMicroseconds(K); //OK pas trop long } else { milli_delay = ((K / 1000.) - 2);//Pour ces K longs,utiliser delay()en ms micro_delay = (K - (milli_delay * 1000)); delay(milli_delay); // delayMicroseconds(micro_delay); } // Affiche();// Affiche N, AP et Dinj sur Sphone } void InjBatch() { // *****************************/Batch dès PMH 2 on active les 4 injecteurs en même temps Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 1 et 4 digitalWrite(I1, 1); //Alimenter 1 digitalWrite(I4, 1); //Alimenter 4 //FlexiTimer2 unité mini =10µs,mais 100µs plus precis donc on divise Dinj par 100 FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs, coupera 2 et 3 FlexiTimer2::start(); digitalWrite(I2, 1); //Alimenter 2 digitalWrite(I3, 1); //Alimenter 3 puis aller attendre PMH 2 } void InjBP()/////////////////////////////////////////// { while (digitalRead(BP) == 0) //BP poussé? injection manuelle { Dsup = Dbp; //Dbp typique pour 1cc InjSup();//Injecter Dsup ms delay(500); //Attendre un peu } } void Injecte()/////////////////////////////////////////////////////////// // Injecte selon un mode c'est à dire un phasage spécifié par InjMode //La durée d'injection Dinj est fixée mais le début de l'injection varie dans le cycle { if (Dinj != 0) //Pas d'injection en mode denoyage ou pied levé >2000t/mn { //Dinj = Dinj + 900; //0.9ms ajoutés pour proportionalité entre volume injecté/temps //Serial.print("InjMode = ");Serial.println(InjMode); switch (InjMode) { case 1: InjSemiSeq14_32(); break; //mode semi sequentiel 14 180° 32 case 2: InjBatch(); break; //mode batch, imédiat case 3: InjSemiSeq13_42(); break; //mode semi sequentiel 13 360° 42 case 4: InjSeq3421(); break; //mode sequentiel immédiat case 5: InjSeq4213(); break; //mode sequentiel avec attente } } } void InjSemiSeq13_42() { //**************************Injection semi sequentielle dans l'ordre 1,3 360° puis 4,2 FI1342 = 1; //Flag pour isr. C'est l'isr qui fera le reset Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 1 et 3 digitalWrite(I1, 1); //Alimenter 1 digitalWrite(I3, 1); //Alimenter 3 K = 2 * D180; DelayK(); //Attendre 360 deg entre deux couples d'injections FI1342 = 1; //Flag pour isr //FlexiTimer2 unité mini =10µs,mais 100µs plus precis donc on divise Dinj par 100, coupera 4 et 2 FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs FlexiTimer2::start(); digitalWrite(I2, 1); //Alimenter 2 digitalWrite(I4, 1); //Alimenter 4 } void InjSemiSeq14_32() { //**************************Injection semi sequentielle dans l'ordre 1,4 180° puis 2,3 Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 4 et 1 digitalWrite(I1, 1); //Alimenter 1 digitalWrite(I4, 1); //Alimenter 4 K = D180; DelayK(); //Attendre 180 deg entre deux couples d'injections // K = 3 * D180; DelayK(); // Variante ou idem? Attendre 540 deg entre deux couples d'injections //FlexiTimer2 unité mini =10µs,mais 100µs plus precis donc on divise Dinj par 100, coupera 2 et 3 FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs FlexiTimer2::start(); digitalWrite(I2, 1); //Alimenter 2 digitalWrite(I3, 1); //Alimenter 3 } void InjSeq3421() { //***************************Sequentiel injecte soupape déjà ouverte ordre 3,4,2,1 K = D720 / 4.2; Serial.print("K= "); Serial.println(K); FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs, coupera 2 et 3, ici 3 FlexiTimer2::start(); digitalWrite(I3, 1); //Alimenter 3 //Attendre un peu moins de 180deg entre deux injections pour compenser les temps de calcul DelayK(); Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 4 et 1, ici 4 digitalWrite(I4, 1); //Alimenter 4 DelayK(); //Attendre <180deg entre deux injections FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs,coupera 2 et 3, ici 2 FlexiTimer2::start(); digitalWrite(I2, 1); //Alimenter 2 DelayK(); //Attendre <180deg entre deux injections Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 4 et 1, ici 1 digitalWrite(I1, 1); //Alimenter 1 et attendre } void InjSeq4213() { //***************************Sequentiel injecte 10° avant AOA ordre 4,2,1,3 Serial.print("DelSeq= "); Serial.println(DelSeq); K = (D720 / 720) * DelSeq; DelayK(); //Attendre 10° avant AOA de I4 Serial.print("K DelSeq= "); Serial.println(K); K = D720 / 4.2; Serial.print("K= "); Serial.println(K);//Attendre <180deg entre deux injections Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 4 et 1, ici 4 digitalWrite(I4, 1); //Alimenter 4 DelayK(); //Attendre <180deg entre deux injections FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs,coupera 2 et 3, ici 2 FlexiTimer2::start(); digitalWrite(I2, 1); //Alimenter 2 DelayK(); //Attendre <180deg entre deux injections Timer1.initialize(Dinj);//Lancer TMR1 qui coupera l'injection 4 et 1, ici 1 digitalWrite(I1, 1); //Alimenter 1 et attendre FlexiTimer2::set(Dinj / 100, 0.1 / 1000, isr_Fin_23); // Definition 100µs, coupera 2 et 3, ici 3 FlexiTimer2::start(); digitalWrite(I3, 1); //Alimenter 3 } void InjSup()///////////////////////////////// { //Attention, ms et non µs. //Injection supplementaire au BP ou à la mise du contact (amorçage) digitalWrite(I1, 1); //Alimenter les 4 injecteurs simultanément digitalWrite(I2, 1); digitalWrite(I3, 1); digitalWrite(I4, 1); delay(Dsup); //Ex 250ms = 1cc pour injecteur de 240cc/mn digitalWrite(I1, 0); //Arreter digitalWrite(I2, 0); digitalWrite(I3, 0); digitalWrite(I4, 0); } void isr_Fin_14()///////////////////////////////////////////// { Timer1.stop();// Coupe 1 et 4 sauf 1 et 3 dans le cas semiseq 1342 digitalWrite(I1, 0); //Couper inj 1 if (FI1342 == 1) { FI1342 = 0; //inj semi seq 1342 digitalWrite(I3, 0); } else digitalWrite(I4, 0); } void isr_Fin_23()//////////////////////////////////////////////////// { FlexiTimer2::stop();//Coupe 2 et 3 sauf 2 et 4 dans le cas semiseq 1342 digitalWrite(I2, 0); //Couper inj 2 if (FI1342 == 1) { FI1342 = 0; //inj semi seq 1342 digitalWrite(I4, 0); } else digitalWrite(I3, 0); } void Lec_AFR()/////////////////////////////////////////// { AFRu = analogRead(AFR);//Non utilisé // AFRv = map(AFRu, 0, 1023, 74, 221); // AFR valeur entre 7.4 et 22.1 } void Lec_AP()//////////////////////////////////////////////////////////// { APu = analogRead(AP);//Lire l'ouverture papillons TPS = map(APu, APumin, APumax, 0, 100); // TPS 0 à 100% if (TPS >= 100)TPS = 100; //A tout hasard // Serial.print("TPS et prec ");Serial.print(TPS);Serial.println(TPSprec); } void Prep_Dinj()/////////////////////////////////////////////////////////////// { CalcPap(); //Calcul la ligne de TabDinj suivant l'ouverture TPS CalcReg(); //Calcul la colonne de TabDinj suivant le regime N Dinj = TabDinj[Pap][Reg] ; //Extrait la durée d'injection brute en unités de 100µs Sv1 = Dinj;//Sauver pour imprimer // Serial.print("Pap"); Serial.println(Pap); // Serial.print("Reg"); Serial.println(Reg); // Serial.print("CT"); Serial.println(CT); // Serial.print("CN"); Serial.println(CN); //Dinj en µs calculée par interpollation sur 4 valeurs: case + 3 cases adjacentes Dinj = (TabDinj[Pap][Reg] * (1 - CT) * (1 - CN) + TabDinj[Pap + 1][Reg] * CT * (1 - CN) + TabDinj[Pap + 1][Reg + 1] * CT * CN + TabDinj[Pap][Reg + 1] * (1 - CT) * CN) * 100.; Sv2 = Dinj;//Sauver pour imprimer DinjCor = 1; //Re init, pas de correction //Calcul de toutes les corrections applicables à Dinj TestDemarreur(); TestPostDem(); if (Depannage == 0) //Non executé en mode Depannage = 1 { TestAcc(); TestPot(); //Correction de richesse ou autre selon PotAffect TestTmot(); TestTair(); } DinjCor = CorDem * CorPostDem * CorAcc * CorPot * CorTmot * CorTair; //Correctif global Dinj = Dinj * DinjCor; //Dinj corrigée,en % Dinj = Dinj + DinjDel; //Dinj corrigée en + ou - DinjDel ms if (N > 2000 && TPS <= 5)Dinj = 0; //Pied levé on coupe // if (PotCoru > 1000) //Pour imprimer ces valeurs et stopper, tourner Potcor au maxi // { Serial.print("D720 µs "); Serial.println(D720); // Serial.print("N t/mn "); Serial.println(N); // Serial.print("Angle papillon, TPS "); Serial.println(TPS); // Serial.print("Dinj avant interpollation *100µs "); Serial.println(Sv1); // Serial.print("Dinj après interpollation, avant correction en µs "); Serial.println(Sv2); // Serial.print("CorTmot "); Serial.print(CorTmot); Serial.print(" DegM en °C "); Serial.println(DegM ); // Serial.print("CorTair "); Serial.print(CorTair); Serial.print(" DegA en °C "); Serial.println(DegA ); // Serial.print("DinjCor "); Serial.println(DinjCor); // Serial.print("Dinj finale après corrections "); Serial.println(Dinj); // Serial.println(); // Serial.print("CorDem "); Serial.println(CorDem); // Serial.print("CorPostDem "); Serial.println(CorPostDem); // Serial.print("CorAcc "); Serial.println(CorAcc); // Serial.print("CorPot "); Serial.println(CorPot); // Lec_AFR(); // Serial.print("AFRu non utilisé "); Serial.println(AFRu); // Serial.println(); Serial.println(); // while (1);//On arrete // } } void TestAcc()////////////////////////////////////// { //Correction de l'injection, type pompe de reprise si vitesse du papillon assez grande //L'enrichissement CorAcc sera maintenu pendant NCyclesAcc cycles // if((TPS-TPSprec)>=3) //Ignorer le petites variations if (CtAcc > 0)CtAcc--; //Acceleration en cours, CorAcc reste actif, un cycle en moins else { CorAcc = 1;//Voir si correction necessaire Pente = (CorAccMax - 100.) / PapDotPla; PapDot = ((TPS - TPSprec) / D720) * 1000000; //Dérivée: position/temps= vitesse TPSprec = TPS; //On memorise l'ancienne position du papillon if (PapDot >= 25) //On ignore les petites vitesses { CtAcc = NCycleAcc; // Initialise le compteur de cycles à enrichir CorAcc = (PapDot * Pente + 100) / 100.; //Calcul de la correction à appliquer à Dinj if (CorAcc >= CorAccMax)CorAcc = CorAccMax / 100.; //On plafonne la correction } } } void TestDemarreur()/////////////////////////////////////////// { if (N < Ndem) {//On est sous demarreur if (TPS >= TPSdenoie)CorDem = 0; //Pas d'essence, on dénoie else { CorDem = ((500 - 5 * DegM) / 100.); //Enrichir, typique 500% } } else { if (CorDem > 1) //premier tour sous explosion { CorDem = 1; //TestPostDem() devra enrichir pendant NCyclePost cycles CtCyclePost = NCyclePost; //typique 50 à 300 } } } void TestPostDem()////////////////////////////////////// { CorPostDem = 1;// En option Enrichir pendant le post demarrage si <30°C //Serial.print ("DegM= "); Serial.println (DegM); // if (DegM < 30) // A essayer au delà de 30°C ? if (CtCyclePost != 0) //En cours de post demarrage { CtCyclePost --; //Décompter ce cycle CorPostDem = CorPost / 100.;//Enrichir } } void TestPot()//////////////////////////////////////////// //L'attribution du potar dépend du logger via PotAffectLog { CorPot = 1; DinjDel = 0; //Correction en % et absolue en ms PotCoru = analogRead(PotCor);//Dans tous les cas on lit la valeur du potar // Serial.print ("D4,5,6 "); Serial.println (digitalRead(4)); // Serial.println (digitalRead(5)); Serial.println (digitalRead(6)); PotAffectLog = digitalRead(4) * 4 + digitalRead(5) * 2 + digitalRead(6); // Emis par le Logger Serial.print ("PotAffectLog= "); Serial.println (PotAffectLog); if (PotAffectLog != 7)PotAffect = PotAffectLog; // Imposer l'affectation du Log si different de 7 switch (PotAffect) // { case 7: break; //Pas de potar case 6: if (PotCoru > 10)CorPot = map(PotCoru, 0, 1023, 70, 130) / 100.; break; //Le pot module Dinj case 5: if (PotCoru < 20) { InjMode = 1; //Le pot sert à choisir entre5 modes d'injections break; } if (PotCoru < 300) { InjMode = 2; break; } if (PotCoru < 600) { InjMode = 3; break; } if (PotCoru < 900) { InjMode = 4; break; } InjMode = 5; break; case 4: PapDotPla = map(PotCoru, 0, 1023, 200, 500); break; //en %/s plafond pour acc case 3: CorAccMax = map(PotCoru, 0, 1023, 110, 200); break; //en % d'enrichissement pour acc case 2: NCycleAcc = map(PotCoru, 0, 1023, 10, 100); break; //nombre de cycles enrichis en acc case 1: InjMode = 5; DelSeq = map(PotCoru, 0, 1023, 0, 180); break; //Forcer Sequentielle4213, délai avant injection en degrès case 0: DinjDel = map(PotCoru, 0, 1023, 0, 6000); DinjDel= DinjDel - 3000;break; //Correction en ms, + à - 3ms } } void TestTair()///////////////////////////////////////////// { CorTair = 1;// On mesure la resistance d'où la température. //Ensuite la température donne le % d'enrichissement car la table est définie à 20°C Vau = analogRead(Sair); //De 0 à 1023 lire la sonde dans un cornet d'admission Vav = Vau * (Vp5 / 1023.); //Convertir en V Ra = Vav * (Rta / (Vp5 - Vav)); //Resistance ohmique du capteur if (Ra >= 1050)DegA = ((3453 - Ra) / 55.7); //Première droite else //Si < 1050 ohms { DegA = ((1662 - Ra) / 13.6);//Seconde droite } CorTair = ((104 - 0.2 * DegA) / 100.); if (CorTair >= 1.1 || CorTair <= 0.8)CorTair = 1; //Non plausible, pb de sonde ou connexion // Serial.print ("DegA= "); Serial.println (DegA); // Serial.print ("Ra= "); Serial.println (Ra); // Serial.print ("Vau= "); Serial.println (Vau); // Serial.print ("Vav= "); Serial.println (Vav); // Serial.print ("CorTair= "); Serial.println (CorTair); } void TestTmot()///////////////////////////////////////////// { CorTmot = 1;//Correctif pour table définie à 70°C Vmu = analogRead(Smot); //De 0 à 1023 On mesure la resistance d'où la température. Vmv = Vmu * (Vp5 / 1023.); //Convertir en V Rm = Vmv * (Rtm / (Vp5 - Vmv)); //R du capteur if (Rm >= 1500)DegM = ((4880 - Rm) / 110.);// Première droite else { if (Rm >= 500)DegM = ((2700 - Rm) / 40.);//Deuxième droite else { DegM = ((1257 - Rm) / 12.8); //Troisième droite } } // CorTmot = ((180 - 1.14 * DegM) / 100);//trop riche au ralenti à 20°C // CorTmot = ((150 - 1.14 * DegM) / 100);//mieux mais erreur sur la pente CorTmot = ((150 - 0.71 * DegM) / 100); //pente correcte pour 100% à 70°C if (CorTmot >= 1.8 || CorTmot <= 1)CorTmot = 1; //Non plausible, pb de sonde ou connexion // Serial.print ("DegM= "); Serial.println (DegM); // Serial.print ("Rm= "); Serial.println (Rm); // Serial.print ("Vmu= "); Serial.println (Vmu); // Serial.print ("Vmv= "); Serial.println (Vmv); // Serial.print ("CorTmot = "); Serial.println (CorTmot); } void loop()/////////////////////////////////////////////////////////////////////////////////// { InjBP(); //Injection manuelle, si BP appuyé while (digitalRead(Cible) == 1)InjBP(); //Pendant l'attente du passage à 0 de la cible, injection manuelle? //Cible detectée D720 = micros() - prec_H; // Durée de 2 tours vilo = 1 tour AàC soit 720° prec_H = micros(); //Nouvelle heure de reference D180 = D720 / 4; //Delai pour 180° N = 120000000 / D720; //N en t/mn pour un 4 cylindres 4 temps // Serial.print("N"); Serial.println(N); // Serial.print("PotAffect "); Serial.println(PotAffect); Lec_AP();// Angle TPS la lecture prend environ 200µs if (Prem != 1) //Pour la première injection, Prem = 1, ne rien faire { Prep_Dinj();//Calcul Dinj en µs, et applique le correctif DinjCor Injecte(); //Injecter les 4, suivant l'un des 4 modes de phasage possibles } while (digitalRead(Cible) == 0); //Attente retour à 1, cible dépassée Prem = 0; // La première injection a été ignorée }