Probleme sur le port analogique( pas sûre)!

Bonjour ,je vous contactent au sujet d’un problème .
J’essaye de faire un chargeur nomade avec une batterie akku nimh (7.2v) , un convertisseur 5v et un
pont diviseur de tension branche sur l’arduino pour savoir qu’en est décharge l’akku .Mais mon problème
est que les valeurs du pont diviseur de tension reçu sont 1 fois sur deux mauvaise ,je ne comprends pas pourquoi .(Je veux quand le dire les tensions dans le pont son exacte teste avec un voltmètre)

int vout=A0;
int ledvert=6;
int ledrouge=5;
int mos=2;
boolean etatled=0;
long temps;
float tension;
float tensionVin=9;
void setup(){
  pinMode(vout,INPUT);
  pinMode(ledvert,OUTPUT);
  pinMode(ledrouge,OUTPUT);
  pinMode(mos,OUTPUT);
Serial.begin(9600);
temps=0;
}
void loop(){
 tension=5.0*(analogRead(vout)/1024.0);
  tensionVin=(tension*(147.0+100.0))/100.0;
    Serial.println(tensionVin);
  
  if(tensionVin>=7.4&&tensionVin<=7.59){
    digitalWrite(ledrouge,HIGH);
    digitalWrite(ledvert,LOW);
  }
  if(tensionVin>=7.60&&tensionVin<=7.79){
    digitalWrite(ledrouge,HIGH);
    digitalWrite(ledvert,HIGH);
  
  }
  if(tensionVin>=7.8&&tensionVin<=9.49){
    digitalWrite(ledrouge,LOW);
    digitalWrite(ledvert,HIGH);
 
  }
  if(tensionVin>=7.2&&tensionVin<=7.39){
    if(millis()-temps>=500){
      temps=millis();
      etatled=!etatled;
      digitalWrite(ledrouge,etatled);
    }
  digitalWrite(ledvert,LOW);
  }
  if(tensionVin>=7.22){
    digitalWrite(mos,HIGH);
  }
  else{
    digitalWrite(mos,LOW);
  }
}
pinMode(vout,INPUT);

Est inutile.
Cet ordre concerne uniquement le port digital.
La patte appelée A0 par arduino est reliée en permanence a un port digital (C pour l'atmega328p de la UNO) et au multiplexeur analogique.
Par défaut à la mise sous tension c'est le port digital qui est activé, le multiplexeur et le convertisseur analogique digital sont désactivés.
C'est la fonction analogRead(X) qui active ces composantes analogiques du micro.
Il y a même de forte probabilité que la fonction analogRead désactive le pinMode(A0, INPUT) (a vérifier dans le code source de la fonction analogRead ).

En ce qui concerne l'instabilité constatée:

  1. Ce n'est probablement pas la cause (mais encore faut-il le vérifier) as tu essayé un simple analogRead(A0) ?

  2. Tu utilises deux fonctions "câblées" du micro-contrôleur : zone de la puce qui sont de l'électronique pure et qui communiquent avec la zone programme uniquement par des registres :

  • le multiplexeur analogique et le convertisseur analogique/digital.
  • L'UART pour dialoguer avec le PC
    Une fois activée ces deux zones d'électronique pure vivent leur vie indépendamment du programme.
    Une peut être particulièrement lente c'est la liaison série (UART), l'autre (mesure analogique) est bloquante et ne devrait pas poser de soucis.

Dans un premier temps je passerai à la vitesse maximale pour Serial.begin (L'IDE arduino.cc accepte une vitesse supérieure à celle d'arduino.org).
Depuis que je me suis fait avoir j'utilise toujours la vitesse max. C'est avec l'analyseur logique que j'ai compris d'où venait les indications farfelues : je lançais un nouveau Serial.print alors que le précédent n'était pas encore terminé d'où des collisions.
Analyseur logique clone de Saleae 6€ sur ebay --> à user et abuser sans modération.

Si cela ne va pas mieux mets des delay.
On dit qu'il faut éviter d'utiliser des delay dans un programme et c'est vrai.
Mais pendant la phase de mise au point c'est comme avec l'analyseur logique il ne faut pas hésiter à les utiliser pour comprendre ce qu'il se passe. C'est surtout vrai quand on gère du matériel qui ne répond pas instantanément, en tout cas beaucoup plus lentement que le programme.

Votre code est correct d’un point de vue lecture de la tension.

votre code présente un soucis au niveau des if.

vous utilisez des float, dont la précision n’est pas terrible mais à plus de 2 chiffres après la virgule et vous faites

  // led rouge ou vertes mais pas de else... pas top...
  if (tensionVin >= 7.4 && tensionVin <= 7.59){}
  if (tensionVin >= 7.60 && tensionVin <= 7.79){}
  if (tensionVin >= 7.8 && tensionVin <= 9.49){}
  if (tensionVin >= 7.2 && tensionVin <= 7.39){}

  // puis pour mos
  if (tensionVin >= 7.22){} else {}

le pb peut survenir si votre tension oscille autour the 7.59 et 7.60 par exemple. imaginez que vous ayez 7.595 (vous ne le voyez pas parce que votre print arrondit par défaut les float à 2 chiffres à l’affichage) alors ce n’est capturé dans aucun des IF et vous vous retrouvez au niveau du if/else final.

il faut donc des bornes sans espace dans les if, et sans doute des else tout le long:
essayez avec

  if (tensionVin >= 7.4 && tensionVin < 7.6){} else
  if (tensionVin >= 7.60 && tensionVin < 7.8){} else
  if (tensionVin >= 7.8 && tensionVin < 9.5){} else
  if (tensionVin >= 7.2 && tensionVin < 7.4){}

  if (tensionVin >= 7.22){} else {}

personnellement j’enlèverai tous les maths et je calculerai les formules inverses pour tester uniquement sur des entiers entre 0 et 1023. par exemple pour tensionVin = 7.40 ça veut dire que

(tension * (147.0 + 100.0)) / 100.0 = 7.40
tension * (147.0 + 100.0) = 740
tension = 740/ 247

comme tension c’est 5.0 * (analogRead(vout) / 1024.0)

5.0 * (analogRead(vout) / 1024.0) = 740/ 247

soit analogRead(vout) = (740 * 1024) / (5 * 247) = ~613

donc au lieu de comparer tensionVin >= 7.4 je comparerai directement analogRead(vout) (mis dans une variable pour ne pas le lire plein de fois) à 613. vos maths ne vont pas vous donner une meilleure précision que les 1024 valeurs possibles de l’ADC donc autant se ramener à cela. le code ira bcp plus vite.