Pilotage de bobines d'allumage

Bonjour à tous,

Toujours dans le cadre de ma préparation automobile, je me permets de solliciter le forum pour la suite de mes aventures.

Je possède un véhicule, qui possède un allumage par distributeur. Le calculateur (ECU) envoi un signal nommé IGT (quasiment +5V) à un allumeur, qui lui "gère" le temps d'allumage (dwell time) de l'unique bobine du véhicule. Le courant pour l'étincelle est ensuite acheminé mécaniquement par le distributeur (tete delco) qui par le doigt d'allumage se trouvera en face du plot qui correspondera au cylindre ciblé.

Je possède un deuxieme calculateur qui intercepte certains signaux du calculateur d'origine, et qui modifie des paramètre selon ce que je cherche (par exemple l'avance à l'allumage). J'ai pendant très longtemps eu largement assez en me servant du montage d'origine (1 bobine -> 1 allumeur/distributeur) et des modification d'avance par l'ECU 2.

Ensuite, ne voulant pas modifier le temps de charge d'origine du système, grace à mon ECU 2 qui peut nativement diviser et copier un signal, j'ai fait un montage d'allumage par cylindres indépendants -> 1 bobine et 1 allumeur par cylindre. L'ECU 1 emet son signal IGT0, et l'ECU 2 (avec d'autres parametres) sort IGT1, IGT2, IGT3, IGT4 qui sont des copies conformes d'IGT0.

Je souhaite aujourd'hui encore passer une étape, pour passer sur des bobines plus modernes qui ne nécessites pas d'allumeur. Le seul soucis, c'est qu'IGT0 fait tout le temps un signal carré 0 - 5V, en restant à 5V 6ms. Les allumeur receptionnaient ce signal carré de 6ms pour déclencher immédiatement (indépendament du temps d'IGT0) un signal carré de 0 -5V mais d'uniquelment 4ms à 12V.

Ce signal carré en sortie d'allumeur correspond au temps de chargement de la bobine, appelé dwell time. En passant de 0 à 5V, la bobine charge le temps du 5V, et déclenche quand le signal repasse à 0V.

Voulant passer sur un système sans allumeur, et n'ayant pas possibilité de gerer le dwell time avec l'ECU 2 qui clone juste IGT0, je souhaiterai intercaller une arduino entre ECU1 et ECU2, pour intercepter IGT0 et le fournir à ECU2 avec un temps modifier. Receptionner le signal IGT0 via une interruption en "rising", pour ensuite emettre de nouveau le signal 5V mais avec le temps de chargement (dwell time) que j'aurai choisi.

Un autre paramètre interviendra plus tard, le dwell time changera en fonction de la tension (6 à 15V) du véhicule

Je pense partir vers ce montage. Attention, il n'est nullement parlé de puissance, uniquement du signal 5V de pilotage.

Relevé à l'oscilloscore, IGT0 sortant de l'ECU1 fait systématiquement 6ms. Quoi qu'il arrive. A 12V, les allumeurs genere un signal de 4ms. qui débute exactement en même temps qu'IGT0 mais qui se stoppent plus tot de 2ms

Voilà la map par voltage que genere un allumeur:

Toyota_Distributor_Dwell

Et voulant me passer d'allumeur, voilà ce que l'arduino devra fournir à ECU 2:

Toyota_Yaris_Coil_Dwell

Puis-je partir sur un tel montage, et si j'ai oublié des élements, que me conseillez-vous d'ajouter? Pour un seul signal à la base, il m'est beaucoup plus simple d'intercepter IGT0 et de le fournir comme je le souhaite à ECU 2 qui lui va distribuer et cloner ce signal de lui même

(PS: pourquoi gèrer des temps de chargement, et par tension : En cas de gros temps de charge, les bobines sortent de leurs plages de confort et vont s'autodétruire à l'usage -> chauffe énorme)

Merci!

hello brasiligun
dans un premier temps, tu veux un arduino qui receptionne sur interruption flanc montant, le signal 5V 6ms
et qui te sorte un signal 5V 4ms, à quelle fréquence ?

tu parles de 12 V 3.8ms , comment veux tu pouvoir regler la durée du pulse ?

Salut,

Connais tu les projets Combiduino ou speeduino?

Salut dfgh,

Pour l'instant on ne se souci pas de 12V. Le 12V ou 13V ou 14V sera à la partie puissance de la bobine (bobine 3 fils +12/gnd/commande).

Je lirai plus tard la valeur du circuit 12V avec l'arduino avec un pont diviseur de tension

Le but de ma démarche d'aujourd'hui, c'est que des que mon signal d'origine lance un front montant, c'est que l'arduino demarre tout de suite un signal identique mais qui se terminera plus tot que celui d'origine

C'est vraiment le front montant d'origine qui fera le go. Et le nouveau signal de 4ms (pour exemple), sera terminé alors que celui d'origine de 6ms courrira toujours mais ne sera pas communiqué à ECU 2

Salut Jambe,

Oui je connais, mais perso j'ai un EMU (greddy e-manage Ultimate), qui est un piggyback, pas un standalone. Il n'y a que le dwell time que je ne pas gérer.

D'où la petite arduino pour réceptionner le signal d'origine comme "go" et fournir a ECU 2 (le EMU) un signal a dupliquer

#define front_montant 2
#define sortie_4ms 8
unsigned long pulse = 0;
bool top = false;
void setup() {
  Serial.begin(115200);
  //pinMode(sortie_4ms,OUTPUT);
  DDRB |= 0b0000001;  //1 = sortie
  pinMode(front_montant, INPUT);
  attachInterrupt(0, isr_IGTO, RISING);
  sei();
}
void isr_IGTO() {
  pulse = micros();
  PORTB |= 0b00000001;
}

void loop() {
  if (micros() > (pulse + 4000)) {
    PORTB &= 0b11111110;
    pulse = micros() + 100000;
  }
}

amitiés

Salut DFGH,

Un grand merci, ̶a̶ ̶p̶e̶u̶ ̶d̶e̶ ̶c̶h̶o̶s̶e̶s̶ ̶p̶r̶ê̶t̶ ̶n̶o̶u̶s̶ ̶a̶v̶o̶n̶s̶ ̶l̶e̶ ̶m̶ê̶m̶e̶ ̶c̶o̶d̶e̶ ̶:̶p̶(Je suis au boulot sur mon téléphone, je ne peux pas te montrer mon début de code).

Ce qui m'intéressait surtout, c'était la partie hardware, je ne sais pas si ma petite arduino est capable de fournir assez de pêche pour le pilotage. Je pense que oui mais au cas ou, je pense à me servir d'un 7805 pour alimenter un mosfet qui donnera des coups de 5V. C'est la partie montage et sécurisation avec des résistances qui me pose problème.

Et pour le coup des tableaux de durée de chargement de la bobine:

Toyota_Yaris_Coil_Dwell

Je pense lire ma tension de circuit de charge (batterie + alternateur qui oscille théoriquement de 9V à 15V), mais en prenant des extrêmes de 6 à 16V et fournir l'info à l'arduino par un diviseur de tension dimensionné pour

En reprenant ton code, "sortie_4MS" deviendrait "sortie" et serait conditionnée par la tension lue.

Pourquoi faire ça, étonnant donné qu'une bobine charge une tension primaire "faible" avec un peu d'ampérage en une tension énorme entre 20000 et 40000v à ampérage faible, il est important de gérer le temps de chargement d'après la tension du primaire.

Je ne sais pas si avec une arduino nano il vaut mieux partir sur du AnalogRead ou utiliser Vin (jamais fait). Le tout en sécurité

Version "sans" mos pilotage direct résistances et dimensions à ajouter :

Version avec Mosfet (idem résistance + modèle de mosfet à déterminer) :

ECU1 sort bien du 5 V en IGT0 ? pour entrer sur D2 de l'arduino.
et ECU2 attends bien du 5V ? venant de l'arduino.

attention, Vin n'est pas une entrée, c'est une patte d'alimentation de la platine.
une analogRead est adaptée pour lire la tension à condition que tu la ramène dans une fourchette de 0 à 5 volts.

d'autres vont passer et te donner leur avis.

Bonjour

image

cette connection à la masse avec la source du MOSFET est louche !

Exactement. ECU 1 sort IGT0 qui fait réellement 4,73V, et ECU 2 attend un signal de 5V max. Et je me pose la question des résistances pour protéger l'Arduino. Je vais surement essayer sans mosfet pour voir si ECU 2 accepte le signal que sortira l'arduino. En fait certaine bobine comme par exemple celle d'audi R8 dites les "VAG" (elles sont rouges) refuse de faire feu avec des sorties d'arduino ou de calculateur comme mon emanage. Pas assez de courant de sortie pour le pilotage.

Dans mon cas ça devrait le faire, c'est plus au cas ou

Exact, schéma fait à la va vite, j'ai trop vite mis mes masses partout. Bien vu

EDIT : j'ai mal lu ton code, là tu generes toi même le signal d'en haut et l'arduino repond en faisant le signal du bas, c'est bien ça?

A terme, le signal du haut aura toujours le même front montant qui durera 6ms, mais la période entre chaque repetition sera totalement différente. IGT0 correspond reellement à l'avance ou au retard à l'allumage en fonction des tours minutes.

L'arduino devra récuperer IGT0 sur un port d'interruption, le pin 2 dans notre cas, et émettre le nouveau signal avec le temps d'allumage gammé selon la tension de la voiture exemple 4.5ms à 10V, 4ms à 12V etc.

#define front_montantIGT0 2 //pin d'interuption qui va declencher quand IGT0 est en front montant
#define IGTmodif 8 //pin qui va generer IGTmodif (qui va à ECU2)
unsigned long pulse = 0;
bool top = false;
float valeur;
float tensionVehicule = 0;
float coef = 3 / 4; //lecture du "12v" avec un pont diviseur de tension R1 = 30k et R2 = 10k
float dwellTime = 0; //temps de déclenchement du signal sortant vers l'ECU2


void setup() {
  Serial.begin(115200);
  //pinMode(IGTmodif,OUTPUT);
  DDRB |= 0b0000001;  //1 = sortie
  pinMode(front_montantIGT0, INPUT);
  attachInterrupt(0, isr_IGTO, RISING);
  sei();
}

void isr_IGTO() {
  pulse = micros();
  PORTB |= 0b00000001;
}

void loop() {
  if (micros() > (pulse + 4000)) {
    PORTB &= 0b11111110;
    pulse = micros() + 100000;


  }
}

void tension() {
  valeur = analogRead(A0);
  tensionVehicule = valeur * (5 / 1023) / (coef);
}

void gestionDwellTime() { //temps de mise à feu

  if (tensionVehicule < 7) {
    dwellTime = 700;
  }

  if ((tensionVehicule >= 7) && (tensionVehicule < 8)) {
    dwellTime = 625;
  }

  if ((tensionVehicule >= 8) && (tensionVehicule < 9)) {
    dwellTime = 500;
  }
  if ((tensionVehicule >= 9) && (tensionVehicule < 10)) {
    dwellTime = 450;
  }
  if ((tensionVehicule >= 9) && (tensionVehicule < 10)) {
    dwellTime = 450;
  }
  if ((tensionVehicule >= 10) && (tensionVehicule < 11)) {
    dwellTime = 415;
  }
  if ((tensionVehicule >= 11) && (tensionVehicule < 12)) {
    dwellTime = 380;
  }
  if ((tensionVehicule >= 12) && (tensionVehicule < 13)) {
    dwellTime = 355;
  }
  if ((tensionVehicule >= 14) && (tensionVehicule < 15)) {
    dwellTime = 330;
  }
  if ((tensionVehicule >= 15) && (tensionVehicule < 16)) {
    dwellTime = 305;
  }
  if (tensionVehicule >= 16) {
    dwellTime = 280;
  }
}

En prenant ton code tel quel, voilà mes modifs à moi (certes faites de façon basiques), le temps de déclenchement varira en fonction de la tension du véhicule. Reste à integrer tout ça dans l'interruption, que dès que l'arduino voit un front montant d'IGT0, elle déclenche un signal carré avec le temps que nous souhaitons. En l'occurence je vois que tu as préparé le pin8

oui, mes tests avec un générateur de fréquences.
une fois les 6ms de IGT0 passées, combien de temps minimum en millis ?
ensuite, ta tension sera t'elle plus souvent vers les 6 V ou vers les 16 V ?
pourquoi ce coeff ? tu mets bien un pont diviseur?

Il faudrait que je calcul combien de temps, mais en gros le moteur prend 200tr minutes minimum au démarrer, et 700tr au ralenti. Rupteur naturel à 7400tr/min que j'ai abaissé à 6800 pour le protéger.

Mais la fréquence entre 2 fronts montants est elle importante si c'est vraiment le début d'un front montant qu'il déclenche notre nouveau signal?

La tension sera plus souvent comprise entre 12 et 13V. Et oui j'ai calculé sommairement un pont diviseur r1=30k et r2=10k. En comptant 15V max, cela me donne 3.75v donc dans la plage utilisable en sécurité d'une arduino.

Si mes souvenirs sont bons, 30000/(10000+30000)=0.75

le coeff ne sert à rien
je vois ton code comme ceci, attention, non testé

#define front_montantIGT0 2  //pin d'interuption qui va declencher quand IGT0 est en front montant
#define IGTmodif 8           //pin qui va generer IGTmodif (qui va à ECU2)
unsigned long pulse = 0;
//bool top = false;
float valeur;
float tensionVehicule = 0;
//float coef = 3 / 4;   //lecture du "12v" avec un pont diviseur de tension R1 = 30k et R2 = 10k
float dwellTime = 0;  //temps de déclenchement du signal sortant vers l'ECU2


void setup() {
  Serial.begin(115200);
  //pinMode(IGTmodif,OUTPUT);
  DDRB |= 0b0000001;  //1 = sortie
  pinMode(front_montantIGT0, INPUT);
  attachInterrupt(0, isr_IGTO, RISING);
  sei();
}

void isr_IGTO() {
  pulse = (micros()+ dwellTime);
  PORTB |= 0b00000001;
}

void loop() {
  if (micros() > pulse) {PORTB &= 0b11111110;pulse = micros();}
  if(pulse>micros()){gestionDwellTime();}
}

//tension du véhicule est comprise entre 6V et 16V
//pont diviseur:
// VE 6 à 12
// R2 = 30000
// sortie 1.5V à 4V ==> A0  donneront 300 à 810
// R1 = 10000 
// GND

void gestionDwellTime() {  //temps de mise à feu
valeur = analogRead(A0) * (5 / 1023);
  tensionVehicule = map(valeur, 300, 810, 6, 16);
  if (tensionVehicule > 16) {
    dwellTime = 280;
  } else {
    if (tensionVehicule > 15) {
      dwellTime = 280;
    } else {
      if (tensionVehicule > 14) {
        dwellTime = 305;
      } else {
        if (tensionVehicule > 13) {
          dwellTime = 330;
        } else {
          if (tensionVehicule > 12) {
            dwellTime = 355;
          } else {
            if (tensionVehicule > 11) {
              dwellTime = 380;
            } else {
              if (tensionVehicule > 10) {
                dwellTime = 415;
              } else {
                if (tensionVehicule > 9) {
                  dwellTime = 450;
                } else {
                  if (tensionVehicule > 8) {
                    dwellTime = 500;
                  } else {
                    if (tensionVehicule > 7) {
                      dwellTime = 625;
                    } else {
                      if (tensionVehicule > 6) { 
                        dwellTime = 625; }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Bien vu le coup de la map. Demain je sors ma breadbord et j'essaie. Je te remercie

Et je reviens avec mes résistances, on m'a toujours appris à ne pas exploiter directement les entrées et les sorties des arduino. Je ne connais malheureusement pas le courant qui passe pas IGT0. Je sais qu'il est infime, car insuffisant pour la mise à feu de certaines bobines en direct.

Bonne soirée et merci

Je ne suis décidement pas bon avec les interruptions. Mais si je résume bien:

Dès que D2 voit un front montant de IGT0, l'arduino lance sur D8 mon nouveau signal avec le temps que je souhaite.

Pour eviter les mauvais fronts montants IGT0 ou les parasites, je pense ajouter une pull-down.

Peux-tu confirmer mon code?

#define front_montantIGT0 2  //pin d'interruption qui va declencher quand IGT0 est en front montant
#define IGTmodif 8           //pin qui va generer IGTmodif (qui va à ECU2)
//bool top = false;
int valeur;
float tensionVehicule = 0;
//float coef = 3 / 4;       //lecture du "12v" avec un pont diviseur de tension R1 = 30k et R2 = 10k
int dwellTime = 0;          //temps de déclenchement du signal sortant vers l'ECU2
unsigned long deb =  0;



void setup() {
  Serial.begin(115200);
  pinMode(IGTmodif, OUTPUT);
  digitalWrite(IGTmodif, LOW);

  pinMode(front_montantIGT0, INPUT);
  attachInterrupt(0, isr_IGTO, RISING);
  sei();
}

void isr_IGTO() {
  deb = millis();
  while ((millis() - deb) < dwellTime) { //temps d'allumage
    digitalWrite(IGTmodif, HIGH);
  }
  digitalWrite(IGTmodif, LOW);
}

void loop() {

  Serial.println("Tension: ");
  Serial.print(tensionVehicule);
  Serial.println();
  Serial.println("DwellTime: ");
  Serial.print(dwellTime);
}

//tension du véhicule est comprise entre 6V et 16V
//pont diviseur:
// VE 6 à 12
// R2 = 30000
// sortie 1.5V à 4V ==> A0  donneront 300 à 810
// R1 = 10000
// GND

void gestionDwellTime() {  //temps de mise à feu
  valeur = analogRead(A0) * (5 / 1023);
  tensionVehicule = map(valeur, 300, 810, 6, 16);

  if (tensionVehicule >= 16) {    //16V ET plus = 280ms
    dwellTime = 280;
  } else {
    if (tensionVehicule >= 15) {  //15V mais en dessous de 16V = 305ms
      dwellTime = 305;
    } else {
      if (tensionVehicule >= 14) {//14V mais en dessous de 15V = 330ms
        dwellTime = 330;
      } else {
        if (tensionVehicule >= 13) {//13V mais en dessous de 14V = 355ms
          dwellTime = 355;
        } else {
          if (tensionVehicule >= 12) {//12V mais en dessous de 13V = 380ms
            dwellTime = 380;
          } else {
            if (tensionVehicule >= 11) {//11V mais en dessous de 12V = 415ms
              dwellTime = 415;
            } else {
              if (tensionVehicule >= 10) {//10V mais en dessous de 11V = 450ms
                dwellTime = 450;
              } else {
                if (tensionVehicule >= 9) {//9V mais en dessous de 10V = 500ms
                  dwellTime = 500;
                } else {
                  if (tensionVehicule >= 8) {//8V mais en dessous de 9V = 550ms
                    dwellTime = 550;
                  } else {
                    if (tensionVehicule >= 7) {//7V mais en dessous de 8V = 625ms
                      dwellTime = 625;
                    } else {
                      if (tensionVehicule >= 6) {//6V mais en dessous de 7V = 700ms
                        dwellTime = 700;
                      }
                      else {
                        if (tensionVehicule < 6) {// en dessous de 6V = 700ms
                          dwellTime = 700;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Merci!

salut brasiligun
il manquait une initialistion de dwellTime au depart du prg
testes ce prog, il fonctionne chez moi.
j'ai viré la suite de if, la map le fait très bien.
attention ,en fonction des valeurs réelles des résistances, les résultats peuvent se trouver décalés par rapport à ceux calculés
au début dans la série de if, j'avais rajouté un "adjust" pour compenser.
mais comme j'ai viré les if.

#define front_montantIGT0 2  //D2 pin d'interuption qui va declencher quand IGT0 est en front montant
#define IGTmodif 8           //D8 pin qui va generer IGTmodif (qui va à ECU2)
unsigned long pulse = 0;
unsigned long garde = 100000;
unsigned long dwellTime = 4000;  //temps de déclenchement du signal sortant vers l'ECU2
float valeur;
float tensionVehicule = 0;
//byte adjust = 2;

void setup() {
  Serial.begin(115200);
  DDRD &= 0b11111011;                     //0 =  D2 en entrée
  DDRB |= 0b00000001;                     //1 =  D8 en sortie
  pinMode(front_montantIGT0, INPUT);
  attachInterrupt(0, isr_IGTO, RISING);  //INT 0 =interruption sur D2
  //Serial.println("pret");
  sei();
}

void isr_IGTO() {
  pulse = (micros() + dwellTime);  // init durée de l'impulsion
  PORTB |= 0b00000001;             // D8 passe à 1
}

void loop() {
  if ((micros()) > (pulse)) {      // si durée pulse ( + hysteresis) dépassée
    PORTB &= 0b11111110;           // D8 repasse à 0
    pulse = (micros()+garde);      // on force pulse sous hysteresis
    gestionDwellTime();    
  } 
}

//tension du véhicule est comprise entre 6V et 16V
//pont diviseur:
// VE 6 à 16
// R2 = 30000
// sortie 1.5V à 4V ==> A0  donneront 300 à 820
// R1 = 10000
// GND
//adjust est la pour compenser les tolerences des resistances
//dans mon cas les résultats mesurés avaient un delta de deux cases 
//avec les résultats mesurés.

void gestionDwellTime() {  //temps de mise à feu
  valeur = analogRead(A0 * (5 / 1023));
  valeur = constrain(valeur,300,1023);
  //Serial.println(valeur);
  dwellTime=(map(valeur, 300, 1023, 6000, 3000));
}
  /*
  tensionVehicule = (map(valeur, 300, 1023, 6, 20)+adjust);
  if (tensionVehicule > 16) {  //au dessus de 16, 
    dwellTime = 4000;          //dwellTime est bridé à 4000
  } else {
    if (tensionVehicule > 15) {
      dwellTime = 4200;
    } else {
      if (tensionVehicule > 14) {
        dwellTime = 4400;
      } else {
        if (tensionVehicule > 13) {
          dwellTime = 4600;
        } else {
          if (tensionVehicule > 12) {
            dwellTime = 4800;
          } else {
            if (tensionVehicule > 11) {
              dwellTime = 5000;
            } else {
              if (tensionVehicule > 10) {
                dwellTime = 5200;
              } else {
                if (tensionVehicule > 9) {
                  dwellTime = 5400;
                } else {
                  if (tensionVehicule > 8) {
                    dwellTime = 5600;
                  } else {
                    if (tensionVehicule > 7) {
                      dwellTime = 5800;
                    } else {
                      if (tensionVehicule > 6) {
                        dwellTime = 6000;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
*/

nota: j'utilise un générateur de fréquences, le signal est propre. et il m'envoit soit 1 soit 0. donc chez pas besoin de pullup ou pushdown.
20V
image

1 Like

Impec, je vais tester. La nous sommes sur des choses beaucoup plus pointues mais que je ne maitrise pas. Juste un petite question, les dwell time sont bien en ms?

Je te remercie