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%
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);
}
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);
}
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.
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.
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