Hallo liebe Leute,
ich bin Anfänger in Sachen Mikrocontroller-Programmierung und benötige
Hilfe bei der Verwendung des AD Wandlers. Die Suchfunktion hat mir
leider keine Threads mit ähnlichen Problemen beschert.
Erstmal zu meiner Hardware:
Ich benutze das RN Control 1.4 Board mit Atmega32 und 16MHz Quarz.
(Schaltplan angehängt)
Ich möchte mittels AD-Wandlung (PA7) die 5 eingebauten Taster (PC0 bis
PC5) abfragen. Die Taster sind über einen Spannungsteiler angeschlossen.
Jedem Taster ist eine LED zugeordnet, welche bei Betätigung leuchtet.
Wenn kein Taster betätigt wird soll keine LED leuchten.
Der erste Teil der Aufgabe funktioniert auch gut ganz, jeder Taster
lässt die entsprechende LED leuchten. Das eigentlich Problem ist, wenn
ich keinen Taster drücke flackern die LEDs wahllos. Es scheint irgendein
hochfrequentes/kapazitives Problem zu sein. Nähere ich mich dem Board
mit der Hand oder einem Gegenstand verändert sich die Stärke des
Flackerns. Je nach dem wie man das Board hält Flackern verschiedene
LEDs. Ich verstehe nicht wie das Zustande kommt.
Für die Auswertung des ADC Signales benutze ich die 8 Bit des
ADCH-Registers. Das ADCL-Register wird nicht abgefragt.
Für den Spannungsteiler über den die Taster angeschlossen sind habe ich
folgende Werte ausgerechnet (und im Code verwendet):
Spannung ADC-Messwert(8 Bit)
o. Taster 3,33 170,67
Taster 1 1, 85,33
Taster 2 1,3 68,27
Taster 3 1,00 51,20
Taster 4 0,67 34,13
Taster 5 0,33 17,07
Hier der zugehörige Code:
1
#define F_CPU 1600000UL
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
7
double voltage;
8
double wert;
9
10
11
int main(void)
12
{
13
DDRC = 0xFF;
14
15
16
//ADC CONFIG
17
ADMUX = (1<<ADLAR); //linksbündige Ausgabe des Ergebnisses
18
ADMUX |= (1<<REFS0); ///Festlegung der Referenzspannung auf Extern
Das ist normal, da der Eingang des ADC in der Luft hängt, wenn kein
Taster gedrückt ist. Eine Lösung wäre, einen Widerstand (z. B. 220k oder
größer) zwischen PA7 und +5V zu schalten. Oder zwischen PA7 und Masse.
Erstere Lösung würde den ADC auf Maximum aussteuern, wenn kein Taster
gedrückt ist, die zweite würde 0V am ADC anliegen lassen, wenn kein
Taster gedrückt ist.
Voldemort schrieb:> wenn> ich keinen Taster drücke flackern die LEDs wahllos. Es scheint irgendein> hochfrequentes/kapazitives Problem zu sein.
Wenn keine Taste gedrückt ist hängt der ADC-Eingang "in der Luft".
Dadurch wirkt er wie eine Antenne.
Häng mal einen 1Mohm vom ADC zu GND.
Danke für eure Hilfe.
Wieso hängt der ADC eigentlich "in der Luft"? Wenn ich den
Spannungsteiler der dort verwendet wird (1x 10kOhm, 5x 1kOhm) richtig
verstanden habe, müssten doch immer 3,33V (5V * 10kOhm/15kOhm) an PA7
liegen wenn kein Taster gedrückt wird. Oder?
Aus welchem Grund wurde den herstellerseitig kein größerer Widerstand
als 10kOhm dort verbaut? Bisher schien mir das Board an allen stellen
sehr durchdacht zu sein. Dann gibt es sicher dafür auch eine gute
Begründung.
Gibt es irgendeine eine Software Lösung um dieses Flackern zu
unterbinden?
Voldemort schrieb:> Bisher schien mir das Board an allen stellen> sehr durchdacht zu sein
Für mich sieht die Art wie die Taster angeschlossen sind eher suboptimal
aus!
> Dann gibt es sicher dafür auch eine gute> Begründung.
Die Begründung ist vermutlich dass man so an den JP2/8 alles
anschliessen kann.
Voldemort schrieb:> Wieso hängt der ADC eigentlich "in der Luft"? Wenn ich den> Spannungsteiler der dort verwendet wird (1x 10kOhm, 5x 1kOhm) richtig> verstanden habe, müssten doch immer 3,33V (5V * 10kOhm/15kOhm) an PA7> liegen wenn kein Taster gedrückt wird. Oder?
Nein, der Spannungsteiler hängt an PA6, schau mal genau hin. PA7 hängt
in der Luft wenn kein Taster gedrückt wird.
Voldemort schrieb:> Aus welchem Grund wurde den herstellerseitig kein größerer Widerstand> als 10kOhm dort verbaut?
Wegen eventueller Leckströme und ähnliches. Je kleiner der Widerstand
desto mehr Strom kann fließen (will man ggf ja gar nicht). Macht man den
Widerstand aber zu groß können sich z.B. Leckströme unangenehm bemerkbar
machen. 100 nA erzeugen an 1 MegΩ schon 100 mV Spannungsfall, man will
aber vielleicht 0 V. Die 10 kΩ sind also ein Kompromiss. Man hätte auch
20 kΩ oder 50 kΩ nehmen können. Das ist dann eher eine
Bauchentscheidung. 10 kΩ sind halt am leichtesten zu bekommen, gibts
besser als Sand am Meer.
Max M. schrieb:> Schalt einfach mal den internen Pullup ein!
Jaaa. Danke das hat es gebracht. ;)
Ich wusste bisher nicht dass es möglich ist den ADC mit den internen
Pullup Widerständen zu kombinieren. Schön blöd von mir.
Wie berechnet man denn am leichtesten welchen Spannungswert den der ADC
misst? Durch die Zuschaltung der Pullups haben sich die Messwerte
gegenüber den oben angegebenen verändert.
Ich habe durch probieren heraus gefunden welche Werte ich in die
If-Abfrage eintragen muss. Würde jedoch gerne wissen wie man es
berechnet.
Danke für eure Unterstützung! :)
Voldemort schrieb:> Wie berechnet man denn am leichtesten welchen Spannungswert den der ADC> misst? Durch die Zuschaltung der Pullups haben sich die Messwerte> gegenüber den oben angegebenen verändert.> Ich habe durch probieren heraus gefunden welche Werte ich in die> If-Abfrage eintragen muss. Würde jedoch gerne wissen wie man es> berechnet.
Hö? Was meinst du damit?
Die Spannung am ADC-Pin, die gemessen wurde, ist:
Je nachdem welche Referenzquelle du halt ausgesucht hast, ob du ADLAR
und 8 bit nutzt oder 10 bit usw. Also das ist doch nun wirklich kein
Hexenwerk und wird im Datenblatt des Atmegas32 ausführlich beschrieben.
Michael K. schrieb:> Hö? Was meinst du damit?
Er meint damit, daß der nun eingeschaltete interne Pull-up-Widerstand
von seinem Wert her in die Rechnung eingeht, er aber den Wert nicht
kennt.
Da hilft nur: Den internen Ziehwiderstand nicht einschalten und
stattdessen draußen einen "echten" Widerstand dranmachen, dessen Wert
bekannt ist.
MfG Paul
Michael K. schrieb:> Hö? Was meinst du damit?>> Die Spannung am ADC-Pin, die gemessen wurde, ist:>> Je nachdem welche Referenzquelle du halt ausgesucht hast, ob du ADLAR> und 8 bit nutzt oder 10 bit usw. Also das ist doch nun wirklich kein> Hexenwerk und wird im Datenblatt des Atmegas32 ausführlich beschrieben.
Sorry falls ich mich unverständlich ausgedrückt habe.
Ich habe die Spannung am ADC-Eingang bisher über die Verhältnisse am
Spannungsteiler berechnet.
Also Referenzspannung * Widerstand/Gesamtwiderstand.
Für Taster T1 heißt das beispielsweise 5V * 5kOhm/15kOhm = 1,67 V
Und diese 1,67V entsprechen bei 8 Bit auslesen einem Wert von 85. (1,67
* 256/5 = 85) Daher wusste ich, dass das bei einem Messwert am ADC von
etwa 85 der erste Taster betätigt wird.
Jetzt wo ich die Pullup Widerstände eingeschaltet habe funktioniert
diese Rechnung jedoch nicht mehr. Die Messwerte habe sich verändert. Der
erste Taster erzeugt nun einen Wert von 98, statt wie vorher 85.
Paul B. schrieb:> Er meint damit, daß der nun eingeschaltete interne Pull-up-Widerstand> von seinem Wert her in die Rechnung eingeht, er aber den Wert nicht> kennt.
Achso, ja da ist was dran.
Voldemort schrieb:> Jetzt wo ich die Pullup Widerstände eingeschaltet habe funktioniert> diese Rechnung jedoch nicht mehr. Die Messwerte habe sich verändert. Der> erste Taster erzeugt nun einen Wert von 98, statt wie vorher 85.
Beachte was Paul geschrieben hat. Du hast jetzt einen kleinen Vorteil:
Du kennst deinen Spannungsteiler und hast den ADC-Wert. Mit diesen
Mitteln kannst du nun den internen Pullup ausrechnen. Wie das? Ganz
einfach: Oben hab ich ja schon geschrieben wie du die Spannung am Pin
aus dem ADC-Wert ausrechnen kannst.
Deine Schaltung bei geschlossenem Taster schaut so aus:
Ub Ub
o o
| |
| |
- -
| | | |interner
R1| | | |Pullup
- -
| |
| |
| |
+----+--- ADC
|
-
| |
R2| |
-
|
|
-
GND
Bis auf den Pullup kennst du alle Werte (R1 und R2 ergeben sich aus dem
Taster, den du gedrückt hast), damit kannst du dir den Pullup ausrechnen
;)
Michael K. schrieb:> Du hast jetzt einen kleinen Vorteil:> Du kennst deinen Spannungsteiler und hast den ADC-Wert. Mit diesen> Mitteln kannst du nun den internen Pullup ausrechnen.
Das kann er machen, aber wenn er einen anderen Atmega32 aus der Kiste
nimmt, dann ist der Ziehwiderstand in diesem wieder (wahrscheinlich
geringfügig) ein Anderer. So müßte er das Programm für jeden Kontroller
einzeln mit den entsprechenden Werten versehen.
Da ist es doch besser, draußen einen separaten Widerstand dranzumachen,
denke ich.
MfG Paul
Danke Paul und Michael für eure Tipps. :)
Die Auswertung von Analog Signalen scheint leider ganz schön umständlich
zu sein. Nach dem das mit den LEDs geklappt hat (jeder Taster betätigt
jeweils eine LED) habe ich einen PC Lüftermotor angeschlossen. Die
Drehzahl des Motors wird über PWM gesteuert. Jedem Taster wurde eine
bestimmte Drehzahl zugeordnet.
Die Werte die der ADC misst sind für den Motor wiederum andere als für
die LEDs. Anscheinend muss man je nach Verbraucher die ADC Werte
anpassen, sonst ist die Zuordnung zu den Tastern korrekt.
Paul B. schrieb:> Da ist es doch besser, draußen einen separaten Widerstand dranzumachen,> denke ich.
Natürlich ist das besser die Schaltung entsprechend zu ändern. Man muss
ja schon so genügend von Controller zu Controller vermessen wenn man
will, dass sie gleich sind (z.B. die interne VREF-Spannung)
Voldemort schrieb:> Danke Paul und Michael für eure Tipps. :)>>> Die Auswertung von Analog Signalen scheint leider ganz schön umständlich> zu sein.
Nicht wirklich.
> Die Werte die der ADC misst sind für den Motor wiederum andere als für> die LEDs. Anscheinend muss man je nach Verbraucher die ADC Werte> anpassen, sonst ist die Zuordnung zu den Tastern korrekt.
Vor allen Dingen wäre es wichtig, dass die Spannungen nicht je nach
Verbraucher einbrechen und der Verbraucher keinen Schmutz auf die
Spannungen einkoppelt. So wie immer halt. Je sauberer gearbeitet wird,
desto besser sind die Ergebnisse.