Hi,
Sollte mir folgender Code nicht bei einer Spannung kleiner 3.3V an Pin
PB4 die LED blinken lassen? Leider blinkt die LED unabhängig von der
anliegenden Spannung an PB4.
Sieht jemand meinen Fehler?
1
#include<Arduino.h>
2
3
#define BAT_EMPTY_PIN PB2
4
5
intgetBattV()
6
{
7
DDRB&=~_BV(PB4);// PB4 as input
8
PORTB&=~_BV(PB4);// no pullup on PB4
9
10
ADMUX=_BV(MUX1)|_BV(REFS1);//ADC2/PB4 and 1.1V as ref
11
12
delay(5);// wait for Vref to settle
13
14
ADCSRA|=_BV(ADSC);// reading ADC
15
while(bit_is_set(ADCSRA,ADSC));//ADSC will be set to 0 wen conversion is finished
16
17
uint8_tlow=ADCL;
18
unsignedintadcVal=(ADCH<<8)|low;
19
20
// discard previous result ("The first ADC conversion result after switching voltage reference source maybe inaccurate, and the user is advised to discard this result.")
Sebastian W. schrieb:> Erstens liefert bei AREF 1.1V jeder Messwert >1.1V als ADC-Ergebnis> 1023.
Ist das so? Ist mir so aus dem Datenblatt nicht klar geworden, wo steht
das?
Dann müsste ja das funktionieren? Geht aber leider auch nciht
1
ADMUX=_BV(MUX1);//ADC2/PB4 and Vdd als Ref(4,8V)
2
..
3
..
4
return((long)1024*4800)/adcVal;
Georg M. schrieb:> Sebastian W. schrieb:>> Zweitens ist diese Zeile komisch>> Offensichtlich unüberlegt abgeschrieben: so wird die Spannung am VDD-Pin> gemessen.
1
return((long)1024*1100)/adcVal;
Sicher nicht unüberlegt.
Ich dachte die Zeile setzt das Ergebnis vom ADC ins Verhältnis zur
Referenzspannung.(1,1V ->1100)
1
ADMUX=_BV(MUX3)|_BV(MUX2);
Gibt mir tatsächlich die Spannung am VDD.
Warum sollte dann
1
ADMUX=_BV(MUX1)
,was laut Datenblatt den Input für den ACD auf ADC2 setzt, nicht
funktionieren?
Die VDD-Spannung ist höher als VREF, deswegen ist die Gleichung
umgestellt.
Deswegen je kleiner der ADC-Wert ist, desto größer ist die gemessene
Versorgungsspannung.
Z.B. Max schrieb:> return ((long)1024 * 1100) / adcVal;>> Sicher nicht unüberlegt.> Ich dachte die Zeile setzt das Ergebnis vom ADC ins Verhältnis zur> Referenzspannung.(1,1V ->1100)
Das Ergebnis wird aber größer wenn der Messwert kleiner wird ...
LG, Sebastian
Z.B. Max schrieb:> ADMUX = _BV(MUX3) | _BV(MUX2);>> Gibt mir tatsächlich die Spannung am VDD.> Warum sollte dann>> ADMUX = _BV(MUX1)>> ,was laut Datenblatt den Input für den ACD auf ADC2 setzt, nicht> funktionieren?
Ok. Wenn MUX auf 0b1100 gestellt wird, und REFS auf 0b000, dann passiert
folgendes: Der ADC misst seine interne (stabile) Bandgap-Spannung im
Verhältnis zu VCC. Wenn also VCC 4.4V ist, dann wird die 1.1V
Bandgap-Spannung als 256 gemessen. Wenn VCC 3.3V ist, dann misst man
341. Dann stimmt deine Rechenmethode, um VCC auszurechnen.
Aber wenn du eine veränderliche Spannung an einem der ADC-Eingangspins
messen willst, brauchst du a) eine stabile Referenzspannung, b) darf die
Eingangsspannung nicht größer als die Referenzspannung werden (sonst
kommt als Messwert immer 1023 raus), und c) musst du deine
Berechnungsformel umstellen.
HTH.
LG, Sebastian
Sebastian W. schrieb:> Z.B. Max schrieb:>> ADMUX = _BV(MUX3) | _BV(MUX2);>>>> Gibt mir tatsächlich die Spannung am VDD.>> Warum sollte dann>>>> ADMUX = _BV(MUX1)>>>> ,was laut Datenblatt den Input für den ACD auf ADC2 setzt, nicht>> funktionieren?>> Ok. Wenn MUX auf 0b1100 gestellt wird, und REFS auf 0b000, dann passiert> folgendes: Der ADC misst seine interne (stabile) Bandgap-Spannung im> Verhältnis zu VCC. Wenn also VCC 4.4V ist, dann wird die 1.1V> Bandgap-Spannung als 256 gemessen. Wenn VCC 3.3V ist, dann misst man> 341. Dann stimmt deine Rechenmethode, um VCC auszurechnen.>> Aber wenn du eine veränderliche Spannung an einem der ADC-Eingangspins> messen willst, brauchst du a) eine stabile Referenzspannung, b) darf die> Eingangsspannung nicht größer als die Referenzspannung werden (sonst> kommt als Messwert immer 1023 raus), und c) musst du deine> Berechnungsformel umstellen.>> HTH.>> LG, Sebastian
Hi danke für die Antwort.
Ist mir gerade nach langem Googeln auch klar geworden.
Habe fäschlicherweise gedacht Vbg == Vcc
und Somit die Funktionsweise von GetVcc() total falsch verstanden.
Jetzt ist`s klar.
Ich setzte also REFS1 und REFS0 auf 0 für Vcc als Ref und MUX auf 0b0010
für ACD2.
Dann müsste mir Aref(Vcc) / 1024 * ResultACD die Spannung am Pin ACD2
geben.
Ist es eigentlich notwendig den Pin als Input ohne Pullup zu setzen oder
reicht es das Digital Input Disable Register zu setzen?
Z.B. Max schrieb:> Jetzt ist`s klar.> Ich setzte also REFS1 und REFS0 auf 0 für Vcc als Ref und MUX auf 0b0010> für ACD2.> Dann müsste mir Aref(Vcc) / 1024 * ResultACD die Spannung am Pin ACD2> geben.
Du bist verwirrt, wie mir scheint...
Wenn du die Betriebsspannung des µC messen willst, was hat das dann mit
Pin 2 zu tun?
Und wenn du die Spannung an Pin 2 messen willst, dann doch nicht
ratiometrisch gegen Vcc.
Oder?
Du merkst:
Ich habe noch nicht verstanden was du willst!
Weißt du was du willst?
Z.B. Max schrieb:> Jetzt ist`s klar.> Ich setzte also REFS1 und REFS0 auf 0 für Vcc als Ref und MUX auf 0b0010> für ACD2.> Dann müsste mir Aref(Vcc) / 1024 * ResultACD die Spannung am Pin ACD2> geben.
Ja. Setzt natürlich voraus dass du VCC kennst ...
LG, Sebastian
Arduino F. schrieb:> Z.B. Max schrieb:>> Jetzt ist`s klar.>> Ich setzte also REFS1 und REFS0 auf 0 für Vcc als Ref und MUX auf 0b0010>> für ACD2.>> Dann müsste mir Aref(Vcc) / 1024 * ResultACD die Spannung am Pin ACD2>> geben.>> Du bist verwirrt, wie mir scheint...>> Wenn du die Betriebsspannung des µC messen willst, was hat das dann mit> Pin 2 zu tun?> Und wenn du die Spannung an Pin 2 messen willst, dann doch nicht> ratiometrisch gegen Vcc.> Oder?>> Du merkst:> Ich habe noch nicht verstanden was du willst!> Weißt du was du willst?
Hi, ich möchte nicht die Vcc messen sondern die Batteriespannung. Der
ATTiny wird über eine 9V Batterie über einen Linerregler mit 5V
betrieben. Nun möchte ich herausfinden wann die 9V Batterie leer ist.
Also über einen 50/50 Spannungsteiler an ACD2 angelegt.
Hab das ganze jetzt mal an einem 328 getestet damit ich die Werte über
den seriellen Port anzeigen lassen kann.
Vin laut Multimeter 4,8V
Über ein Netzteil gebe ich nun auf ACD2 0 - 4,8V
Nun erwarte ich dass das Ergebnis vom ADC bei 4,8V am Pin ACD2 1023,
jedoch bekomme ich schon bei 4,2V 1023 als Ergebnis. Warum?
1
#include<Arduino.h>
2
intgetBattV()
3
{
4
DDRB&=~_BV(PC2);// PB4 as input
5
PORTB&=~_BV(PC2);// no pullup on PB4
6
7
DIDR0&=~_BV(ADC2D);//disable digital input for ADC2
8
9
ADMUX=_BV(MUX1)|_BV(REFS0);//ADC2/PB4 and Vdd als Ref(4,8V)
10
11
delay(5);// wait for Vref to settle
12
13
ADCSRA|=_BV(ADSC);// reading ADC
14
while(bit_is_set(ADCSRA,ADSC));//ADSC will be set to 0 wen conversion is finished
15
16
uint8_tlow=ADCL;
17
unsignedintadcVal=(ADCH<<8)|low;
18
19
// discard previous result ("The first ADC conversion result after switching voltage reference source maybe inaccurate, and the user is advised to discard this result.")
Sebastian W. schrieb:> Bei einem Arduino ist VIN nicht VCC ...>> LG, Sebastian
Sorry meine natürlich VCC nicht VIN ich benutze nur den 328 auf nem
breadboard.
Aber hab meinen Fehler grad gefunden VCC !=AVCC
Brücke ich VCC und AVCC bekomm ich das erwartete Ergebnis.
Z.B. Max schrieb:> Brücke ich VCC und AVCC
AVCC ist die Versorgung für den Analogteil. Wenn man die weglässt, dann
wird der Analogteil aus VCC parasitär versorgt, also über Pfade und
Dioden die für Ströme nicht ausgelegt sind. Auf diesen Pfaden fallen
dann schnell einige Zehntel Volt ab. Soll man nicht machen ...
LG, Sebastian
Sebastian W. schrieb:> Z.B. Max schrieb:>> Brücke ich VCC und AVCC>> AVCC ist die Versorgung für den Analogteil. Wenn man die weglässt, dann> wird der Analogteil aus VCC parasitär versorgt, also über Pfade und> Dioden die für Ströme nicht ausgelegt sind. Auf diesen Pfaden fallen> dann schnell einige Zehntel Volt ab. Soll man nicht machen ...>> LG, Sebastian
Bin grad erst am Anfang mit den Microcontrollern, da hab ich übersehen
dass der 328 im Gegensatz zum t85 ne extra Spannungsversorgung für den
Analogteil hat.
Danke für deine Hilfe, hat mir sehr geholfen.