Lecture de la tension d'une sonde Lambda et affichage

Bonjour les Arduiniens,

Je vous présente mon projet que je pense réalisable à partir d'une arduino.

Matériel en ma possession :
arduino UNO
écran LCD
quelques résistances et boutons

Je viens vers vous car je n'ai pas les connaissances pour réaliser ce montage, je n'ai pour l'instant malheureusement pas le temps (pas si malheureux !! ..... 3ème enfant) mais un jour viendra car j'ai pas mal d'applications arduino en vue.

Je souhaite réaliser un lecteur de tension de sonde lambda pour pouvoir régler correctement le mélange air/essence de ma vielle voiture.

Cela consiste à retranscrire une tension de 0v à 1V en d'autres valeurs et/ou clignotement de leds de couleur (vert, jaune et rouge ... yeah rastaman !!)

la précision devrait etre au millivolt

par exemple tension lue 900 à 945 mV = valeur 12.5 sur l'écran. cf tableau joint

Voltage sonde Facteur Lambda Air/Essence (Ratio) Observations

945mV <0.80 <12 Trop riche, perte de puissance
900-945 mV ~0.85 ~12.5 Pmax = lambda 0.86
855-900 mV ~0.90 ~13.2 Augmentation du rendement
810-855 mV ~0.93 13.8 Mélange correct
540-810 mV ~0.97 14.3 Mélange optimal
225-540 mV ~0.98 14.4 Bonne économie de carburant
180-225 mV ~1.0 14.7 Fonctionnement mixte
135-180 mV ~1.02 ~15 Réglage routier
90-135 mV ~1.04 ~15.3 Mélange moyen
45-90 mV 1.05-1.25 15.4-18 Mélange pauvre
<45 mV >1.25 >18 Trop pauvre, pas de combustion !

Les infos vous suffisent-elles ?

Merci pour votre aide si cela est possible.

elian67:
Bonjour les Arduiniens,

Je vous présente mon projet que je pense réalisable à partir d'une arduino.

Matériel en ma possession :
arduino UNO
écran LCD
quelques résistances et boutons

Je viens vers vous car je n'ai pas les connaissances pour réaliser ce montage, je n'ai pour l'instant malheureusement pas le temps (pas si malheureux !! ..... 3ème enfant) mais un jour viendra car j'ai pas mal d'applications arduino en vue.

Je souhaite réaliser un lecteur de tension de sonde lambda pour pouvoir régler correctement le mélange air/essence de ma vielle voiture.

Cela consiste à retranscrire une tension de 0v à 1V en d'autres valeurs et/ou clignotement de leds de couleur (vert, jaune et rouge ... yeah rastaman !!)

la précision devrait etre au millivolt

par exemple tension lue 900 à 945 mV = valeur 12.5 sur l'écran. cf tableau joint

Voltage sonde Facteur Lambda Air/Essence (Ratio) Observations

945mV <0.80 <12 Trop riche, perte de puissance
900-945 mV ~0.85 ~12.5 Pmax = lambda 0.86
855-900 mV ~0.90 ~13.2 Augmentation du rendement
810-855 mV ~0.93 13.8 Mélange correct
540-810 mV ~0.97 14.3 Mélange optimal
225-540 mV ~0.98 14.4 Bonne économie de carburant
180-225 mV ~1.0 14.7 Fonctionnement mixte
135-180 mV ~1.02 ~15 Réglage routier
90-135 mV ~1.04 ~15.3 Mélange moyen
45-90 mV 1.05-1.25 15.4-18 Mélange pauvre
<45 mV >1.25 >18 Trop pauvre, pas de combustion !

Les infos vous suffisent-elles ?

Merci pour votre aide si cela est possible.

Bonjour
l'acquisition de sonde lambda par arduino à été recemment discuté ici
mais ... il faut retrouver où ? :grin:

ceci etant sur un arduino "basique" l'ideal est d'utiliser la reference interne (1.1V sur une base 328P comme un uno/nano)
pour optimiser la mesure

Merci pour ton retour, je vais voir si je retrouve le post

elian67:
Merci pour ton retour, je vais voir si je retrouve le post

J'avais trouvé tout simplement en tapant lambda .... pkoi faire simple quand...

Merci

elian67:
J'avais trouvé tout simplement en tapant lambda .... pkoi faire simple quand...

Merci

attention son schema n'est pas bon

la sonde lambda doit simplement etre connecté entre GND et A0 (elle est vue comme un generateur de tension )

salut

bon j'ai avancé, j'ai repompé un programme de eskimon modifié avec analoreference internal

// Déclaration et remplissage du tableau...
// ...représentant les broches des LEDs
const int leds[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// le potentiomètre sera branché sur la broche analogique 0
const int potar = 0;
// variable stockant la tension mesurée
int tension = 0;

void setup()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {

    //tension de référence de 1.1V
    analogReference(INTERNAL);
    // déclaration de la broche en sortie
    pinMode(leds[i], OUTPUT);
    // mise à l'état haut
    digitalWrite(leds[i], HIGH);
  }
}


void loop()
{
  // on récupère la valeur de la tension du potentiomètre
  tension = analogRead(potar);
  // et on affiche sur les LEDs cette tension
  afficher(tension);
}


void afficher(int valeur)
{
  int i;
  for (i = 0; i < 10; i++)
  {
    if (valeur < (i * 100))
      digitalWrite(leds[i], HIGH); // on allume la LED
    else
      digitalWrite(leds[i], LOW); // ou on éteint la LED
  }
}

par contre vu que le tableau n'est pas linéaire comment dois-je m'y prendre ?

merci

Déjà :
avant de vouloir faire des "illuminations"
A tu déjà vérifié que ta sonde lambda renvoie de l'info brute "cohérente/exploitable"

Si j'ai fais une remarque "concernant" le schema
le code proposé lui me semblait correct (pas verifié)

elian67:
par contre vu que le tableau n'est pas linéaire comment dois-je m'y prendre ?

Tout d'abord je me commanderais quelque chose comme ca pour afficher et pour interfacer:

[chercher "TM1638 8-Bit LED 8-Bit Digital Tube" chez votre fournisseur préfére]

Ensuite je lirais l'entrée A0 une bonne dizaine de fois à 100mS d'intervalle et ferais la moyenne des mesures.

Je construirais 2 ou trois arrays avec les valeurs que tu nous as données.

-Tu fais une première boucle de i=0 à 10 en testant ta mesure contre les max dans l'array 1.
Aussitot que la mesure est supérieure, tu sors de la boucle et notes i.

-Ensuite tu cherche la valeur du facteur Lambda dans l'array 2 avec i.

-Ensuite tu cherche la valeur du ratio Air/Essence dans l'array 3 avec i.

-Pour finir tu mets tout ces résultats sur les displays et tu allumes la LED correspondante.

P.S. prends aussi le temps de faire un quatrième enfant pour payer ma retraite :wink:

Petite participation sur la référence interne :
Pour un exemplaire de micro donné sa valeur est stable, mais statistiquement elle fait 1,1V +/- 10 % --> c'est pas bon.

Solution extraite de la datasheet pour améliorer la précision des mesures : passer en mode ref interne et mesurer la tension sur la pin Aref -- > la ref interne est renvoyée sur Aref.
Une bonne idée est de stoker la valeur mesurée dans l'eeprom interne du micro.

Conséquence : si une tension est présente sur Aref et que l'on commute sur la référence interne --> boom plus de micro car la ref interne sert à fixer énormément de potentiels à l'intérieur du micro.
En usage ref int il ne faut strictement aucune connexion sur Aref.

68tjs:
Une bonne idée est de stoker la valeur mesurée dans l'eeprom interne du micro.

Une meilleure idée est de mettre exactment 1,000V sur l'entrée avec un potentionmètre et un bon voltmètre.

Par programme on stocke une fois la lecture de l' ADC correspondante en eeprom, par ex. lorsqu'on recoit "cal" par le port série.

Ensuite on fait un map() sur chaque mesure.

Petit retour et petit problème !

j'ai ce code !

// Déclaration et remplissage du tableau...
// ...représentant les broches des LEDs
const int leds[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// le potentiomètre sera branché sur la broche analogique 0
const int potar = 0;
// variable stockant la tension mesurée
int tension = 0;

void setup()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {

    //tension de référence de 1.1V
    analogReference(INTERNAL);
    // déclaration de la broche en sortie
    pinMode(leds[i], OUTPUT);
    // mise à l'état haut
    digitalWrite(leds[i], HIGH);
  }
}


void loop()
{
  // on récupère la valeur de la tension du potentiomètre
  tension = analogRead(potar);
  // et on affiche sur les LEDs cette tension
  afficher(tension);
}


void afficher(int valeur)
{
  int i;
  for (i = 0; i < 10; i++)
  {
   if ( (valeur>=0) && (valeur<=40) ) 
      digitalWrite(leds[0],LOW); // on allume la LED 1
   else
      digitalWrite(leds[0],HIGH);

    if ( (valeur>=40) && (valeur<=125) ) 
      digitalWrite(leds[1],LOW); // on allume la LED 2
   else
      digitalWrite(leds[1],HIGH);


      if ( (valeur>=125) && (valeur<=169) ) 
      digitalWrite(leds[2],LOW); // on allume la LED 3
   else
      digitalWrite(leds[2],HIGH);


      if ( (valeur>=169) && (valeur<=211) ) 
      digitalWrite(leds[3], LOW); // on allume la LED 4
    else
      digitalWrite(leds[3], HIGH); // ou on éteint la LED 4


        if ( (valeur>=211) && (valeur<=515) ) 
      digitalWrite(leds[4], LOW); // on allume la LED 5
    else
      digitalWrite(leds[4], HIGH); // ou on éteint la LED 5


       if ( (valeur>=515) && (valeur<=770) ) 
      digitalWrite(leds[5], LOW); // on allume la LED 6
    else
      digitalWrite(leds[5], HIGH); // ou on éteint la LED 6


      if ( (valeur>=770) && (valeur<=815) ) 
      digitalWrite(leds[6], LOW); // on allume la LED 7
    else
      digitalWrite(leds[6], HIGH); // ou on éteint la LED 7


      if ( (valeur>=815) && (valeur<=854) ) 
      digitalWrite(leds[7], LOW); // on allume la LED 8
    else
      digitalWrite(leds[7], HIGH); // ou on éteint la LED 8


      if ( (valeur>=854) && (valeur<=897) ) 
      digitalWrite(leds[8], LOW); // on allume la LED 9
    else
      digitalWrite(leds[8], HIGH); // ou on éteint la LED 9


      if ( (valeur>=897) && (valeur<=1000) ) 
      digitalWrite(leds[9], LOW); // on allume la LED 10
    else
      digitalWrite(leds[9], HIGH); // ou on éteint la LED 10


  
}}

je l'ai appliqué au compte tour de ma voiture et cela a l'air de fonctionner correctement.

par contre quand je l'utilise sur la sonde lambda j'ai un scintillement de plusieurs leds. Ces leds se "déplacent" dans le "bon sens" mais il y a un manque de "précision" de fourchette de tension.
j'ai pourtant programmé chaque led pour une fourchette de tension mais plusieurs sont allumées ...

faudrait il placé un filtre quelque part ? Programmer autrement ?

merci

Je tiens à m'excuser car je n'avais pas vu votre participation à mon post ..... bordel pourquoi je ne reçois pas de notifs ......

Bref je vais essayer de comprendre ce que vous m'avez conseiller et je reviendrais vers vous !!!

Pour le moment j'ai ceci

Tu voudrais pas mettre un titre en rapport avec la sonde Lambda ?

Du genre "Lecture de la tension d'une sonde Lambda et affichage".

Voilà ou j'en suis pour la lecture de la sonde lambda

pour plus de "stabilité" des leds j'ai mis un délais pour les sorties.

Je ne pense pas que ce soit la meilleure (fiable) solution.

Comme suggérer plus haut il faudrait effectivement faire un échantillonnage de tensions sur quelques ms.

j'ai trouvé pas mal de choses mais je nage un peu pour programmer ce "tableau" et l'appliquer, quelqu'un aurait l'envie de me corriger et me compléter mon code, ou au moins me donner les bases ?

merci

// Déclaration et remplissage du tableau...
// ...représentant les broches des LEDs
const int leds[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// le potentiomètre sera branché sur la broche analogique 0
const int potar = 0;
// variable stockant la tension mesurée
int tension = 0;

void setup()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {

    //tension de référence de 1.1V
    analogReference(INTERNAL);
    // déclaration de la broche en sortie
    pinMode(leds[i], OUTPUT);
    delay(50);

    // mise à l'état haut
    digitalWrite(leds[i], HIGH);
    delay(50);
  }
}


void loop()
{
  // on récupère la valeur de la tension du potentiomètre
  tension = analogRead(potar);
  delay(100);

  // et on affiche sur les LEDs cette tension
  afficher(tension);
}


void afficher(int valeur)
{
  int i;
  for (i = 0; i < 10; i++)
  {
   if ( (valeur>=0) && (valeur<=40) ) 
      digitalWrite(leds[0],LOW); // on allume la LED 1
   else
      digitalWrite(leds[0],HIGH); // on éteind la LED 1

    if ( (valeur>=40) && (valeur<=125) ) 
      digitalWrite(leds[1],LOW); // on allume la LED 2
   else
      digitalWrite(leds[1],HIGH); // on éteint la LED 2


      if ( (valeur>=125) && (valeur<=169) ) 
      digitalWrite(leds[2],LOW); // on allume la LED 3
   else
      digitalWrite(leds[2],HIGH); // on éteint la LED 3


      if ( (valeur>=169) && (valeur<=211) ) 
      digitalWrite(leds[3], LOW); // on allume la LED 4
    else
      digitalWrite(leds[3], HIGH); // ou on éteint la LED 4


        if ( (valeur>=211) && (valeur<=515) ) 
      digitalWrite(leds[4], LOW); // on allume la LED 5
    else
      digitalWrite(leds[4], HIGH); // ou on éteint la LED 5


       if ( (valeur>=515) && (valeur<=770) ) 
      digitalWrite(leds[5], LOW); // on allume la LED 6
    else
      digitalWrite(leds[5], HIGH); // ou on éteint la LED 6


      if ( (valeur>=770) && (valeur<=815) ) 
      digitalWrite(leds[6], LOW); // on allume la LED 7
    else
      digitalWrite(leds[6], HIGH); // ou on éteint la LED 7


      if ( (valeur>=815) && (valeur<=854) ) 
      digitalWrite(leds[7], LOW); // on allume la LED 8
    else
      digitalWrite(leds[7], HIGH); // ou on éteint la LED 8


      if ( (valeur>=854) && (valeur<=897) ) 
      digitalWrite(leds[8], LOW); // on allume la LED 9
    else
      digitalWrite(leds[8], HIGH); // ou on éteint la LED 9


      if ( (valeur>=897) && (valeur<=1000) ) 
      digitalWrite(leds[9], LOW); // on allume la LED 10
    else
      digitalWrite(leds[9], HIGH); // ou on éteint la LED 10


  
}}

elian67:
Voilà ou j'en suis pour la lecture de la sonde lambda

pour plus de "stabilité" des leds j'ai mis un délais pour les sorties.

Je ne pense pas que ce soit la meilleure (fiable) solution.

Comme suggérer plus haut il faudrait effectivement faire un échantillonnage de tensions sur quelques ms.

Bonsoir
le temps de boucle est faible , le moindre bruit récupéré en sortie de lambda va etre interprété comme une valeur "exploitable"

l'ideal serait de regarder à l'oscillo , la "tronche" du signal de sortie , il doit y avoir des pics importants en V , rendu par l'AD à 1023.

Ne pas oublier que la ref de l'AD etant là de 1.1V (théorique) , le moindre pic V > à AREF sur l'entrée ana (mais de V < à 5.5V ) indiquera une saturation.

à defaut d'oscillo , déjà pour test faire un log de verif des acquisitions brutes A0

je pense que tu devrais statistiquement avoir ponctuellement enormement plus de "1023"que de valeur intermediaires

elian67:
Comme suggérer plus haut il faudrait effectivement faire un échantillonnage de tensions sur quelques ms.

j'ai trouvé pas mal de choses mais je nage un peu pour programmer ce "tableau" et l'appliquer, quelqu'un aurait l'envie de me corriger et me compléter mon code, ou au moins me donner les bases ?

C'est pas dur. Tu remplaces

void loop()
{
  // on récupère la valeur de la tension du potentiomètre
  tension = analogRead(potar);
  delay(100);

  // et on affiche sur les LEDs cette tension
  afficher(tension);
}

par

void loop()
{
  // on récupère la valeur de la tension du potentiomètre

tension = 0;
for (int i=0; i<=9; i++)
{
  tension += analogRead(potar); // on additionne 10 fois la mesure...
  delay(10);
}
tension = tension/10; // et on divise par 10

  // et on affiche sur les LEDs cette tension
  afficher(tension);
}

elian67:
j'ai trouvé pas mal de choses mais je nage un peu pour programmer ce "tableau" et l'appliquer, quelqu'un aurait l'envie de me corriger et me compléter mon code, ou au moins me donner les bases ?

//...

void afficher(int valeur)
{
  int i;
  for (i = 0; i < 10; i++)
  {
  if ( (valeur>=0) && (valeur<=40) )
      digitalWrite(leds[0],LOW); // on allume la LED 1
  else
      digitalWrite(leds[0],HIGH); // on éteind la LED 1

//...

Pourquoi fais tu 11 fois la même chose?

en plus

if ( (valeur>=0) && (valeur<=40) ) 
      digitalWrite(leds[0],LOW); // on allume la LED 1
   else
      digitalWrite(leds[0],HIGH); // on éteind la LED 1

s'écrit plus simplement

      digitalWrite(leds[0],!(valeur>=0) && (valeur<=40));

RIN67630:
Pourquoi fais tu 11 fois la même chose?

en plus

if ( (valeur>=0) && (valeur<=40) ) 

digitalWrite(leds[0],LOW); // on allume la LED 1
  else
      digitalWrite(leds[0],HIGH); // on éteind la LED 1



s'écrit plus simplement


digitalWrite(leds[0],!(valeur>=0) && (valeur<=40));

ok merci pour le raccourci !!