Atmega/Arduino – odczyt AVC

Jak odczytać własny poziom napięcia przez atmegę? w cale nie tak łatwo. Posiadam Atmegę32 z bootloaderem Arduino (liby są dostępne tutaj dla chcących dokonać takiej modyfikacji – wystarczy zwykły programator np. USBasp, aplikacja Arduino GUI) chciałbym aby mikroprocesor sam zmierzył napięcie jakie jest mu dostarczane – dotyczy to w większości projektów z zasilaniem bateryjnym, solarnym i każdym innym budzącym wątpliwości (bądź nie?). W pierwszej kolejności polecam bezwzględnie ujarzmić atmegę i jej napięcia – ja to zrobić dowiemy się tutaj, szczególnie zalecam zastosować się do wersji 2 tzw. “Podłączanie zalecane”.  Po co nam pomiar napięcia? a no po że gdy zachcemy np wykorzystać przetwornik analogowo-cyfrowy do mierzenia np. przepływu prądu to niezbędnym będzie nam mieć właściwe napięcie odniesienia, które domyślnie wynosi 5.0v. A więc, gdy dostarczamy prądu np. 5.1v i przetwarzamy to przez 5.0 – to otrzymamy błędne wyniki. Takie coś przyda nam się gdy zechcemy zasilać atmegę solarnie z zapasem akumulatorów z opcją rejestrowania przepływu prądu i stanu napięć (więcej o tym w przyszłych artykułach).  Poniższy kod służy jako gotowiec, wystarczy go wkleić, wgrać, a do pinu PA1 podłączyć + z szyny zasilającej samą atmegę. Strojenie: polecam spojrzeć na parametr 1238816L –  w idealnych warunkach powinien wynosić 123500L, niestety, z winy low-endu, komponentów lub innych niepożądanych czynników należy dobrać go tak by wskazywał poprawne wartości (w porównaniu z jakimś niezależnym miernikiem).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//pin napięcia - PA1 (ADC1), drugi pin od góry z prawej
void setup(void)
{
Serial.begin(4800);
delay(2000);
}
 
void loop(void)
{
Serial.print("Input Voltage =  ");
float AvrVcc = readVcc();
Serial.println(AvrVcc);  //mV
}
 
long readVcc() {
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(10);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA,ADSC));
uint8_t low  = ADCL;
uint8_t high = ADCH;
long result = (long)(high<<8) | low;
result = 1238816L / result; // Calculate Vcc (in mV); 1125300~ = 1.1*1023*1000
return result;
}
//pin napięcia - PA1 (ADC1), drugi pin od góry z prawej
void setup(void)
{
Serial.begin(4800);
delay(2000);
}

void loop(void)
{
Serial.print("Input Voltage =  ");
float AvrVcc = readVcc();
Serial.println(AvrVcc);  //mV
}

long readVcc() {
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(10);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA,ADSC));
uint8_t low  = ADCL;
uint8_t high = ADCH;
long result = (long)(high<<8) | low;
result = 1238816L / result; // Calculate Vcc (in mV); 1125300~ = 1.1*1023*1000
return result;
}

 

Ten wpis został opublikowany w kategorii Code, Ideas i oznaczony tagami . Dodaj zakładkę do bezpośredniego odnośnika.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Rozwiąż zagadkę aby kontynuować * Time limit is exhausted. Please reload CAPTCHA.