Arduino Mkr 1200 - Mesure d'un voltage externe

Bonjour,

Pour mon projet de balise connecté au réseau Sigfox, j'ai besoin de mesurer une tension externe (Une batterie Lipo 4.2V) qui est connectée à un chargeur solaire.

Voici mon code :

uint8_t battery;
float voltage;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
 battery_mesure();

  Serial.print(voltage);
  Serial.println(" V");
 
  Serial.print(battery);
  Serial.println(" %");
 
 delay(600);
}

void battery_mesure () {
  // read the input on analog pin A1:
  int sensorValue = analogRead(A1);
  Serial.println(sensorValue);
  
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 3.22V):
 voltage = sensorValue * (3.22/1024)*((4700.00 + 15000.00)/15000.00);

      if (voltage >= 4.35){battery=110;}
      else if (voltage >= 4.20) {battery = 100;}
      else if (voltage >= 4.15) {battery = 95;} 
      else if (voltage >= 4.11) {battery = 90;}
      else if (voltage >= 4.08) {battery = 85;}   
      else if (voltage >= 4.02) {battery = 80;}
      else if (voltage >= 4.20) {battery = 75;}
      else if (voltage >= 3.98) {battery = 70;} 
      else if (voltage >= 3.95) {battery = 65;}
      else if (voltage >= 3.91) {battery = 60;}   
      else if (voltage >= 3.87) {battery = 55;}
      else if (voltage >= 3.85) {battery = 50;}
      else if (voltage >= 3.84) {battery = 45;} 
      else if (voltage >= 3.82) {battery = 40;}
      else if (voltage >= 3.80) {battery = 35;}   
      else if (voltage >= 3.79) {battery = 30;}  
      else if (voltage >= 3.77) {battery = 25;}
      else if (voltage >= 3.73) {battery = 20;} 
      else if (voltage >= 3.71) {battery = 15;}
      else if (voltage >= 3.69) {battery = 10;}   
      else if (voltage >= 3.61) {battery = 5;} 
      else  {battery = 0;} 
      
    
  
}

Ce code marche très bien comme ça. Par contre dès que je l'intégre dans mon code global (Avec les mesure de vent, de température, avec des période de Lowpower,...), les valeurs que je reçois via Sigfox deviennent très variables.

Es-ce que vous voyez une erreur déjà sur cette partie ?
Est-ce que c'est quand je coupe l'alim USB 5v et que je passe en mode batterie (Via un régulateur) ?

Bref, un coup de main serais vraiment apprécié !

Une erreur ici

else if (voltage >= 4.20) {battery = 75;}

Je ne connais pas trop cette famille de carte mais à la lecture de la doc, il me semble que par défaut c'est l'alimentation du processeur qui est utilisée comme référence pour le DAC. Comme lorsque tu fonctionnes sur piles la tension est différente du 3,3V que tu as avec l'USB et qu'elle peut fluctuer dans le temps les mesures ne sont pas fiables. Il faudrait peut-être utiliser une référence interne.
Tu peux le vérifier en alimentant la carte avec une powerbank sur son port USB.
La manip la plus probante serait d'alimenter la carte avec 2 piles. De faire une mesure sur un pile de 1,5V par exemple en envoyant le résultat sur la console. Puis de brancher/débrancher un 5V sur l'entrée USB. Si la mesure change alors c'est un problème lié au Vref de l'ADC et il faudrait passer sur ref interne.
La mesure devrait en principe changer du rapport 3V/3,3V. Lorsque la carte sera alimentée par l'USB, la tension de référence sera de 3,3V. Lorsque la carte sera alimentée par les piles, la tenson de référence devrait être de l'ordre de 3V (suivant l'état des piles bien sûr).

Bon j'ai modifié le code pour travailler avec la tension de référence à 1 volt. J'ai aussi du coup du changer le pont diviseur pour abaisser ma tension max de 4.2v à 1v.

Maintenant pour tester ça c'est pas tout simple car si je veux pouvoir tester la carte sur batterie (Ou piles), je n'ai plus la possibilité d'avoir accès au sérial moniteur car je dois débranché l'Usb.

Donc faut que je programme un envoi via Sigfox des données de la batterie pour voir comment cela se comporte...

J'ai juste ?

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}


void loop() {

  analogReadResolution(10);
  analogReference(AR_INTERNAL1V0); //AR_DEFAULT: the default analog reference of 3.3V // AR_INTERNAL1V0: a built-in 1.0V reference
 
  // read the input on analog pin 1:
  int sensorValue = analogRead(3);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 4.3V):
  float voltage = sensorValue * (3.3/1024) * ((3300.00 + 1000.00) / 3300.00);
  // print out the value you read:
  Serial.println(sensorValue);
  Serial.print(voltage);
  Serial.println("V");
  delay(800);

}

Si tu as un cable FTDI (ou équivalent) tu peux utiliser la liaison série hardware sur les broches 13/14 et utiliser Serial1. Comme ça tu auras une liaison série quelque soit la configuration d'alimentation.

Ces lignes devraient être dans le setup() c'est inutile de les répéter à chaque itération de loop()

  analogReadResolution(10);
  analogReference(AR_INTERNAL1V0); //AR_DEFAULT: the default analog reference of 3.3V // AR_INTERNAL1V0: a built-in 1.0V reference

Dans cette formule

  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 4.3V):
  float voltage = sensorValue * (3.3/1024) * ((3300.00 + 1000.00) / 3300.00);

Il faudrait remplacer le 3.3 par un 1 puisque la référence a changé.