non, en micros
dwellTime = 4000µ correspond à 4ms
Je me suis permis de demander comme je ne joue jamais avec les micro, mais les millis
Pareil la map, il faut impérativement que mes valeurs soient les bonnes. J'ai peur d'avoir un décalage
J'ai peur que mes petites bobines crament directement en cas de décalage important
Pour être exactement aux valeurs voulues, la fonction de map n'est-elle pas un peu permissive, et le fait de faire des conditions certes un peu répétitives, ne forceraient pas à rester des les plages voulues par voltages?
6 volts, 7ms alors que ton signal dure 6ms, ce n'est possible que si le deuxième signal arrive après les 7ms,
pour les valeurs justes, je vais voir. je suis parti sur les valeurs que tu utilisais, soit de 4ms à 6ms
avec les valeurs que tu donnes maintenant, celles du deuxième tableau, la progression n'est pas linéaire.
donc oui, il faut repartir sur les if successifs.
#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 = 2800; //dwellTime est bridé à 2800
} else {
if (tensionVehicule > 15) {
dwellTime = 3050;
} else {
if (tensionVehicule > 14) {
dwellTime = 3300;
} else {
if (tensionVehicule > 13) {
dwellTime = 3500;
} else {
if (tensionVehicule > 12) {
dwellTime = 3800;
} else {
if (tensionVehicule > 11) {
dwellTime = 4100;
} else {
if (tensionVehicule > 10) {
dwellTime = 4500;
} else {
if (tensionVehicule > 9) {
dwellTime = 5000;
} else {
if (tensionVehicule > 8) {
dwellTime = 5500;
} else {
if (tensionVehicule > 7) {
dwellTime = 6250;
} else {
if (tensionVehicule > 6) {
dwellTime = 7000;
}
}
}
}
}
}
}
}
}
}
}
}
edit, chez moi adjust est passé à 1
J'avoue ne pas comprendre le fonctionnement de adjust.
Et réellement, certaines valeurs du tableau ne peuvent pas se réaliser.
Elles doivent être là "au cas ou", mais les cas qui vont être utilisés sont entre 11 et 14V (le régulateur de tension du circuit de charge (alternateur + régul + batterie veille au grain).
Après aucun problème si les IGTmodif dépasse le temps d'IGT0, car l'ECU split et envoi le signal PAR bobines. Donc la 1 va travailler pendant que 2 - 3 - 4 sont au repos. Ensuite 3 va travailler pendant que 1 - 4 - 2 au repos et ainsi que suite. Ordre d'allumage en 1-3-4-2
ECU 2 transforme un signal unique en des signaux séquentiels pour la bobine qui doit recevoir son signal (par le controle d'un capteur d'arbre à came mais le sujet est autre)
Donc nous le but était vraiment :
- intercepter IGT0 (qui fait 6ms quoi qu'il arrive). La fréquence entre le front décendant et le prochain front montant est geré par le calculateur (cela correspond à l'avance à l'allumage + au tours minutes)
- transformer IGT0 en signal IGT modif avec un temps défini par la tension du circuit de charge. IGTmodif doit démarrer en même temps que le front montant d'IGT0.
-> ensuite c'est ECU2 qui transforme ce signal unique, en 4 signaux. Un seul signal à la fois, vers la bobine qui correspond au cylindre qui est sur son cycle d'allumage (moteur 4 temps).
Les deux conditions préalables sont repesctées, je pense que le projet est prêt pour essais!
Dernier petis secret: mes bobines toyota, ont une sécurité intégrée, elles sont entre des dumb coils et des smart coils. En cas de tout petit signal trop court, elles ont un temps minimum de déclenchement pré-enregistré. Par contre, l'inverse n'existe pas, elles ne peuvent pas se réguler avec un signal trop long
edit: nos posts se sont croisés
c'est le moment des questions:
es tu sur de toi?
sur un 4 temps 4 cylindres, je vais avoir 4 explosions en 2 tours moteur, soit deux explosions par tour. exact?
avec 6800 tr/minute au rupteur, j'ai 6800/60 =113 tr/s . d'ou 113*2 = 226 explosions secondes
et 1000/226=4.42ms et le maxi autorisé est de 6ms
ECU1 à une seule sortie signal carré partie utile = 6ms constante.
ECU2 va sortir un signal vers le delco?
le train d'impulsion à 7ms va se faire transformer en une constante continue de 5V
adjust sert à corriger une erreur possible due à l'imprécision des valeurs de résistances.
chez moi, une tension d'entrée dans le pont diviseur égale à 7 me donnait en sortie des if la valeur qui correspondait au if d'à coté.
d'ou adjust = 1
Il n'y a plus de delco, je l'ai dégagé.
Initialement, IGT0 envoi son signal à un allumeur, qui lui diminu le signal pour un signal carré de 4ms. Une delco / un allumeur / une bobine
Pour l'essais, jai choppé 4 bobines d'origines + 4 allumeur, mon ECU 2 sait transformer 1 entrée en 4 sorties séquentielles. J'ai donc déjà (et ça roule) 1 allumeur et 1 bobine par cylindre piloté par ECU2 qui declenche les allumeurs dans le bon ordre. Il rentre avec 1 seul signal de 6 ms, et sors 4 signaux de 6 ms mais avec un seul canal à la fois
Relevés fait à l'oscilloscope
je veux passer à des bobines crayons, sans allumeurs. Je dois juste donc fournir un signal "raccourci" qui correspond au temps et à la tension souhaité. Par simplicité matériel, j'ai voulu intercepter ce signal "avant" ECU2 pour avoir 1 seul signal à transformer comme les arduino ont seulement 2 pin interruption.
Sinon au tout début, je voulais intercepter les 4 signaux de ECU2, mais pas assez de pin interrupt avec mes nano ou ma uno. Mais avec du recul, la gestion serait plus propre
EDIT:
Montage origine :
La modif 1 entrée, 4 canaux par ECU2:
Utilisation acutelle en haut, projet en bas:
Arduino après ECU2?
En vrai actuellement, x4 allumeurs et x4 bobine:
tu aurais préféré 4 entrées interruptibles et 4 sorties différentes?
Je me dis que ça aurait peut-etre été plus propre. Et plus proche de ce qu'on souhaite piloter. Peut-etre
Et si j'ai bien compris, les arduino UNO et les nano n'ont que 2 pins d'interruption. Il me faudrait autre chose, ou une nano every qui possède beaucoup plus de pin d'interruptions. C'est bien ça?
Hello, Pour parler simplement
Le microcontrôleur 328 possède deux interruptions que je dirai "directes"
Un évènement se produit sur D2ouD3 et une fonction dite d'interruption est exécutée immédiatement.
MAIS ce microcontrôleur possède aussi des interruptions par "port". Un port est constitué de huit entrées/sorties. On peut parler d'un octet dont chacun des bits correspond à une entrée/sortie.
Lorsque les registres internes au micro sont initialisés correctement, une fonction de tri est appelée en premier afin de déterminer sur quel bit du port s'est produit l'événement.
Et ensuite, on traite la réaction appropriée.
Le nombre d'interruptions n'est donc pas le problème.
Si tu en as besoin, je veux bien regarder ça de près.
Franchement avec plaisir, je suis une cave sur le sujet Mais c'est super intéressant, surtout que chaque allumage de cylindre se produit individuellement, cette utilisation peut-être possible
hello
avec la tension >16V
et avec la tension <6V
avec une uno, j'ai utilisé D8,D9,D10,D11 en entrées interruptibles
elles déclenchent le timer 1 chacune à leur tour.
la durée du timer varie en fonction de la tension de l'alternateur soit pour 5 Vet moins ==>7ms et pour 16V et plus ==>2.8ms
les tensions intermédiaires donnent des durées selon ton tableau.
les signaux temporisés sortent en D4,D5,D6,D7.
pour faire mes tests, j'ai fais un petit prg tout simple pour simuler les signaux d'origine pour un moteur 4 temps
j'ai donc utilisé 2 UNO et un petit Saelae 8 canaux.
sans oublier le pont diviseur 30K/10K (30 avec 27 et 3.3)
avec mon alim, je me baladais entre 0V et 20 V ( 20V =4.96V en sortie du pont) d'ou une bonne marge pour la platine arduino
sur les copies d'écran, le canal 0, à pene visible en haut de l'écran correspond au signal du cylindre 1.
le canal 1 correspond à a sortie du signal1
le canal 2 correspond à l'entrée du signal du cycimdre 4
le canal 3 correspond à la sortie du signal 4
le canal 4 correspond à l'entrée du signal du cycimdre 3
le canal 5 correspond à la sortie du signal 3
le canal 6 correspond à l'entrée du signal du cycimdre 2
le canal 7 correspond à la sortie du signal 2
nota, pour raccorder le saelae, j'ai dupliqué les sorties des signaux sur A0,A1,A2,A3 ( du UNO simulateur)
voici le prog de simulation des signaux
const byte bob_1= 8;// port B bit 0
const byte bob_2= 9;// port B bit 1
const byte bob_3=10;// port B bit 2
const byte bob_4=11;// port B bit 3
const byte bob_11= 14;// port B bit 0
const byte bob_22= 15;// port B bit 1
const byte bob_33=16;// port B bit 2
const byte bob_44=17;// port B bit 3
void setup() {
Serial.begin(115200);
pinMode(bob_1,OUTPUT);
pinMode(bob_2,OUTPUT);
pinMode(bob_3,OUTPUT);
pinMode(bob_4,OUTPUT);
pinMode(bob_11,OUTPUT);
pinMode(bob_22,OUTPUT);
pinMode(bob_33,OUTPUT);
pinMode(bob_44,OUTPUT);
}
void loop() {
digitalWrite(bob_1,HIGH);
digitalWrite(bob_11,HIGH);
Serial.println("1");
delay(6);
digitalWrite(bob_1,LOW);
digitalWrite(bob_11,LOW);
delay(10);
digitalWrite(bob_4,HIGH);
digitalWrite(bob_44,HIGH);
Serial.println("4");
delay(6);
digitalWrite(bob_4,LOW);
digitalWrite(bob_44,LOW);
delay(10);
digitalWrite(bob_3,HIGH);
digitalWrite(bob_33,HIGH);
Serial.println("3");
delay(6);
digitalWrite(bob_3,LOW);
digitalWrite(bob_33,LOW);
delay(10);
digitalWrite(bob_2,HIGH);
digitalWrite(bob_22,HIGH);
Serial.println("2");
delay(6);
digitalWrite(bob_2,LOW);
digitalWrite(bob_22,LOW);
delay(10);
}
voici le prog de traitement des signaux
inter_PCINT_UNO_brasili_V2.zip (3,1 Ko)
La vache quel truc! C'est à des années-lumières de ma capacités. Pardon c'est indiscret, mais tu travail dans un secteur traitant des signaux ou qui touche aux filtrages?
C'est extrêmement pointu, même en terme de matériel utilisé.
Je vais me poser pour tout décortiquer, mais un grand merci pour le temps de dingue que tu as du passer !
J'ai interpreté le code comme j'ai pu, c'est vraiment pointu.
Concernant la petite partie que je peux gerer, je ne comprends pas les valeurs pour le dwell time:
Par exemple, comment 6000 peuvent faire de 3.05 à 3.10? "dwellTime = 6000; //3.05ms 3.10"
dwellTime = 9000; //7ms 7.00 -> je n'arrive pas à trouver le calcul ou la façon dont c'est utilisé. Naivement, je lis 9ms et pas 7 dans ce cas là
Je te remercie
void gestionDwellTime() { //temps de mise à feu
valeur = constrain(analogRead(A0 * (5 / 1023)), 300, 830);
//Serial.print('\t');//Serial.println(valeur);
//valeur = constrain(valeur,300,830);
//Serial.print(valeur); Serial.print('\t');
// dwellTime=(map(valeur, 300, 830, 6000, 3000));
tensionVehicule = (map(valeur, 300, 830, 6, 17)); //+adjust);
Serial.println(tensionVehicule);
if (tensionVehicule >= 16) { // egal et au dessus de 16,
dwellTime = 5600; //2.80 ms dwellTime est bridé à 4500
} else {
if (tensionVehicule >= 15) {
dwellTime = 6000; //3.05ms 3.10
} else {
if (tensionVehicule >= 14) {
dwellTime = 6600; //3.3ms 3.30
} else {
if (tensionVehicule >= 13) {
dwellTime = 7150; //3.55ms 3.57
} else {
if (tensionVehicule >= 12) {
dwellTime = 7600;//3.8ms 3.80
} else {
if (tensionVehicule >= 11) {
dwellTime = 8300;//4.15ms 4.15
} else {
if (tensionVehicule >= 10) {
dwellTime = 9100;//4.5ms 4.55
} else {
if (tensionVehicule >= 9) {
dwellTime = 10000;//5ms 5.00
} else {
if (tensionVehicule >= 8) {
dwellTime = 11000;//5.5ms 5.50
} else {
if (tensionVehicule >= 7) {
dwellTime = 12500;//6.25 6.253
} else {
if (tensionVehicule >= 6) {
dwellTime = 14000; //7ms 7.00
} else {
if (tensionVehicule < 6) {
dwellTime = 9000; //7ms 7.00
}
}
}
}
}
}
}
}
}
}
}
}
}
hello
je viens de recharger le prog après avoir changé la derniere valeur de <6 qui était restée à 9000. je l'ai passée à 14000
if (tensionVehicule >= 16) { // egal et au dessus de 16,
dwellTime = 5600; //2.80 ms dwellTime est bridé à 4500
} else {
if (tensionVehicule >= 15) {
dwellTime = 6000; //3.05ms 3.10
} else {
if (tensionVehicule >= 14) {
dwellTime = 6600; //3.3ms 3.30
} else {
if (tensionVehicule >= 13) {
dwellTime = 7150; //3.55ms 3.57
} else {
if (tensionVehicule >= 12) {
dwellTime = 7600;//3.8ms 3.80
} else {
if (tensionVehicule >= 11) {
dwellTime = 8300;//4.15ms 4.15
} else {
if (tensionVehicule >= 10) {
dwellTime = 9100;//4.5ms 4.55
} else {
if (tensionVehicule >= 9) {
dwellTime = 10000;//5ms 5.00
} else {
if (tensionVehicule >= 8) {
dwellTime = 11000;//5.5ms 5.50
} else {
if (tensionVehicule >= 7) {
dwellTime = 12500;//6.25 6.253
} else {
if (tensionVehicule >= 6) {
dwellTime = 14000; //7ms 7.00
} else {
if (tensionVehicule < 6) {
dwellTime = 14000; //7ms 7.00
j'ai recommencé la manip suivante.
tension à 4 V . capture avec le saelae: temps d'impulsion attendue = 7ms. temps mesuré à l'écran :7ms
tension à 6 V . capture avec le saelae: temps d'impulsion attendue = 7ms. temps mesuré à l'écran :7ms
tension à 8 V . capture avec le saelae: temps d'impulsion attendue = 5.5ms. temps mesuré à l'écran :5.5ms
tension à 10 V . capture avec le saelae: temps d'impulsion attendue = 4.5ms. temps mesuré à l'écran :4.5ms
tension à 12 V . capture avec le saelae: temps d'impulsion attendue = 3.8ms. temps mesuré à l'écran :3.8ms
tension à 14V . capture avec le saelae: temps d'impulsion attendue = 3.3ms. temps mesuré à l'écran :3.3ms
tension à 16 V . capture avec le saelae: temps d'impulsion attendue = 2.8ms. temps mesuré à l'écran :2.8ms
tension à 18 V . capture avec le saelae: temps d'impulsion attendue = 2.8ms. temps mesuré à l'écran :2.8ms
hello
voici les calculs:
sachant que le timer travaille avec un prescaler de 8
durée d'un cycle : 1/16000000 = 6.25nanos
durée d'un cycle pour timer 6.25 * 8 = 0.0000005 Seconde
durée du cycle en millis 0.0000005*1000=0.0005
tempo pour 16V = 5600 * 0.0005 = 2.8 ms
tempo pour 14V = 6600 * 0.0005 = 3.3 ms
tempo pour 12V = 7600 * 0.0005 = 3.8 ms
tempo pour 10V = 9100 * 0.0005 =4.55 ms
tempo pour 8V = 11000 * 0.0005 = 5.5ms
tempo pour 6V = 14000 * 0.0005 = 7.0ms
je n'avais pas fait les calculs. valeurs trouvées avec les graph du saelae. je n'étais pas tombé loin
je te laisse modifier la valeur pour 10V qui donne une tempo trop longue de 50 µs
4.5 ms / 0.0005 = 9000
edit: : les interruptions déclenchent sur les fronts montants des signaux d'entrée, ce qui signifie que ces signaux peuvent etre très courts.( pas besoin de 6 millis)
Impeccable, merci pour les explications et pour ton retour! Je vais me mettre en ordre de bataille pour les essais.
Je me permets de revenir sur un de tes précédents post, que voulais-tu dire par :
sans oublier le pont diviseur 30K/10K (30 avec 27 et 3.3)?
Le pont diviseur avec les deux résistances de 10K et 30k pas de probleme, mais je ne saisis pas le 30 avec 27 et 3.3
Je te remercie, bonne soirée
Hello
J'ai bien 10k, mais pas 30k
J'ai donc mis en série 27ket3.3k pour avoir 30.3k
Donc chez moi,le pont diviseur est 10k/30.3k