Forum: Mikrocontroller und Digitale Elektronik Taster am AD Wandler plus WakeUp - wie?


von T.Baumbach (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe an einem Atmega8 4 Taster an einem AD-Wandler.
Ich drücke immer nur einen Taster also nie mehrere gleichzeitig, 
Entprellen habe ich über eine einfache Warteschleife realisiert. Reicht 
aus und funktioniert.
Wenn ich einen der 4 Taster drücke, ändert sich der Widerstand und das 
kann ich am AD-Wandler des Atmega8 auswerten welcher Taster gedrückt 
wurde. So brauche ich nur 1 Port für 4 Taster. Siehe dazu auch 
angehängtes Bild.
Nun würde ich gerne meine Schaltung mit Batterien oder Akkus betreiben 
und eine möglichst lange Laufzeit erreichen. Dafür würde ich den Atmega8 
gerne in eine SleepMode versetzen und über den Druck auf einen der 4 
Taster wieder aufwecken.

Meine Frage:

Die Schaltung für die 4 Taster habe ich bereits, funktioniert auch, ich 
würde die Schaltung gerne so ändern, dass ich über einen Druck auf einen 
der vier Taster den Atmega8 aufwecke und dann sofort über den AD-Wandler 
auslese welche Taste gedrückt wurde.
Da ich nicht so sehr elektronisch bewandert bin weiß ich nicht, wie ich 
den WakeUp-Interrupt-Pin des Atmega8 und meine jetzige Schaltung 
verbinden muss damit das funktioniert.

Brauche da mal eure Hilfe, vielen Dank schonmal!

von c-hater (Gast)


Lesenswert?

T.Baumbach schrieb:

> Die Schaltung für die 4 Taster habe ich bereits, funktioniert auch

Dann muß sie sich aber recht stark von der unterscheiden, deren Plan du 
gepostet hast. Denn diese funktioniert garantiert NICHT.

> Nun würde ich gerne meine Schaltung mit Batterien oder Akkus betreiben
> und eine möglichst lange Laufzeit erreichen. Dafür würde ich den Atmega8
> gerne in eine SleepMode versetzen und über den Druck auf einen der 4
> Taster wieder aufwecken.

Kann man machen. Wenn man das Widerstandsnetzwerk sinnvoll auslegt, 
sollte  diese Zusatzfunktionalität mit nur vier Tastern noch relativ 
problemlos möglich sein.

von T.Baumbach (Gast)


Angehängte Dateien:

Lesenswert?

Hi c-hater,

ja hast recht, habe meinen Schaltplan zu schnell ab gezeichnet - sorry.
Hier die (hoffentlich) korrekte Version, siehe angehängte Datei.

Wie muss ich die nun erweitern, um über den Interrupt den Atmega8 
aufzuwecken und dann den ADC auswerten zu können welche Taste gedrückt 
wird?

Danke nochmals!

von c-hater (Gast)


Lesenswert?

T.Baumbach schrieb:

> Hier die (hoffentlich) korrekte Version, siehe angehängte Datei.

Ja, das sieht schon viel besser aus, diese Schaltung kann immerhin 
funktionieren. Sie ist allerdings schon für den ursprünglichen Zweck 
ziemlich suboptimal. Und für den neuen Zweck, Energie zu sparen, ist sie 
leider ziemlich unbrauchbar, auch wenn die grundsätzliche Funktion damit 
realisierbar ist.

> Wie muss ich die nun erweitern, um über den Interrupt den Atmega8
> aufzuwecken und dann den ADC auswerten zu können welche Taste gedrückt
> wird?

Einfach den 10k-Widerstand Richtung GND deutlich vergrößern, z.B. auf 
33k.

Damit verringern sich allerdings die ohnehin bescheidenen Unterschiede 
für die einzelnen Taster weiter.

Die Alternative wäre, statt dessen den 10k-Widerstand Richtung Vcc zu 
verkleinern, z.B. auf 3,3k. Damit erhöhen sich die Unterschiede zwischen 
den Tastern etwas, aber es fließt im Schlafzustand noch mehr Strom 
sinnlos.

Grundsätzlich kannst du das Problem nur durch eine Modifikation der 
Schaltung lösen. Die kann dann erstens dafür sorgen, daß im 
Schlafzustand garkein Strom mehr durch das Taster-R-Netzwerk fließt und 
zweitens auch noch dafür, daß die Taster im Wachzustand sehr viel 
zuverlässiger unterscheidbar sind als bisher.

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> T.Baumbach schrieb:

>> Wie muss ich die nun erweitern, um über den Interrupt den Atmega8
>> aufzuwecken

Ooops, ich habe jetzt erst gesehen, daß es um einen Methusalem von 
Controller geht, der noch keinen PCINT für jeden Pin beherrscht. Für den 
ist natürlich zusätzlich ein freier interruptfähiger Pin nötig, um das 
zu realisieren. Dieser Pin muß dann einfach mit an den verwendeten 
ADC-Eingang geschaltet werden. Und in diesem Fall fällt auch die 
Variante mit der Erhöhung des Widerstands Richtung Vcc aus.

von m.n. (Gast)


Lesenswert?

Wenn Du unbedingt beim ATmega8 bleiben möchtest, mußt Du parallel zum 
ADCx-Eingang noch einen INTx-Eingang verwenden, der auf negative Flanken 
reagiert. Besser ist es allerdings einen ATmega48/88 mit PCINT-Option zu 
verwenden.

Mein Vorschlag: ein Pullup-Widerstand (100k) von ADCx nach VCC. Von ADCx 
werden einzelne Widerstände (68k, 33k, 15k, 0R0) mit den Tastern gegen 
GND geschaltet.
Bei offenen Tastern fließt kein Strom. Sobald ein Taster geschlossen 
wird, sinkt die Spannung an ADCx/INTx deutlich unter VCC/2, was zur 
Flankenerkennung notwendig ist und den µC aufweckt.
Man kann auch größere Widerstände einsetzen (220k, 100k, 47k, 0R0), 
wobei bei den Werten >=68k noch ein 1nF Kondensator parallel geschaltet 
werden muß, damit der INTx-Eingang kurzzeitig auf kleiner 0,4 x VCC 
gebracht wird, um den Interrupt auszulösen. Anstelle des 0R0, kann man 
auch 6k8 bzw. 22k vorsehen und damit auch mehrere Taster gleichzeitig 
erkennen.

Oder man nimmt eine Reihenschaltung von 3 x 22k, deren Abgriffe nach GND 
geschaltet werden. Dadurch erhält man eine Priorität der Taster: der 
Taster 'gewinnt', der am nächsten zu ADCx geschlossen ist. Als 
Widerstände ergeben sich dann 0R0, 22k, 44k oder 66k.

Für geringe Stromaufnahme sollte BOD ausgeschaltet sein. Ferner sollten 
die Taster möglichst vergoldete Kontakte aufweisen, womit kleine Ströme 
zuverlässig geschaltet werden können.

von T.Baumbach (Gast)


Lesenswert?

Hallo,

danke erstmal für die Tipps. Ich muss nicht unbedingt einen Atmega8 
nehmen, hatte den nur gerade da. Ich denke mal ich nehme in meiner 
finalen Schaltung einen Attiny26.
Hinsichtlich möglichst geringem Stromverbrauch macht es da überhaupt 
Sinn über den ADC die Tasten auszuwerten?
Oder spare ich mehr Strom, wenn ich einen anderen Prozessor nehme (evtl. 
Attiny2313?) und dann für z.B. 16 Tasten ein 4x4 Keypad an 4 Zeilen / 4 
Spalten nehme und dafür 8 Portpins 'opfere'? Wäre diese Version 
stromsparender als die ADC-Variante?

von m.n. (Gast)


Lesenswert?

T.Baumbach schrieb:
> 16 Tasten ein 4x4 Keypad an 4 Zeilen / 4
> Spalten nehme

Warum willst Du 16 Tasten nehmen, wenn Du nur vier brauchst?
Die Stromaufnahme steht im Datenblatt und liegt unter 1µA, wenn man den 
µC richtig schlafen legt.
Fang einfach an!

von T.Baumbach (Gast)


Lesenswert?

Hallo m.n.,

danke nochmal, die Schaltung mit den 4 Tastern war (eigentlich) zum 
'lernen' gedacht. In meiner finalen Schaltung brauche ich aber 16 
Taster.
Macht es hinsichtlich Stromaufnahme dann eher Sinn die 4x4 Keypad-Lösung 
zu nehmen?

von c-hater (Gast)


Lesenswert?

T.Baumbach schrieb:

> Ich denke mal ich nehme in meiner
> finalen Schaltung einen Attiny26.

Bessere Wahl.

> Hinsichtlich möglichst geringem Stromverbrauch macht es da überhaupt
> Sinn über den ADC die Tasten auszuwerten?

Solange du nicht vorhast, dauerhaft Tasten zu drücken, sondern das immer 
ein vergleichsweise kurzes Ereignis bleibt, was die übliche Nutzung 
wäre, spricht nichts gegen die ADC-Variante, sofern sie in etwa so 
umgesetzt wird wie von "m.n." vorgeschlagen. Strom fließt da nämlich, 
abweichend von deiner ursprünglichen Schaltung, nur dann, wenn 
tatsächlich eine Taste gedrückt wird.

> Wäre diese Version
> stromsparender als die ADC-Variante?

Ja, aber nur in irrelevanter Größenordnung. So lange dir ca. 8 Taster 
oder weniger reichen, kannst du getrost bei der ADC-Variante bleiben.

von T.Baumbach (Gast)


Lesenswert?

Hi c-hater,

>Ja, aber nur in irrelevanter Größenordnung. So lange dir ca. 8 Taster
>oder weniger reichen, kannst du getrost bei der ADC-Variante bleiben.

Ich brauche 16 Taster, aber immer nur einer gedrückt, nie zwei oder 
mehrere zusammen!
Wenn immer nur einer gedrückt wird dann ist es doch egal wieviele Taster 
ich habe - oder? Ich meine hinsichtlich Stromaufnahme.

von T.Baumbach (Gast)


Lesenswert?

Hi,

der ADC selber braucht ja auch Strom. Kann ich denn den ADC erst 
einschalten lassen, wenn ich den Mikrocontroller aufgeweckt habe?
Das würde dann noch mehr Strom sparen - oder?
Also der Mikrocontroller schläft, in Low-Pegel auf einem Interrupt-Pin 
weckt den Mikrocontroller auf. Der geht in die Interruptroutine und 
schaltet den ADC ein der dann auswertet welche Taste gedrückt wurde - 
ginge das?

Aufbauen würde ich das Teastenfeld wie m.n. es beschrieben hat:

>Oder man nimmt eine Reihenschaltung von 3 x 22k, dere>n Abgriffe nach GND
>geschaltet werden. Dadurch erhält man eine Priorität der Taster: der
>Taster 'gewinnt', der am nächsten zu ADCx geschlossen ist. Als
>Widerstände ergeben sich dann 0R0, 22k, 44k oder 66k.

Ich weiß aber nicht wie ich die Schaltung erstellen muss, um den 
Interrupt an einem Pin auszulösen, der den Mikrocontroller aufweckt.
Das soll ja eine der 16 Tasten machen. Wie muss ich die Tasten und den 
Interrupt-Pin beschalten, damit zuerst der Interrupt ausgelöst wird (um 
den Mikrocontroller aufzuwecken) und dann über den Widerstandswert und 
den ADC ausgewertet wird welche taste gedrückt wurde.

Danke nochmal, bin wie gesagt nicht so fit in Elektronik, bin für jede 
Hilfe dankbar. Ein Schaltplan wäre super!

von c-hater (Gast)


Lesenswert?

T.Baumbach schrieb:

> Ich brauche 16 Taster, aber immer nur einer gedrückt, nie zwei oder
> mehrere zusammen!
> Wenn immer nur einer gedrückt wird dann ist es doch egal wieviele Taster
> ich habe - oder? Ich meine hinsichtlich Stromaufnahme.

Nein.

Das Problem ist, zuverlässig zu unterscheiden, welcher Taster nun 
gedrückt ist. Das wird umso schwerer, je mehr Taster es sind, denn damit 
werden logischerweise die zu messenden Unterschiede immer kleiner. Diese 
Unterscheide müssen aber immer deutlich größer bleiben als das Rauschen. 
Das führt dazu, daß man die Tasterschaltung umso niederohmiger auslegen 
muß, je mehr Taster zu erfassen sind. Geringere Widerstände ziehen aber 
leider auch höhere Ströme nach sich.
Und hier kommt bezüglich der Aufwachfunktion noch hinzu, daß sie den für 
die Tasterwerte verfügbaren Messbereich etwa halbiert, was das Problem 
weiter verschärft.

Also bei 16 Tastern mit Aufweckfunktion würde ich mich ganz klar pro 
Matrix und kontra ADC entscheiden. Das spart einen Haufen Ärger.

von c-hater (Gast)


Lesenswert?

T.Baumbach schrieb:

> der ADC selber braucht ja auch Strom. Kann ich denn den ADC erst
> einschalten lassen, wenn ich den Mikrocontroller aufgeweckt habe?

Das machst du automatisch, wenn du den µC in den Tiefschlaf schickst, 
damit hältst du sämtliche Takte an, auch den des ADC.

> Ich weiß aber nicht wie ich die Schaltung erstellen muss, um den
> Interrupt an einem Pin auszulösen, der den Mikrocontroller aufweckt.

Da brauchst du keine extra Schaltung für zu erstellen, sondern bloß 
Software.

Im Minumum eine leere ISR für den verwendeten PCINT-Interrupt und den 
Code zur Aktivierung des PCINT für den gewünschten Pin (ADC-Tastatur) 
bzw. für die Eingangs-Pins der Matrix im Falle einer Matrixtastatur.

Bei der Matrix ist noch eine Vorkehrung mehr nötig, hier muß direkt vor 
dem Einschlafen das normale Multiplexing zur Abfrage stillgelegt und 
durch einen konstanten "aktiven" Pegel auf allen angesteuerten Leitungen 
der Matrix ersetzt werden. Dementsprechend muß dann beim Aufwachen die 
Sache wieder in den Normalzustand zurückversetzt werden. Dafür bietet 
sich dann die (ansonsten ja völlig ungenutzte) ISR des PCINT an.

von T.Baumbach (Gast)


Lesenswert?

Hi c-hater,

danke nochmals. Ich denke dann werde ich wohl eher mit der 4x4 Matrix 
arbeiten.
Habe dazu folgendes gefunden (leider erst jetzt ;-)):

http://www.atmel.com/Images/doc1232.pdf

Werde mich da mal ranwagen ;-)

Danke nochmals an all hier!

von T.Baumbach (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

habe mir die Schaltung die Atmel vorschlägt gerade mal angesehen.
Die Widerstande R1-R4 sind doppelt in der Zeichnung.
Einmal links an den Dioden (siehe rote Umrahmung) und einmal in den 
Widerständen an den Portpins PB7-PB4.

PB7-PB4 sind 470 Ohm, aber wie muss ich die vier Widerstände an den 
Dioden dimensionieren?

Die sollen den Interrupt-Pin PD2 auf low ziehen um den Mikrocontroller 
aufzuwecken.

Danke für Eure Hilfe!

von m.n. (Gast)


Lesenswert?

c-hater schrieb:
> Also bei 16 Tastern mit Aufweckfunktion würde ich mich ganz klar pro
> Matrix und kontra ADC entscheiden. Das spart einen Haufen Ärger.

Nur unter uns und nichts für Anfänger: wenn ich es bräuchte, wäre ich 
mutig und würde es auch bei 16 Tastern mit ADC machen.
Ein Pullup 100k || 10nF von ADCx nach Vref (bzw. VCC) und dann eine 
Reihenschaltung von 16 x 10k Widerständen, wobei jeder 4.-5. Abgriff mit 
100nF nach ADCx die Aufweckfunktion ermöglicht. Alle Taster schalten 
gegen GND; die Schaltung selbst kannst Du sicherlich im Kopf 
nachvollziehen.

Bezogen auf einen 10Bit-ADC ergeben sich rein rechnerisch folgende Werte 
für die einzelnen Taster:
 1-8:  93, 170, 236, 292, 341, 383, 421, 455
9-16: 485, 512, 536, 558, 578, 597, 614, 640

Die kleinste Änderung ergibt sich am Ende der Tabelle und beträgt 16 
Schritte (640-614), was 2,5% entspricht. Mit einer 1% Widerstandskette 
läßt sich hinreichende Genauigkeit erreichen, wobei sich das 
Toleranzband durch 4 x 22k Widerstände am Ende noch vergrößern ließe.
Eine fertige Tabelle (ggf. auch mit nur 8 Bit), die die Schwellwerte 
zwischen den Stufen enthält, erleichtert die schnelle Auswertung.

Wie gesagt, nichts für Anfänger aber machbar, wenn nur ein freier 
ADC-Eingang zur Verfügung steht.

von T.Baumbach (Gast)


Lesenswert?

Hi c-hater,

danke für Deine Mühe. Aber da ich mich eher zu den Anfänger zähle, fange 
ich wohl besser mit der Matrix-Lösung an.
Wer kann mir denn nun sagen, wie ich die 4 Widerstände an den Dioden 
dimensionieren muss?

von T.Baumbach (Gast)


Lesenswert?

Hi c-hater,

rein interessehalber und um deine Schaltung mit ADC und 16 Tastern zu 
verstehen wie wird denn da die Aufweckfunktion realisiert?
Brauche ich da einen zusätzlichen Interrupt Pin oder wird der 
Mikrocontroller durch eine Tastendruck (eine der 16 Tasten) am ADC 
aufgeweckt?
Wenn das so ist hiße das doch, dass der ADC laufen muss und strom 
verbraucht - oder?
Wäre meine Idee nicht sinnvoller den Mikrocontroller in den SleepMode zu 
versetzen, also auch der ADC ist komplett abgeschaltet. Ein Tastendruck 
(auf irgendeine der 16 Tasten) würde den Mikrocontroller aufwecken und 
in der Interuptroutine den ADC starten der dann den Taster auswertet?

Wie sieht denn dann die Schaltung aus? Also wie sorgt man dafür dass 
beim Drücken einer Taste der Interruptpin auf low gezogen wird und 
gleichzeitig der entsprechende Widerstandswert am ADC-Pin anliegt?

Danke nochmal!

von c-hater (Gast)


Lesenswert?

T.Baumbach schrieb:

> habe mir die Schaltung die Atmel vorschlägt gerade mal angesehen.

Die ist Mist (im Sinne von: für einen modernen AVR unnötig aufwendig).

Bei einem modernen AVR brauchst du für eine Tastenmatrix mit 
Aufweck-Funktionalität exakt garkeine Bauelemente (außer den Tastern 
selber natürlich). Alles andere wird per Software und mit Hilfe der in 
den AVR bereits eingebauten Hardware erledigt.

Für eine 4x4 Matrix nimmst du z.B. einfach alle 8 Pins eines Ports, 
sagen wir mal den PortA eines Tiny26. Nehmen wir an, die 
Spaltenleitungen der Matrix hängen an PA0..3 und die Zeilenleitungen an 
PA4..7. Wobei Spalten und Zeilen nur eine Frage der Definition sind, 
prinzipiell sind die natürlich austauschbar.

Wie auch immer, die Spalten-Pins, also PA0..3, programmierst du als 
Eingang mit aktivem Pullup. Die werden später im Normalbetrieb gelesen 
und es sind auch die Pins, die das Wecken auslösen werden. Nach der 
Initialisierung liest du an allen vier Pins erstmal dauerhaft High, also 
eins, weil die Pullups sie an Vcc legen.
Die Zeilen-Pins, also PA4..7, programmierst du auch erstmal als 
Eingänge, allerdings ohne Pullup. Sie sind also hochohmig, machen 
erstmal garnix.

Das normale Auslesen der Matrix funktioniert nun so: Eine der 
Leitungen PA4..7 wird als Ausgang umprogrammiert. Der entsprechende Pin 
liegt dadurch auf Low. Wenn nun in der Matrix irgendeine (oder auch 
mehrere) der vier Tasten gedrückt sind, die an der entsprechenden Zeile 
hängen, wird an den mit den Tasten korrespondierenden Spaltenanschlüssen 
der Pegel von High auf Low gezogen. Du brauchst also bloß PA0..3 zu 
lesen und kennst den Status der ersten vier Tasten der Matrix, jedes 
gelesene 0-Bit entspricht der Tatsache, daß die zugehörige Taste 
gedrückt ist. Nun merkst du dir die gelesene Zeile.
Nun willst du auch noch den Status der anderen Tasten wissen. Nichts 
einfacher als das. Die zuvor auf Ausgang geschaltete Zeilenleitung wird 
wieder auf Eingang (also hochohmig) geschaltet und die nächste wird auf 
Ausgang geschaltet. Damit kannst du dann wieder PA0..3 lesen, die 
diesmal den Zustand der Taster der zweiten Zeile wiederspiegeln.
Das Verfahren setzt du jetzt analog fort, bis du alle Zeilen durch hast. 
Damit hast du jetzt den Zustand aller 16 Tasten gelesen.

Nun kommt das beliebte Entprellen. Das realisiert man dadurch, da man 
oben beschriebene Operation für jede Zeile in der ISR eines geeignet 
konfigurierten Timers laufen läßt und sich immer zwei Sätze von 
Tastenstati merkt, das zuletzt vollständig gelesene und das aktuelle. 
Ist auch das aktuelle vollständig, geht man an's Vergleichen der beiden 
Datensätze, wurde zweimal hintereinander der gleiche Zustand für eine 
Taste
gelesen, wird der wohl gültig sein und kann akzeptiert werden. Will man 
daraus noch ein Ereignis generieren, im Sinne von "Taste(n) haben sich 
geändert", nimmt man einfach noch einen dritten Datensatz zu Hilfe und 
vergleicht den mit den als gültig erkannten Zuständen, gibt es 
Unterschiede, hat sich der Zustand mindestens einer Taste geändert.

So, nun gehst du schlafen. Das machst du, indem du alle Zeilenleitungen 
auf Ausgang programmierst, für die vier Spaltenleitung den 
PCINT-Interrupt aktivierst und dann sleep ausführst. Das Teil schläft 
jetzt ein.
Vorsicht: Oft ist es nötig, weitere Maßnahmen zu treffen, bevor man 
einschlafen kann. Leuchtet da z.B. noch irgendeine LED, wird sich der 
Stromspareffekt des Schlafmodus in Grenzen halten...

Bleiben wir aber bei der Tastatur: Wird jetzt irgendeine Taste der 
Matrix gedrückt, ändert irgendeine Spaltenleitung ihren Zustand von 
High auf Low. Tritt nun so ein Pegelwechsel ein, wacht das Teil wieder 
auf und durchläuft als erstes die ISR des PCINT-Interrupt. Dort 
deaktivierst du den PCINT-Interrupt und setzt alle Zeilenleitungen 
wieder auf Eingang (also hochohmig=inaktiv). Der nächste Interrupt des 
Polltimers wird dann wieder eine davon auf Ausgang legen und alles geht 
wieder seinen normalen Gang. Maximal für einen Abfragezyklus ergeben 
sich falsche Tastenwerte für eine Zeile, das bügelt aber die Entprellung 
weg.

Was bleibt ist die zum Aufwachen verwendete Taste. Die kann man garnicht 
so schnell wieder loslassen, daß die normale Tastaturabfrage nicht 
mitbekommen würde, daß sie gedrückt und wieder losgelassen wurde. Um 
dieses Problem muß sich deine Software selber kümmern, das erledigt die 
normale Entprellung nicht mit.

von T.Baumbach (Gast)


Lesenswert?

Hi c-hater,

wow, danke für die ausführliche Info und deine Mühe!
Dann wird meine Schaltung ja wesentlich einfacher. Hoffe dass ich den 
C-Code hinbekomme.
Dann mache ich mich mal an die Arbeit, leider ist das Wochenende nun 
schon rum, werde es wohl auf nächste Woche verschieben. Mache mir dazu 
eine Platine (mit Target 3001) und ätze die dann...

Nochmal vielen lieben Dank!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.