#include //Mr Philippe Loutrel pour l'AEPL original //Mr Dedessus les Moutiers Christophe pour la version Panhard avec prise en compte de la dépression //Mr Zorgati Antoine pour la version Peugeot avec sortie Powerdyn, prise en compte de la dépression et utilisation du module Bosch TSZ-H à la place de l'IGBT14C40L //Courbe d'avance à dépression à renseigner de la façon suivante: //int xhigh = 0;// Dépression correspondant à l'avance maxi, convertie en bits //int xlow = 0;// Dépression correspondant à l'avance mini, convertie en bits //int yhigh = 0;// Avance à dépression maxi, en degrés vilebrequin //int ylow = 0;// Avance mini de départ, toujours égale à zéro //Formule à appliquer pour la conversion dépression(mmHg) en bits: Nbits = 1,0912 x Dep(mmHg)+102,3 //Valable pour le capteur FAE réf 16111 //Courbe d'avance centrifuge à renseigner de la façon suivante: //int N[] = {0, 1300, 2000, 3500, 7000, 0}; //int Ang[] = {0, 0, 12, 24, 21, 0}; //const int Avancestatique = 10; //Chaque couple N Ang correspond à un point de la courbe centrifuge //L'avance statique est à ajouter à la courbe //Exemple ici: à 2000trs/min, l'avance centrifuge sera de 12°+10° d'avance statique soit 22° au vilebrequin //Courbe dépression à renseigner int xhigh = 604;// valeur ADC haute pour conversion de la valeur mmHg haute int xlow = 320;// valeur ADC basse pour conversion de la valeur mmHg basse int yhigh = 12;// valeur de la limite en degré haute int ylow = 0;// valeur de la limite en degré basse soit 0 degré //Courbe centrifuge à renseigner int N[] = {0, 1300, 2000, 3500, 7000, 0}; int Ang[] = {0, 0, 12, 24, 21, 0}; const int Avancestatique = 10; //Valeurs à renseigner selon les caractéristiques de votre moteur int Ncyl = 4;//Nombre de cylindres const int AngleCapteur = 60;//Avance statique de calage du capteur, en degrés vilebrequin const int CaptOn = 0; //CapteurOn = 1 si le signal est donné par un passage 0=>5V (front montant), CapteurOn = 0 si front descendant const int Nplancher = 1000; // vitesse en t/mn jusqu'a laquelle l'avance à dépression = 0°, utile si la prise de dépression est en aval du papillon des gaz (pour ne pas perturber le ralenti) //Valeurs à renseigner selon la façon dont est cablé votre Arduino const int Module = 3; //Sortie D3 vers Module const int Powerdyn = 4; //Sortie D4 vers prise Jack (pour exploitation Powerdyn) const int Cible = 2; //Entrée D2 du capteur à effet Hall //Les valeurs suivantes n'ont pas lieu d'être modifiées int unsigned long D = 0; int unsigned long Ddep = 0; int unsigned long Dsum = 0; int milli_delay = 0; int micro_delay = 0; float Tplancher = 0; const int tcor = 380; //correction en µs du temps de calcul pour D 120µs + 120µs de lecture de dépression + 140µs de traitement int unsigned long Davant_rech = 0; int unsigned long Tprec = 0; int unsigned long prec_H = 0; int unsigned long T = 0; int unsigned long Tant = 0; int N1 = 0; int Ang1 = 0; int N2 = 0; int Ang2 = 0; int* pN = &N[0]; int* pA = &Ang[0]; float k = 0; float C1[20]; float C2[20]; float Tc[20]; int Tlim = 0; int j_lim = 0; int unsigned long NT = 0; int AngleCibles = 0; int UneEtin = 1; float uspardegre = 0; int Dep = 0; float Degdep = 0; int unsigned long Vitesse = 0; float Delaideg = 0; unsigned long Stop_temps; unsigned long Tempsecoule = 0; const unsigned char PS_16 = (1 << ADPS2); const unsigned char PS_32 = (1 << ADPS2) | (1 << ADPS0); const unsigned char PS_64 = (1 << ADPS2) | (1 << ADPS1); const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); //********************LES FONCTIONS************************* void CalcD () { for (byte j = 1; j <= j_lim; j++) { if (T >= Tc[j]) { D = float(T * C1[j] + C2[j]); Ddep = (Degdep * Delaideg ) ; //if (T > Tplancher){Ddep=0}; //Pour activer cette fonction, enlever les // en début de ligne Dsum = D - Ddep - tcor ; break; } } } void Etincelle () { if (Dsum < 14000) { delayMicroseconds(Dsum); } else { milli_delay = ((Dsum / 1000) - 2); micro_delay = (Dsum - (milli_delay * 1000)); delay(milli_delay); delayMicroseconds(micro_delay); } digitalWrite(Module, 1); digitalWrite(Powerdyn, 1); Stop_temps = micros(); Davant_rech = T * 3 /10; Timer1.initialize(Davant_rech); UneEtin = 1; } void Init () { AngleCibles = 720 / Ncyl; NT = 120000000 / Ncyl; Tplancher = 120000000 / Nplancher / Ncyl; Prep_courbe(); Serial.print("Tc = "); for (int i = 1 ; i < 8; i++)Serial.println(Tc[i]); Serial.print("Tlim = "); Serial.println(Tlim); Serial.print("C1 = "); for (int i = 1 ; i < 8; i++)Serial.println(C1[i]); Serial.print("C2 = "); for (int i = 1 ; i < 8; i++)Serial.println(C2[i]); Timer1.attachInterrupt(isr_GestionIbob); } void Prep_courbe() { N1 = 0; Ang1 = 0; //Toute courbe part de 0 int i = 0; //locale mais valable hors du FOR pN++; pA++; //sauter le premier element de tableau, toujours =0 for (i = 1; *pN != 0; i++)//i pour les C1,C2 et Tc.Arret quand regime=0. //pN est une adresse (pointeur) qui pointe au tableau N.Le contenu pointé est *pN { N2 = *pN; Ang2 = *pA;//recopier les valeurs pointées dans N2 et Ang2 k = float(Ang2 - Ang1) / float(N2 - N1); C1[i] = float(AngleCapteur - Avancestatique - Ang1 + k * N1) / float(AngleCibles); C2[i] = - float(NT * k) / float(AngleCibles); Tc[i] = float(NT / N2); N1 = N2; Ang1 = Ang2; //fin de ce segment, début du suivant pN++; pA++; //Pointer à l'element suivant de chaque tableau } j_lim = i - 1; //Revenir au dernier couple entré Tlim = Tc[j_lim]; //Ligne rouge } void isr_GestionIbob() { Timer1.stop(); if (UneEtin == 1) { digitalWrite(Module, 0); digitalWrite(Powerdyn, 0); } UneEtin = 0; } void setup() { Serial.begin(115200); if (Ncyl < 2)Ncyl = 2; pinMode(Cible, INPUT_PULLUP); pinMode(Module, OUTPUT); pinMode(Powerdyn, OUTPUT); ADCSRA &= ~PS_128; // you can choose a prescaler from above. // PS_16, PS_32, PS_64 or PS_128 ADCSRA |= PS_64; // set our own prescaler to 64 Init(); } void loop() { while (digitalRead(Cible) == !CaptOn); T = micros() - prec_H; prec_H = micros(); Dep = analogRead(A0); Degdep = map(Dep, xhigh, xlow, yhigh, ylow); if (Degdep < 0) { Degdep = 0; } else if (Degdep > yhigh) { Degdep = yhigh ; } else ; Vitesse = NT / T; Delaideg = NT / Vitesse / float(AngleCibles); if (T > Tlim) { CalcD(); Etincelle(); } if (T < Tlim) { T = Tant; CalcD(); Etincelle(); Vitesse = NT / Tant; } while (digitalRead(Cible) == CaptOn); Tempsecoule = Stop_temps - prec_H ; Tant = T; }