Ciao a tutti.
Non ho trovato niente di simile girando nei forum per quanto riguarda una lettura precisa dell'alimentazione in uso, o meglio ci si basa sulla lettura dei 1,1 volt ma il tutto è legato alla fine alla variabile RESULT legata a una divisione del numero numero definirei MAGIC NUMBER che varia sia a secondo dei vari Arduino utilizzati (anche se sono tutti Uno o Nano) sia a seconda dell'alimentazione se USB o esterna e questo rende impossibile ottenere dei risultati decenti ad esempio nella misurazione di resistenze/volt in cui molto spesso viene usata una variabile Vin generica di 5.00 volt e ovviamente il risultato dell'operazione risulta errato, soprattutto se si usa l'alimentazione USB e di meno se si usa un'alimentazione esterna, perchè è più facile che con alimentazione esterna il risultato sia effettivamente 5 Volt.
Ci sono poi in giro delle dritte su come calcolare questo MAGIC NUMBER ma ne ho seguite un paio e mi davano risultati completamente errati.
Quello che ho fatto io è di mettere all'avvio di Arduino una routine che, dopo aver atteso un paio di secondi per attendere che l'alimentazione si stabilizzi, fà 16 campionamenti simili alla routine ReadVcc() e, a seconda del RESULT stabilisce se l'alimentazione arriva da USB o esternamente e poi, moltiplica questo RESULT con 2 variabili precedentemente misurate col tester tra ground e Aref ad esempio, per ottenere il nostro numero magico che viene memorizzato nella variabile globale MoltiplicatoreVin ed utilizzato nelle successive chiamate a ReadVCC.
Quello che dovete fare dunque è misurare col tester i valori restituiti da Aref sia che sia alimentato tramite USB oppure da alimentazione esterna e inserirlo nelle 2 variabili TesterUsb e TesterBatt.
Come potete vedere dai risultati nel monitor seriale, questi 2 numeri sono molto differenti tra loro, per cui metterne uno solo (come si vede nelle routines che girano nei forum) và a falsare i risultati a seconda se vi state alimentando da USB o da una batteria esterna.
Spero vi sia utile...ciaoooo
// inserite in queste 2 variabili i valori misurati col tester
//******************************************************************************************
float TesterUsb = 4560, TesterBatt = 5000; // MISURATI CON TESTER TRA GROUND E AREF o VCC
//******************************************************************************************
long MoltiplicatoreVin = 0;
void setup() {
analogReference(DEFAULT);
Serial.begin(115200);
while (!Serial)
;
LeggoMoltiplicatore();
}
void loop() {
float Vin = readVcc() / 1000.00;//valore in volt
Serial.print("Vin = ");
Serial.println(Vin,3);
delay(1000);
}
long readVcc() {
//long result; // Read 1.1V reference against AVcc
// 4,562 V da USB e 5,000 V da batteria
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // for arduino 328-168
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC))
; // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
result = MoltiplicatoreVin / result;
return result;
}
void LeggoMoltiplicatore() {
delay(2000); // lasciare che il sistema si stabilizzi altrimenti la lettura non è corretta
long result = 0;
for (int r = 1; r <= 16; r++) {
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // for arduino 328-168
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC))
; // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
result += (high << 8) | low;
}
Serial.println("----------");
result = (int)result / 16;
// il valore 230 è una via di mezzo tra il risultato tramite USB o batteria
if (result > 230) { //244 alimentazione USB nel mio arduino
MoltiplicatoreVin = result * TesterUsb;
Serial.println("alimentazione USB");
Serial.print("result = ");
Serial.println(result);
} else { // 223 alimentazione a batteria nel mio arduino ma potrebbe variare nel vostro
MoltiplicatoreVin = result * TesterBatt;
Serial.println("alimentazione Batteria");
Serial.print("result = ");
Serial.println(result);
}
Serial.print("Moltiplicatore = ");
Serial.println(MoltiplicatoreVin);
}
Se invece avete misurato i valori tra GND e AREF potete usare questa routine che identifica se l'alimentazione è a batteria oppure tramite USB.
E risparmiate i 2 secondi iniziali di attesa.
Cmq và bene se non sostituite arduino, altrimenti la prima volta vanno usate le 2 routines complete
long readVcc() {
//long result; // Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // for arduino 328-168
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC))
; // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
// il valore 230 è una via di mezzo tra il risultato tramite USB o batteria
if (result > 230) { //244 alimentazione USB
result=4560;// valore letto col tester tra GND e AREF
} else { // 223 alimentazione a batteria
result=5000;// valore letto col tester tra GND e AREF
}
return result;
}