Tension de référence Pro mini [Résolu]

Bonjour,
J'utilise un pro mini alimenté sur son entrée VCC, régulateur enlevé.
La référence Aref ne sort pas sur une broche et est à VCC.

Sans référence interne de tension fixe, comment faire simplement pour obtenir une mesure relativement fiable sur les entrées analogiques ?

Le microcontrôleur est un ATMEGA328P. Il dispose de la référence interne 1.1V comme les autres, UNO ou NANO, activable par analogReference().
La broche AREF est absente, mais cela n'empêche pas de comparer la valeur mesurée sur une entrée analogique avec celle lue par un multimètre, et d'ajuster la valeur d'une constante :

#define VREF                  1.099       // à ajuster
#define DIVIDER             0.248      // pont diviseur éventuel
  analogReference(INTERNAL);
  unsigned int adc = analogRead(0);
  float voltage = adc * VREF / 1023 / DIVIDER;

La référence interne a une précision de 10%. La constante VREF doit donc être ajustée.
L'autre solution est d'adopter une référence externe, TL431 par exemple (mais il y a mieux).
TL431 : 1% de précision
LM4040 : 0.1%

10 % me suffisent
J'ai mis ça hors fonction loop() et setup() et ça indique l'erreur :

210702MAJ:51:18: error: 
expected constructor, destructor, or type conversion before '(' token

   analogReference(INTERNAL);

C'est à déclarer comment ?

Les constantes avant setup()
analogReference(INTERNAL); dans setup()
Le reste dans loop() ou une fonction.

Je n'ai pas besoin de valeur convertie.
J'ai fait ce test et ça fonctionne comme je le souhaitais, ne reste plus qu'à modifier les ponts diviseurs.

/*
 * test mesure entrée avec tension d'alimentation variable
 * seuil réglé avec un potentiomètre ou la led commence à s'allumer
 * alim         normal      reference interne
 * 4.75 V       3.69          0.83
 * 5.3 V        4.13          0.83
 */

int sensorPin = A0;    // select the input pin for the potentiometer
int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
   analogReference(INTERNAL); // d'abord désactivé
  pinMode(ledPin, OUTPUT);
}

void loop() {
  sensorValue = analogRead(sensorPin);
  if (sensorValue > 800) digitalWrite(ledPin, HIGH);
  else digitalWrite(ledPin, LOW);
}

Merci Henry, j'en apprends encore tous les jours :wink:

Je t'en prie.

J'y revient parce que j'avais un manque de précision avec pont diviseur de forte valeur en ohm, utilisé pour limiter la consommation en mode économiseur.

La solution était d'utiliser une entrée configurée en sortie le temps de prendre la mesure.

  //////test pont diviseur alimenté momentanément par pin output côté - /////

  résistance 2.2 k entre A1 et 11
  résistance 10 k entre A1 et +alim
  coeff 12.2/2.2 = 5.54
  5.3 V 917  calcul : 917 x 0.00105 x 5.54 = 5.33 V
  4.75 V 823
  conso en veille 6.5 µA à 5.3 V
  Durée de réveil : moins de 1 mS
*/

#include <LowPower.h>
//#define Debug  // mode test et moniteur série

int sensorPin = A1;
int cdPin = 11;
int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
  analogReference(INTERNAL);
  pinMode(ledPin, OUTPUT);
  pinMode(cdPin, INPUT);
#ifdef Debug
  Serial.begin(115200);
  Serial.println ("Moniteur série validé") ;
  delay(10) ;
#endif // Debug
}

void loop() {
  pinMode(cdPin, OUTPUT);
  sensorValue = analogRead(sensorPin);
#ifdef Debug
  Serial.print ("sensorValue = ") ;
  Serial.println (sensorValue) ;
  delay(10);
#endif // Debug
  pinMode(cdPin, INPUT);
// retour en veille 
  LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
}

Pour ma part j'utilise couramment 1MΩ + 330KΩ sans problème.

Avec cette référence de 1.1 V au lieu de 5, le résultat de la mesure variait de plus ou moins 3 point sur le moniteur série sans rien changer.
Avec 10 k / 2.2 k, la précision est revenue, mais 430 µA pour alimenter le pont.

L'astuce efface cette conso durant la veille.

En fait, tu as raison :clap:

En changeant l'attribution d'une pin d'output en input semble créer des aléas de fonctionnement. J'ai toujours des ratés au réveil avec un programme un peu plus compliqué que l'exemple.

Pour mesurer l'état de la batterie, la référence est indispensable.

Après faut réadapter les valeurs du pont pour mettre en évidence ce qui nous intéresse pour ne pas perdre de sensibilité par rapport à la division par 5 de la tension de référence.
Dans mon cas, il s'agit de seuils, plus facile à mettre en évidence avec l'allumage d'une led qu'avec le moniteur série.

3 points ce n'est pas grand chose (3mV).
Éventuellement, pour de la détection par seuils, utiliser un hystérésis.

Le danger avec l'allumage d'une LED, est de voir tomber la batterie en décharge profonde.
Il est possible d'ajouter un bouton de test de la batterie et de faire flasher une LED tricolore, vert, orange, rouge.

1 Like

Bonjour,
C'était le servo moteur à pas cher qui avait des aléas de fonctionnement.
L'effacement de la consommation du pont fonctionne très bien

  pinMode(pinPont, INPUT);// coupe le pont batterie
#ifdef Debug
  LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); // en mode test
#else
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // mise en veille
#endif
  pinMode(pinPont, OUTPUT);// active le pont batterie