Résolu Boitier E85 avec un Arduino nano

hello
pour un néophyte en mécanique, le système, c'est quoi ?

ce que je crois savoir:
normalement, le calculateur " calcule un temps d'injection, il met à low les injecteurs chacun à leur tour en fonction de l'ordre d'allumage pour le type de moteur.

mes questions:

le principe, c'est quoi? la sonde lambda te donne une température, et en fonction de cette température, tu modifies le ratio du mélange air/essence pour arriver à une explosion optimale qui aura la température idéale ?

ton système regarde en boucle l'état des commandes d'injecteur et lorsqu'un injecteur est à low, si la sonde lambda le demande, il fait un calcul d'allongement ou pas du temps à LOW.

ton calculateur est toujours en service. comment peux tu raccourcir le temps alors que le calculateur demande un temps plus long que ton système? le calculateur fais son boulot et va maintenir le temps initial.

si tu maintiens le temps des injecteurs plus longtemps, et que tu repiques la cde des injecteurs en entrée de ton système, ne craint tu pas que la sortie boucle sur l'entrée ?

bon après reflexion, je pense que les sorties du calculateur entrent dans ton montage et que seules les sorties de ton montage sont raccordées aux injecteurs.
là, tout devient possible. :slight_smile:

maintenant, c'est quoi cette 2ème sortie qui doit être actionnée au milieu du temps de la 1ère.
que fait elle? il y a 1 sortie supplémentaire pour chaque injecteur?

lorsque tu fais

cmpt= (micros() - time3);time3=micros();cmpt3=cmpt*(valeur/1000);// calcule pour le temps d'injection suivant le LAMBDA
delayMicroseconds(cmpt3);// injection en plus

tu pourrais faire:

cmpt= (micros() - time3);time3=micros();cmpt3=cmpt*(valeur/1000);
si nb_tours>3000
{
delayMicroseconds(cmpt3/2);// 1/2 temps injection en plus
2ème sortie=1;
delayMicroseconds(cmpt3/2);// 1/2 temps injection en plus
}
else
{
delayMicroseconds(cmpt3);// 1/1 temps injection en plus
}

Je ne peux pas prendre en considération le régime moteur, risque de ralentissement du programme et pas utile pour les commutations, en fait ce que je recherche c'est de commuter une sorties compter le temps et si une autre commande intervient faire la même chose toute en regardant si il y a un changement d'état pour allonger ou diminuer le temps. Car mon programme le fait broche par broche. Ce soir je mets la photo des commutations prise par l'Analyzer logique pour mieux comprendre.
La sonde lambda est un capteur pour l'anti-pollution et avoir une combustion parfaite du mélange. Elle doit être à 1 (1V) pour être parfait.

Le calculateur se fit à la sonde lambda pour réguler le temps d'injection, avec du E85 il faut augmenter ce temps entre 20 et 25%, le calculateur fait le reste.
Le programme ne peut pas diminuer le temps d'injection c'est au calculateur de le faire, c'est pour cela que j'ai volontairement bridé a 1 le minimum et 40% au maxi.

tu es en train de dire :
que ton prg lis la sonde toutes les 10 secondes et fais ses corrections en fonction de sa lecture.

que tu veux lire la sonde en permanence pour modifier la correction de temps d'ouverture en temps réel

c'est bien ça?

lecture du lambda après 10mn et toutes les 10s.
10mn pour le chauffage du moteur.
10s pour le réglage du lambda en temps réel.

En fait je recherche un code qui utiliserais:
PCINT3 Interruption externe sur les broches 0 à 7
LOW : l’interruption est déclenchée quand la broche concernée est LOW.

attachInterrupt(numéro, ISR, mode);

a savoir si c'est possible pour mon montage.

Si c'est pour gérer les interruptions sur un port tu peux lire mon tuto : Interruptions ATMega 328p - Tutoriels et cours - Arduino Forum

Pas de fonctions arduino attachInterrupXXXXt().
C'est de la gestion directement par les registres, cela reste très simple car en programation je ne sais pas faire des choses compliquées.

Merci je vais le lire a tête reposée.

Voilà je mets les images pour mieux comprendre mon problème.

ok, là on comprend tout de suite le problème

par contre, tu veux compter sur deux timers, mais qu'en est il de la pompe?
n'est elle pas perturbée de devoir fournir sur deux injecteurs en même temps?

en supposant que non, le temps de recouvrement sur 2 injecteurs doit fausser le débit et devrait, je suppose, demander un allongement supplémentaire du temps d'injection ?

Non là c'est en mode réel constructeur sortie du calulo. Oui en effet je veux compter sur 2 timers en me servant si possible des interruptions pour gagner du temps dans le programme

Le hic je ne sais pas comment mi prendre, mon idée: détecter un changement d'état et lancer un compteur si une autre broche change on lance un deuxième compteur si l'un ou l'autre change on intervient et on rajoute ce qui a été mémorisé et on continue.

à 6000 tr, tu as une injection toutes les 3ms on vois sur ton analyseur que l'injection dure pratiquement 6ms.

utiliser les interruptions ne te donnera rien, les injections durent 6 ms et elles se recouvrent.

la seule façon de t'en sortir est d'utiliser 2 timers en alternance.

bien sur, je te dis ça sans y avoir réfléchi sérieusement.

Très bon TUTO 68tjs je vais faire des essai avec tes codes voir si je peux les modifier pour mon usage.

par contre on peux avoir des variables volatile du temps avec les timers

effectivement, si on veut faire du temps-réel, il faut oublier toutes les fonctions arduino, ainsi que toutes les libs d'internet et travailler en mode µC, c-a-d en accès direct avec les registres.

le datasheet de l'ATMEL sera ton unique et seule amie sur ce coup-là, mais il faut quand même savoir la lire, et donc avoir un minimum de notions. (RTFD)

Sur un tel programme, la void loop() devrait être vide, tout se traitant en interruptions. Toutes les communications doivent se faire en direct, et surtout pas de truc genre one wire qui mettent un temps pas possible à réagir et ralentissent ton programme. Une bonne vieille sonde analogique fera des merveilles, à condition de gérer toi-même le CAN, et pas de analogRead().

En résumé, un tel programme pour débuter, c'est pas une bonne idée...

En optimisant le code, tu peux multiplier par 20 la vitesse d'exécution.

par exemple, quand tu appelles une fonction, tu perds d'entrée de jeu 500ns. 6 fonctions, et pouf, 3ms de perdues...

Bonjour, merci pour votre aide je vais essayer de la faire uniquement avec les interruptions avec les traitements en assembleur, oui je vais monter une sonde analogique, pas très compliqué pour mon utilisation. Après mon autre idée est de le faire avec 3 ARDUINO en repérant les cylindres. Je revient vers vous une fois fini.
Marcus.

Perso voici comment je gèrerai les choses :

boucle {

calculLambda() // mise à jour de delai

// scan des entrée
for(i=0;i<6;i++) {

bit = 1<<i

//si commande injecteur
si (!(PINB&bit) && actif[i]==0) alors  {

actif[i]=1
PORTD |= ~(bit)
timing[i]=micros()

}

//si command en cours
si (actif[i]==1) alors {

//si temps écoulé
si (micros()>=timing[i]+delai) { 
PORTD &= ~(bit)
actif[i]=0;
}

}


}


}

Globalement y'aura assez peu de perte mais si on est à la µs près c'est sûr que chaque cycle coûte cher ...

Merci pour le bout de code je vais essayer de l'exploité.

Bonsoir, j'essaie de faire un bout de programme en utilisant les interruptions de port sans la boucle Loop rien à faire si je ne mets pas Loop j'ai un message d'erreur a la compilation et si je mets la boucle Loop vide il reste bloqué. Comment faire?

/// ARDUINO UNO - IT Externe 0
// Fonction de IT externe 0 (broche PD2)
ISR(INT0_vect){
PORTB ^= (1<<PORTB5);
}
void setup(){
  Serial.begin (9600);
//Configuration PORTB.5
DDRB |= B1000000; // PB5 en sortie
PORTB &= ~(1<<PORTB6); // PORTB.5 <-0
// Configuration PORTD.2/INT0
DDRD &= B11111011; // PD2 en entrée
PORTD |= (1<<PORTD2); // PORTD.2=1
// active pull-up
EIMSK |= 1; //IT INT0 prise en compte
EICRA = B10; // IT = front négatif sur PD2
sei(); // activation des IT (SREG.7=1)
}
void loop()
{Serial.println("boucle loop"); }
/*
Configuration
PORTB.5 en sortie = gestion de le LED
PORTD.2 en entrée avec pull-up interne activée = gestion du bouton poussoir
soit DDRD.2=0 ET PORTD.2=1 (cf 4.2 DIGITAL I/O)
Autorisation de la source d'IT INT0 : EIMSK= (0000 0001)b
Interruption sur front négatif sur INT0 : EICRA= (0000 0010)b soit ISC01=1 ISC00=0
 */