Bonjour, je suis nouveau sur le forum et débutant en programmation. Merci de votre compréhension.
Donc je travaille sur un projet d'un boitier pour rouler avec du E85 avec un ARDUINO NANO pour un moteur V6. J'ai fait un code qui fonctionne presque bien, au ralenti pas de problème à partir de 3000 Tr/mn il ne fonctionne plus car mon code ne fait pas les commutations de broches en même temps. J'ai recherché un moyen par les interruptions mais je n'y comprends rien (je débute).
Le principe du code est de lire la sonde lambda et de rajouté du temps d'injection par pas de 1%, donc calcul du temps d'injection en maintenant la broche a l'état bas et rajouter 1% sauf qu'a 3000Tr/mm il y faut commuter une autre broche en plein milieu de la première. J'ai vue ça avec un analyseur logique.
Avez-vous une idée pour faire cela?
*************************************************************************************************************************
****************************************************************************************************************************
****************************************************************************************************************************
****************************************** BROCHAGES ARDUINO NANO ********************************
****************************************************************************************************************************
******** Entrée injecteur 1 sur la broche 8 Sortie injecteur 1 sur la broche 2 ********************************
******** Entrée injecteur 2 sur la broche 9 Sortie injecteur 2 sur la broche 3 ********************************
******** Entrée injecteur 3 sur la broche 10 Sortie injecteur 3 sur la broche 4 ********************************
******** Entrée injecteur 4 sur la broche 11 Sortie injecteur 4 sur la broche 5 ********************************
******** Entrée injecteur 5 sur la broche 12 Sortie injecteur 5 sur la broche 6 ********************************
******** Entrée injecteur 6 sur la broche 13 Sortie injecteur 6 sur la broche 7 ********************************
******** Capteur température d'eau moteur broche A2 1-whire ********************************
******** Sonde LAMBDA A3 analogique avec conversion en volt ********************************
******** Sauvegarde de la valeur broche A4 LOW ********************************
******** Blocage du programme mode normal broche A5 LOW ********************************
******** Passage de la valeur a 25% d'un coup broche A6 LOW ********************************
****************************************************************************************************************************
*/
#include <EEPROM.h>
#include <OneWire.h>
long int cmpt; // compteur d'injection
int valeur=0; // Pourcentage E85 mis en mémoire dans l'EEPROM
int valeur2; // Pour le stater
float temp = 0 ; // Température eau
long int cmpt3; // Résultat opération d'injection
float Lmda; // Sonde Lambda
long int valeur3; // Pour le passage du LAMDBA
int x; // PORTB
int z; //PORTD
// moyenePin = A1; // Valeur a 25%
int analogPin = A2; //initialisation de la sonde Lambda sur A2 (analogique)
// entre 0.9 et 1 volt a mesurer
// A3 // Broche utilisée pour le bus 1-Wire
// savePin = A4; // Sauvegarde de la valeur dans l'EEPROM
// resetPin = A5; // Reset valeur
int t_lambda_S; // pour le blocage du LAMBA et du starter
unsigned long time2; // Pour le calcul du temps Lambda/Starter
unsigned long time; // Temps de fonctionnement du programme
unsigned long time3; // Temps pour l'injection
// VARIABLES POUR LES INJECTEURS Entrés Sorties
byte S_inj_[7]={2,3,4,5,6,7,8};
byte E_inj_1;
byte E_inj_2;
byte E_inj_3;
byte E_inj_4;
byte E_inj_5;
byte E_inj_6;
byte inj_[7]={0,1,2,3,4,5,6};
//****************************************************** récupérer sur le net pour le calcul de la température moteur
#define DS18B20 0x28 // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE A3 // Broche utilisée pour le bus 1-Wire
OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
// Fonction récupérant la température depuis le DS18B20
// Retourne true si tout va bien, ou false en cas d'erreur
boolean getTemperature(float *temp){ // data : Données lues depuis le scratchpad
byte data[9], addr[8]; // addr : adresse du module 1-Wire détecté
if (!ds.search(addr)) { // Recherche un module 1-Wire
ds.reset_search(); // Réinitialise la recherche de module
return false; } // Retourne une erreur
if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
return false; // Si le message est corrompu on retourne une erreur
if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
return false; // Si ce n'est pas le cas on retourne une erreur
ds.reset(); // On reset le bus 1-Wire
ds.select(addr); // On sélectionne le DS18B20
ds.write(0x44, 1); // On lance une prise de mesure de température
delayMicroseconds(20); // Et on attend la fin de la mesure 4 micros seconde.
ds.reset(); // On reset le bus 1-Wire
ds.select(addr); // On sélectionne le DS18B20
ds.write(0xBE); // On envoie une demande de lecture du scratchpad
for (byte i = 0; i < 9; i++) // On lit le scratchpad
data[i] = ds.read(); // Et on stock les octets reçus
*temp = ((data[1] << 8) | data[0]) * 0.0625; // Calcul de la température en degré Celsius
return true; // Pas d'erreur
}
//_____________________________________________________________________________________________________________________
//_________________________________________________________ DEBUT DU SETUP __________________________________________
//_____________________________________________________________________________________________________________________
void setup()
{
//**********************************************************************************************************************
// Lecture de la valeur à l'adresse 500 de l'EEPROM
valeur = EEPROM.read(500);
valeur2=(valeur);
//**********************************************************************************************************************
// on met les broches pour les injecteurs en entrée et a l'état HAUT (port B de 8 à 13)
// on met les broches 0 à 7 en sortie (port D de 0 à 7) (0 et 1 sont les broches Rx Tx) et a l'etat Haut
DDRB = B00000000;
PORTB = B11111111;
DDRD = B11111111;
PORTD = PORTD |B11111100;
//***********************************************************************************************************************
(getTemperature(&temp));// Lecture de la température une fois, ralentis le programme. *****
//***********************************************************************************************************************
time = millis(); // Initialisation du temps
time3 = micros(); // Initialisation pour le temps d'injection
//-----------------------------------------------------------------------------------------------------------------------
for (int z=0; z<=7; z++) // compteur pour les varibles
{byte E_inj_[z];byte inj_[x];}
//************************************************************************************************************************
// Starter a 50% si température < 30° et si 15% en plus en memmoire *****
//************************************************************************************************************************
if ((temp < 30.00) && (valeur >= 115))// environ 15%
{t_lambda_S=1; valeur=153;}// starter a 50%
else
{t_lambda_S=2; valeur=0;}// mode normal
}
//************************************************************************************************************************
// CALCUL DU LAMBDA (INT LAMBDA) *****
//************************************************************************************************************************
int lambda (int valeur3)
{
// on lit le LAMBDA
Lmda = (analogRead(A2)*5.0) / 1024 ;
// On regle le LAMBDA entre 0.95 et 1.05 par pas de 0.1%
// moins 0.1%
if (Lmda < 0.95)
{valeur = (valeur -0.5); if (valeur<1){valeur=0;}} // blocage à 0% = 1µs
// plus 0.1%
if (Lmda > 1.05)
{valeur = (valeur +0.5);if (valeur>140){valeur=140;}}
// blocage a 40%
}
/*********************************************** FONCTIONNEMENT ********************************************************
*** Temps d'injection entre 3 et 5ms a 650 T/mn 11 tours/s à 6000 T/mn 100T/s 300 injections/T ***
*** ordre d'allumage V6 1.4.3.6.2.4. 3 explosions par tour. ***
*** Le calculateur voiture talonner si il y a du E85, le programme vas ajouter du temps car le Lambda > a 1. ***
*** Si pas de E85 le calculateur voiture vas réguler l'injection. ***
*** On va mesurer le Lambda toute les 10 secondes pour laisser du temps au calculateur. ***
*** Si la température d'eau > 30° (variable temps) pas de starter. ***
*** Si température < 30° on passe en mode starter a 50% pendant 10 secondes si la valeur de l'EEPROM > 15% ***
*** Problème qui peut se produire: le calculateur diminue le temps d'injection et le programme ajoute du temps, ***
*** jusqu’au moment où le calculateur sera en talon bas pour cette raison on ne dépasse pas les 40% d'injection maxi ***
*** ***
*** ++++++++++++++++++++++++++++++++ GESTION DES INJECTEURS ++++++++++++++++++++++++++++ ***
*** ***
*** Le calculateur commande les injecteurs par un état BAS. On scrute les injecteurs sur le port B. ***
*** On bloque la broche du port D à l'état BAS et on compte. ***
*** On règle l’injection pour avoir un l'LAMBDA entre 0.95 (trop d'essence) et 1.05 (trop d'air) par pas de 0.5%. ***
***************************************************************************************************************************
*/
//************************************************** PROGRAMME INJECTION (INT INJECTEUR) ********************************
int injecteur(float valeur,int z, int x)//passage de variable pour enrichissement du mélange
// "valeur" pour l'injection en plus "Z" pour le PORTD "X" pour le PORTB
// Temps pris par le programme pour le changement d'état entre 8 et 10µs.
{
while ((PINB & (1 << x))>>x== LOW)
{; PORTD = ~(1 << (z)); } // On passe la sortie a 0 et on attend le changement d'état
cmpt= (micros() - time3);time3=micros();cmpt3=cmpt*(valeur/1000);// calcule pour le temps d'injection suivant le LAMBDA
delayMicroseconds(cmpt3);// injection en plus
PORTD = ~(0 << (z));
cmpt=0;cmpt3=0;// on remet la sortie a 1
}
//________________________________________________________________________________________________________________________
//________________________________________________ FIN DU SETUP _____________________________________________
//________________________________________________________________________________________________________________________
//...
//................................................ .......................................
//................................................ BOUCLE PROGRAMME PRINCIPAL .......................................
//................................................ .......................................
//...
void loop(){
//********************************************* MISE EN PLACE DES VARIABLES INJECTEURS ***********************************
E_inj_1 = (PINB & (1 << 0));
E_inj_2 = (PINB & (1 << 1))>>1;
E_inj_3 = (PINB & (1 << 2))>>2;
E_inj_4 = (PINB & (1 << 3))>>3;
E_inj_5 = (PINB & (1 << 4))>>4;
E_inj_6 = (PINB & (1 << 5))>>5;
//****************************************** Suivant l'injecteur on passe les paramètres *********************************
if (E_inj_1 == LOW)
{z=2;x=0;inj_[x]= E_inj_1; injecteur (valeur,z,x);}
if (E_inj_2 == LOW)
{z=3;x=1;inj_[x]= E_inj_2; injecteur (valeur,z,x);}
if (E_inj_3 == LOW)
{z=4;x=2;inj_[x]= E_inj_3; injecteur (valeur,z,x);}
if (E_inj_4 == LOW)
{z=5;x=3;inj_[x]= E_inj_4; injecteur (valeur,z,x);}
if (E_inj_5 == LOW)
{z=6;x=4;inj_[x]= E_inj_5; injecteur (valeur,z,x);}
if (E_inj_6 == LOW)
{z=7;x=5;inj_[x]= E_inj_6; injecteur (valeur,z,x);}
//****************************************************** LAMBDA *********************************************************
if ((t_lambda_S==1) && (millis() - time2 > 10000)) // 10 seconde passage en normale si starter
{time2= millis(); valeur=valeur2; t_lambda_S=2;}// pour la lecture du LAMBDA dans 10 minutes
if (( t_lambda_S == 2) && (millis() - time2 > 60000))// lectures du LAMBDA après 10 minutes
{time2= millis();t_lambda_S=3;lambda(valeur3=10);}// blocage
if ((t_lambda_S ==3) && (millis() - time2 > 10000))// lecture du LAMBDA toutes les 10 secondes après les 10 minutes
{time2= millis();lambda(valeur3=10);}
//***************************************************************** EEPROM ************************************************
// Mise en mémoire du pourcentage de E85 à l'adresse 500 si la broche "X" est a l'état bas, coupure du contact et maintien
// par condo pour sauver la valeur
if ((PINC & (1 << 4))>>4 == LOW)
{EEPROM.write(500, (valeur));delay(50); PORTC |=_BV(PC4);}
//**************************************************** RESET VALEUR *******************************************************
if ((PINC & (1 << 5))>>5 == LOW)
{EEPROM.write(500, (valeur=0));delay(50); PORTC |=_BV(PC5); valeur=0;}
//**************************************************** PASSAGE A 25% D'UN COUP *******************************************
if ((PINC & (1 << 1))>>1 == LOW)
{EEPROM.write(500, (valeur=125));delay(50); PORTC |=_BV(PC1); valeur=125;}
}
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.
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.
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.
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.
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