Hallo zusammen,
Ich habe momentan ein kleines Problem:
Ich bin vom TI Launchpad auf einen Atmel AVR ATtiny 45 umgestiegen.
Ich will mit dem ATtiny 45 die Spannung einer externen
Spannungsversorgung auslesen. Ich habe mich im Vorferld darüber
informiert, leider klappt es in der Praxis aber nicht.
Vom Schaltbild her ist es so, dass ich den Pin PB4 (Physical 3) vom
ATtiny nutzen möchte. In der Theorie reicht es mir, wenn der ATtiny
erkennt ob eine Spannung fließt oder nicht (1|0).
Ich habe bereits mehrere Codes angesehen und ausprobiert und angepasst.
Als Example:
1
voidinitADC()
2
{
3
/* this function initialises the ADC
4
5
ADC Notes
6
7
Prescaler
8
9
ADC Prescaler needs to be set so that the ADC input frequency is between 50 - 200kHz.
10
11
Example prescaler values for various frequencies
12
13
Clock Available prescaler values
14
---------------------------------------
15
1 MHz 8 (125kHz), 16 (62.5kHz)
16
4 MHz 32 (125kHz), 64 (62.5kHz)
17
8 MHz 64 (125kHz), 128 (62.5kHz)
18
16 MHz 128 (125kHz)
19
20
below example set prescaler to 128 for mcu running at 8MHz
21
22
23
*/
24
25
ADMUX=
26
(1<<ADLAR)|// left shift result
27
(0<<REFS1)|// Sets ref. voltage to VCC, bit 1
28
(0<<REFS0)|// Sets ref. voltage to VCC, bit 0
29
(0<<MUX3)|// use ADC2 for input (PB4), MUX bit 3
30
(0<<MUX2)|// use ADC2 for input (PB4), MUX bit 2
31
(1<<MUX1)|// use ADC2 for input (PB4), MUX bit 1
32
(0<<MUX0);// use ADC2 for input (PB4), MUX bit 0
33
34
ADCSRA=
35
(1<<ADEN)|// Enable ADC
36
(1<<ADPS2)|// set prescaler to 64, bit 2
37
(1<<ADPS1)|// set prescaler to 64, bit 1
38
(0<<ADPS0);// set prescaler to 64, bit 0
39
}
40
41
42
intmain(void)
43
{
44
45
initADC();
46
47
while(1)
48
{
49
50
ADCSRA|=(1<<ADSC);// start ADC measurement
51
while(ADCSRA&(1<<ADSC));// wait till conversion complete
52
53
if(ADCH>128)
54
{
55
// ADC input voltage is more than half of VCC
56
57
}else{
58
59
// ADC input voltage is less than half of VCC
60
61
}
62
63
}
64
65
return0;
66
}
Nur so nebenbei, der ATtiny läuft auch und er kann auch LEDs schalten,
nur so als Funktionsbeweis.
Anbei befindet sich auch noch das Pinning des ATtiny.
Ich wäre sehr froh, wenn mir jemand helfen könnte.
Vielen Dank im Voraus,
MfG CortexA8
Hallo spess53,
Danke für die Antwort, aber leider ja habe ich.
Ich habe die Anwendung auch bereits mit dem MSP430G2553 gemacht, dieser
ist allerdings zu Groß und zu stromhungrig.
Hast du noch eine Idee ?
Danke schonmal
CortexA8 schrieb:> Spannungsversorgung auslesen. Ich habe mich im Vorferld darüber> informiert, leider klappt es in der Praxis aber nicht.
Was soll denn klappen, und woran erkennst du, daß es nicht klappt? Im
geposteten Programm wird jedenfalls keine LED geschaltet.
> Vom Schaltbild her ist es so, dass ich den Pin PB4 (Physical 3) vom> ATtiny nutzen möchte. In der Theorie reicht es mir, wenn der ATtiny> erkennt ob eine Spannung fließt oder nicht (1|0).
Spannung fließt nicht. Wie sieht der Schaltplan aus?
Danke für die Anmerkung,
Ich habe den Code Modifiziert und ich schalte eine LED ein, wenn die
Spannung kleiner gleich 128 ist.
Und ja die Spannungsquelle läuft und ich habe das ganze auch per Multi
überprüft. Ich verwende auch eine Spannungsteiler bei 4,8 V in.
Anfürsich ist der ATtiny per 5,2 Volt versorgt und an PB4 und GND an die
zumessende Spannungsversorgung angeschlossen.
MfG CortexA8
Hallo CortexA8,
mit Versorgungsspannung als Referenz wird das nichts. Denn mit der
Spannung verändert sich dann auch die Referenz und dein Messwert bleibt
gleich. In deinem Fall muß eine der internen Referenzspannungen
eingestellt sein.
P.S. Ich habe dein Programm nicht einzeln geprüft, sondern mich am
Kommentar "// Sets ref. voltage to VCC, bit 1" orientiert.
Gruß. Tom
Hallo CortexA8,
ich sehe eben, daß du nicht die Versorgungsspannung des Tiny45 messen
willst, sondern irgendeine andere Versorgungsspannung. Dann ist das
verwenden der Vcc des Tiny, als Referenz, kein Problem.
Sorry, hatte ich falsch verstanden. :(
Gruß. Tom
TomA schrieb:> Dann ist das> verwenden der Vcc des Tiny, als Referenz, kein Problem.
dann darf er aber die Digits nicht absolut in V umrechnen
ich denke das klappt nicht, will er 5V als absolute Schwelle festlegen
bekommt er ja nie ne Referenz, VCC ist unbestimmt, er bekommt nur X% von
VCC mit VCC unbekannt.
Besser wäre es auf jeden Fall, mit einer der internen Referenzen zu
arbeiten. Es geht aber auch mit Vcc, wobei die Genauigkeit eben etwas
geringer sein wird.
Das eigentliche Problem ist meiner Meinung nach aber das alleinige
Auswerten der oberen beiden Bit des 10-Bit Messwertes "if (ADCH > 128)"
- ADCH wird nie größer als 3 sein. Besser wäre hier den ganzen Messwert
zu vergleichen. ADCH beinhaltet nur nur die Bit 8 und 9 von 10-Bit des
Messwertes. Der ganze Meßwert liegt in ADCH/ADCL.
Gruß. Tom
TomA schrieb:> ADCH beinhaltet nur nur die Bit 8 und 9 von 10-Bit des> Messwertes. Der ganze Meßwert liegt in ADCH/ADCL.
Nein. Der ADC wird im "8-Bit-Modus" betrieben:
CortexA8 schrieb:> ADMUX = (1 << ADLAR) |
mfg.
TomA schrieb:> Es geht aber auch mit Vcc, wobei die Genauigkeit eben etwas> geringer sein wird.
ach und wenn es eine Batteriekiste ist mit Spannung von 5,5-2,7V hat man
100% Fehler.
Ist einfach nichts, wenn man sich kein gutes Bild machen kann.
Originalprogramm (das mit dem Fehler) liegt nicht vor. Kein Schaltplan,
Werte des Spannungsteilers unbekannt. Zu messende Spannungsquelle
unbekannt. Wckelaufbau auf Steckbrett ohne Abblock Cs etc. Im
geposteteten Programm erkenne ich zumindest in der Einstellung des ADC
keinen Fehler - wenn man noch wüsste mit welchem Takt der Tiny läuft.
GehtNicht schrieb:> - wenn man noch wüsste mit welchem Takt der Tiny läuft.
wäre auch nicht verkehrt um zu wissen wie oft wie schnell gemessen
werden soll.
Hallo Thomas,
habe jetzt einen Blick ins Datenblatt gewagt, stimmt - Die Bündigkeit
(links/rechts) ist, durch das Bit ADLAR wählbar.
Nun, dann weiß ich auch nicht, wo der Fehler ist.
Gruß. Tom
Hallo beisammen,
Danke für die vielen Rückmeldungen.
Der Takt des ATtiny liegt bei 16 MHz.
Ich habe leider keinen digitalen Schlatplan erstellt, dafür ist der
Aufbau aber auch einfach (Papier).
Nochmals zum Verständnis:
Ich habe einen ATtiny 45 an einer Spannungsversorgung.
Ich will mit dem Pin PB4 die Spannung einer 2. Spannungsquelle messen.
Ich habe dafür einen Spannungsteiler mit je 10kO an R1 und R2. Zwischen
R1 und R2 habe ich eine Verbindung zum Pin PB4 bzw. eine Leitung.
Die Masse/GND von der Spannungsversorgung 2 habe ich mit dem GND Pin vom
ATtiny verbunden.
Meine Anforderung an das Programm wäre jetzt: Wenn eine Spannung an der
2. Spannungsquelle anliegt soll die LED des ATtiny NICHT leuchten,
sollte keine Spannung an der 2. Stromquelle anliegen soll die LED
leuchten.
Der ganz oben gepostete Quellcode war nur ein Testversuch von mir, den
ich dann auch wegen der Disfunktion verbannt habe, aber noch in meinem
Pool von Codes liegen gelassen habe.
Ich bin auch offen für einen anderen Quellcode.
Ich hoffe ich habe alle Ungenauigkeiten beseitigt.
Vielen Dank für die zahlreichen Antworten und ich hoffe die Lösung für
mich kommt auch ;)
MfG CortexA8
CortexA8 schrieb:> Ich habe einen ATtiny 45 an einer Spannungsversorgung.
immer noch unbenannt!
ist die fest? kann man sich auf diese Spannung verlassen?
oder ist es eine Batterie womit AREF = VCC ausfällt
wie oft muss das gemessen werden, in welcher Zeit und warum nimmt man
die interne AREF nicht?
Entschuldigung:
Spannungsquelle 1: 5,1 Volt
Spannungsquelle 2, 4,8 Volt --> Gemessen wird maximal 2,4 Volt, wegen
des Spannungsteilers
Ich hoffe dich habe nichts mehr vergessen.
CortexA8 schrieb:> Der Takt des ATtiny liegt bei 16 MHz.
Und warum setzt du dann den Prescaler für 8 MHz und nicht für 16 MHz?
CortexA8 schrieb:> Clock Available prescaler values> ---------------------------------------> 1 MHz 8 (125kHz), 16 (62.5kHz)> 4 MHz 32 (125kHz), 64 (62.5kHz)> 8 MHz 64 (125kHz), 128 (62.5kHz)> 16 MHz 128 (125kHz)> ...> ADCSRA => (1 << ADEN) | // Enable ADC> (1 << ADPS2) | // set prescaler to 64, bit 2> (1 << ADPS1) | // set prescaler to 64, bit 1> (0 << ADPS0); // set prescaler to 64, bit 0
* Und schon wieder was vergessen:
Wieoft muss gemessen werden: So oft wie es nur geht ;) Ich baue das
ganze nur als Demoapplikation auf um dann später mal eine etwas
erweiterte Platiene zubauen.
Warum ich die interne AREF ausgeschlossen ahbe ist, laut einem
Forumsbeitrag hat man dort das Porblem, das wenn der Wert unter 2 Volt
sinkt, die Auswertung des ATtiny wohl verrückt spielt.
MfG CortexA8
Ich hoffe ich liege grade nicht falsch, aber diese Init geht nicht...
ADMUX =
(1 << ADLAR) | // left shift result
(0 << REFS1) | // Sets ref. voltage to VCC, bit 1
(0 << REFS0) | // Sets ref. voltage to VCC, bit 0
(0 << MUX3) | // use ADC2 for input (PB4), MUX bit 3
(0 << MUX2) | // use ADC2 for input (PB4), MUX bit 2
(1 << MUX1) | // use ADC2 for input (PB4), MUX bit 1
(0 << MUX0); // use ADC2 for input (PB4), MUX bit 0
ADCSRA =
(1 << ADEN) | // Enable ADC
(1 << ADPS2) | // set prescaler to 64, bit 2
(1 << ADPS1) | // set prescaler to 64, bit 1
(0 << ADPS0); // set prescaler to 64, bit 0
Das ist doch eine logische verODERung...Richt wäre:
ADMUX =
(1 << ADLAR) | // left shift result
(1 << MUX1) | // use ADC2 for input (PB4), MUX bit 1
ADCSRA =
(1 << ADEN) | // Enable ADC
(1 << ADPS2) | // set prescaler to 64, bit 2
(1 << ADPS1) | // set prescaler to 64, bit 1
Anmerkung: Ich bin NICHT sicher, ob es daran liegt...
CortexA8 schrieb:> Warum ich die interne AREF ausgeschlossen ahbe ist, laut einem> Forumsbeitrag hat man dort das Porblem, das wenn der Wert unter 2 Volt> sinkt, die Auswertung des ATtiny wohl verrückt spielt.
ich fürchte du verwechselst einiges
wenn der Wert unter 2 Volt.....
ist was völlig anders als
wenn die AVCC / VCC unter 2 Volt......
da der Tiny bis 1,8V arbeiten kann
aber ob der Tiny an einer Batterie hängt hast du ja immer noch
verschwiegen
manno so macht das keinen Spass, mach dir mal eine Checkliste....
Joachim B. schrieb:> aber ob der Tiny an einer Batterie hängt hast du ja immer noch> verschwiegen
--> Nein er hängt an keiner Batterie. Es ist ein sperates stabiles
Netzteil.
MfG CortexA8
EDIT !!!!
Es läuft !! Danke für die Kommentare, schlussendlich hat das
Auskommentieren der Werte von ADMUX geholfen, dann musste ich noch den
Schwellenwert ADCH nach unten absenken. Unten steht der funktionierende
Code:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
5
intset_PORTB_bit(intposition,intvalue);
6
7
voidinitADC()
8
{
9
/* this function initialises the ADC
10
11
ADC Notes
12
13
Prescaler
14
15
ADC Prescaler needs to be set so that the ADC input frequency is between 50 - 200kHz.
16
17
Example prescaler values for various frequencies
18
19
Clock Available prescaler values
20
---------------------------------------
21
1 MHz 8 (125kHz), 16 (62.5kHz)
22
4 MHz 32 (125kHz), 64 (62.5kHz)
23
8 MHz 64 (125kHz), 128 (62.5kHz)
24
16 MHz 128 (125kHz)
25
26
below example set prescaler to 128 for mcu running at 16MHz
27
28
29
*/
30
31
ADMUX=
32
(1<<ADLAR)|// left shift result
33
//(0 << REFS1) | // Sets ref. voltage to VCC, bit 1
34
//(0 << REFS0) | // Sets ref. voltage to VCC, bit 0
35
//(0 << MUX3) | // use ADC2 for input (PB4), MUX bit 3
36
//(0 << MUX2) | // use ADC2 for input (PB4), MUX bit 2
37
(1<<MUX1);// use ADC2 for input (PB4), MUX bit 1
38
//(0 << MUX0); // use ADC2 for input (PB4), MUX bit 0
39
40
ADCSRA=
41
(1<<ADEN)|// Enable ADC
42
(1<<ADPS2)|// set prescaler to 64, bit 2
43
(1<<ADPS1)|// set prescaler to 64, bit 1
44
(1<<ADPS0);// set prescaler to 64, bit 0
45
}
46
47
48
intmain(void)
49
{
50
DDRB=PB3;
51
initADC();
52
53
while(1)
54
{
55
56
ADCSRA|=(1<<ADSC);// start ADC measurement
57
while(ADCSRA&(1<<ADSC));// wait till conversion complete
58
59
if(ADCH>50)
60
{
61
// ADC input voltage is more than half of VCC
62
set_PORTB_bit(3,0);
63
64
}else{
65
66
// ADC input voltage is less than half of VCC
67
set_PORTB_bit(3,1);
68
}
69
70
}
71
72
return0;
73
}
74
75
76
// Function code
77
intset_PORTB_bit(intposition,intvalue)
78
{
79
// Position = PINB
80
// Value HiGH OR LOW bzw. 1 or 0
81
82
83
if(value==0)
84
{
85
PORTB&=~(1<<position);// Set bit position low
86
}
87
else
88
{
89
PORTB|=(1<<position);// Set high, leave others alone
90
}
91
92
return1;
93
}
Ich füge noch demnächst das digitale Schaltbild an, damit man das ganze
auch noch später anchvollziehen kann.
Vielen, vielen Dank
MfG CortexA8