Pfad: Home => AVR_DE => Anwendungen => Schalter und Tasten am ADC => Tasten
Tasten mit Widerstaenden Anwendungen von
AVR-Einchip-Prozessoren AT90S, ATtiny, ATmega and ATxmega
Tasten und Widerstände an einem AD-Wandler-Eingang
Logo

Tasten an einem AD-Wandler-Kanal


1 Tasten und Widerstände

Wenn es die Hardware erforderlich macht, zwei oder mehr Tasten an den AVR anzuschließen und zu erkennen, ob eine (und welche) der Tasten gedrückt ist, kann man das natürlich mit einem Portpin machen, indem man dessen internen Pull-Up-Widerstand im Port PORTn einschaltet und regelmäßig PINn abfragt, ob der Taster diesen Eingang auf logisch Low zieht. Hat man viele solche Tasten, ist das Verfahren aber mühsam und verbraucht unnötig Portpins.

Aber man kann das auch anders und mit nur einem einzigen Pin lösen: man muss nur dafür sorgen, dass jeder Tastendruck eine bestimmte Spannung erzeugt, man kann diese Spannung mit einem AD-Wandler messen und daraus auf die gedrückte Taste schließen. Der AD-Wandler braucht nur einen einzigen ADC-Pin.

Zwei verschiedene Schaltungen sind möglich, die sich nur in der Spannungsberechnung unterscheiden.

1.1 Tasten mit Spannungsteiler mit Einzelwiderständen

Tasten mit Einzelwiderstand Wenn keine Taste gedrückt ist, ist die resultierende Spannung Null. Bei dieser Schaltung erzeugt jeder Tastendruck einen Spannungsteiler, bei dem die Spannung U folgendermaßen ist:
Un = Ubetrieb * R0 / (R0 + Rn)

Die Widerstände R1 bis RN müssen natürlich unterschiedlich sein, damit unterschiedliche Spannungen herauskommen. Und sie sollten so gewählt werden, dass sich so weit wie möglich unterschiedliche Spannungen ergeben.

1.2 Tasten mit gestapelten Widerständen

Gestapelte Tasten Das ist die zweite Möglichkeit: alle Widerstände sind gestapelt. Auch hier ist die Spannung ohne gedrückte Taste Null. Wird die Taste n gedrückt, ist der Widerstand nach Plus (bei N Tasten):
Rplus = Rn + Rn+1 + ... + RN-1



und die Spannung am AD-Wandler ist
UADC = Ubetrieb * R0 / (R0 + Rn + Rn+1 + ... + RN-1)

Der Unterschied zu der ersten Schaltung ist also, dass sich die Widerstände addieren.

Das Ergebnis der AD-Wandlung kann zwischen 0 und 1.023 liegen (10-Bit-ADC) oder auch zwischen 0 und 255 (8-Bit-ADC, ADLAR-Bit gesetzt und MSB des Ergebnisses).

Man kann natürlich eine wilde Mischung von Widerständen nehmen, das AD-Wandler-Ergebnis auslesen und in eine Tabelle schreiben. Einfacher ist es aber die Ergebnisse vorauszuberechnen und unabhängig von Exemplarstreuungen zu werden.

2 Algorithmus für die Auswahl von Widerständen

Um zwischen den Einzeltasten möglichst große Spannungsdifferenzen hinzukriegen, verteilt man die Spannungen gleichmäßig über den gesamten Spannungsbereich. Bei zwei Tasten ist das das 0,5- und das 1,0-fache der Betriebsspannung, bei drei Tasten 0,33, 0,66 und 1,0. Wenn 10 Tasten angeschlossen werden sollen, lautet die Spannungsreihe 0,1, 0,2, usw. bis 1,0.

Unglücklicherweise halten reale Widerstände nur im Ausnahmefall den aufgedruckten Wert genau ein. Alles was noch innerhalb der ebenfalls aufgedruckten Toleranz liegt (+/-5% für Kohleschichtwiderstände, +/-1% für Metallfilmwiderstände) kann dabei sein. Daher ergibt sich für die resultierende Spannung ein Spannungsbereich. Dieser überspannt Darüber hinaus gibt es Widerstandswerte nur in genormten Reihen. Erhältlich im Elektronikhandel sind die E12-Reihe (12 Widerstandswerte pro Dekade) und die E24-Reihe. Rein theoretisch gibt es auch die E48- und E96-Reihen, aber an die kommt man als Normalsterblicher rein gar nicht ran.

Aus allen genannten Spezialbedingungen ist es nicht ratsam, die Lösung der Aufgabe mit Lineargleichungen zu versuchen. Stattdessen kann man so vorgehen,
  1. mit einer Anfangskombination von Widerständen zu beginnen, dann
  2. nacheinander jeweils einen Widerstand auszuwählen und zu schauen, ob der nächsthöhere und der nächstniedrige Wert zu einer besseren Annäherung an die Sollspannung führt.
Durch diese immer bessere Annäherung an die Sollspannung verringert sich auch die Anzahl an Überlappungen zwischen dem oberen Spannungsbereich der Taste und dem unteren Spannungsbereich der nächsthöheren Taste. Wenn durch die Näherung die Anzahl an Überlappungen nicht auf Null zu kriegen ist, kann man es mit 2%-igen oder 1%-igen Widerständen versuchen oder zu E24 übergehen.

3 Software zur optimierten Widerstandsauswahl

Nkey zu Beginn Die Software gibt es für das Windows-Betriebssystem bzw. für Wine unter Linux als ausführbare Datei (906 kB gezippt, 2,82 MB entpackt).

Zu Beginn sind zwei Tasten ausgewählt und kann mit dem Ausklappfeld an den eigenen Bedarf angepasst werden. Auch die anderen Auswahlfelder können verwendet werden, um die Einstellungen zu ändern und mit der Näherung von vorne zu beginnen.

Die Näherung kann Schritt für Schritt und mit 100 Schritten auf einmal durchgeführt werden. Verringert sich die Summe der Abstände nicht mehr, haben sich keine erfolgreichen Näherungsschritte ergeben. Dann kann man durch Neustart einen verbesserten Lauf versuchen.

Die Ergebnisse der Näherung kann man im Widerstandsfenster beobachten, das die derzeit angewendete Widerstandskombination anzeigt. Wenn sich bei einer Näherung keine Änderung ergibt, war die Differenz nicht kleiner geworden. Da die Auswahl des variierten Widerstands zufällig erfolgt, können einzelne Läufe durchaus in anderen Werten resultieren. Die Tabelle im unteren Bereich des Programmfensters zeigt die Spannungen in mV und die ADC-Werte in der gewählten Auflösung an.

Tabellenwerte Klickt man auf den Knopf "Source code" wird eine Assembler-Tabelle erzeugt, die den Minimumwert und das (Maximum + 1) für die einzelnen Tasten angibt. Diese Tabelle kann als Include-Datei gespeichert oder in die Zwischenablage kopiert werden.

Die Einträge in der Tabelle bedeuten:
  1. Liegt das ADC-Ergebnis unter dem ersten Tabellenwert, ist keine Taste gedrückt.
  2. Ist das Ergebnis größer oder gleich dem ersten Tabellenwert und kleiner als der zweite Tabellenwert, dann ist die entsprechende Taste gedrückt.
  3. Ist das Ergebnis größer oder gleich dem zweiten Tabellenwert und kleiner als der erste Tabellenwert der nächsten Taste, dann liegt ein unzulässiger Spannungswert vor und die Messung ist zu verwerfen.
  4. Ist der erste ausgelesene Tabellenwert eine Null, dann ist die Tabelle zu Ende und die höchste Taste ist gedrückt.


10 Tasten gestapelt Wird der Knopf "Schematic" gedrückt dann öffnet sich ein Grafikfenster mit dem Schaltbild und der Widerstandsbemaßung. Die Grafik kann im PNG- oder BMP-Format gespeichert werden wenn auf diese mit der Maus geklickt wird.

Die Widerstandswerte im gestapelten Format zeigen, dass alles andere als eine einfache lineare Funktion vorliegt.

4 Assembler Quellcode zur Identifikation gedrückter Tasten

Der folgende Beispielcode
  1. schaltet den AD-Multiplexer auf Kanal 0 und schaltet das ADLAR-Bit ein (8 Bit ADC),
  2. schaltet den ADC an und startet eine Wandlung,
  3. wartet bis die AD-Wandlung abgeschlossen ist,
  4. liest das Resultat ein und
  5. wandelt dieses in die entsprechende Taste.
Der Assembler-Quellcode (hier im Asm-Format) sieht so aus:

;
; ***********************************
; * Dekodiere Taste                 *
; * (C)2018 by avr-asm-tutorial.net *
; ***********************************
;
.Nolist
.include "tn13def.inc" ; ATtiny13
.list
;
; -----------------------
;     R E G I S T E R
; -----------------------
;
.def rAdcH = R14 ; MSB ADC-Ergebnis
.def rTab = R15 ; Taste Tabellenwert
.def rmp = R16 ; Vielzweckregister
; Benutzt: Z = R31:R30 fuer LPM
;
Start:
  ; Eine AD-Wandlung im Kanal 0 starten
  ldi rmp,1<<ADLAR ; Links-Justieren, Kanal = 0
  out ADMUX,rmp
  ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
  out ADCSRA,rmp ; Starte ADC und Wandlung
WaitAdc:
  sbic ADCSRA,ADSC ; Warte bis Wandlung fertig
  rjmp WaitAdc ; Warte weiter
  in rAdcH,ADCH ; Lese MSB
  ; Wandle ADC-Wert in gedrueckte Taste
  ldi ZH,High(2*Keytab) ; Zeige Z auf Tastenwerte in Tabelle
  ldi ZL,Low(2*Keytab)
  clr rTab ; Keine Taste gedrueckt?
IdentifyKey:
  lpm rmp,Z+ ; Lese erstes Byte aus Tabelle
  tst rmp ; Letztes Byte der Tabelle?
  breq KeyNIdentified
  cp rAdcH,rmp ; Vergleiche ADC-Wert mit erstem Tabellenwert
  brcs KeyUnderflow ; ADC value below
  inc rTab ; Naechste Taste
  lpm rmp,Z+ ; Lese obere Grenze des Tabellenwerts
  cp rAdcH,rmp ; Vergleiche mit oberer Grenze
  brcs KeyIdentified ; Taste gefunden
  rjmp IdentifyKey ; Tabelle weiter abarbeiten
;
KeyNIdentified:
  inc rTab ; Taste = N
  rjmp KeyIdentified
;
; Keine Taste gedrueckt oder illegale Spannung
KeyUnderflow:
  tst rTab ; Taste = 0?
  breq KeyIdentified ;  Keine Taste gedrueckt
  clr rmp
  dec rmp ; Unzulaessige Spannung, rmp = 0xFF
;
KeyIdentified:
  ; Tastennummer ist in rTab
  rjmp KeyIdentified ; Unendliche Schleife
;
; Include der Tabelle
;
.include "tasten10_einzeln.inc" ; Include Tastentabelle
;

Die eingelesene Tabelle, die mit der Software erzeugt wurde, sieht folgendermaßen aus (hier als Quellcode-Include):

;
; Table for recognizing pressed keys
;   10 keys, ADC resolution = 256
;   R0 = 1k
;
KeyTab:
.db 25,31 ; Key=1, R1=8k2
.db 48,57 ; Key=2, R2=3k9
.db 74,86 ; Key=3, R3=2k2
.db 96,109 ; Key=4, R4=1k5
.db 121,135 ; Key=5, R5=1k
.db 146,159 ; Key=6, R6=680
.db 178,189 ; Key=7, R7=390
.db 197,206 ; Key=8, R8=270
.db 225,231 ; Key=9, R9=120
.db 0,0 ; No more keys
;

Beim Simulieren der Programmausführung mit avr_sim zeigen sich die folgenden Ergebnisse.

ADC-Wandlung gestarted Die Wandlung wurde mit einer Analogspannung von 2,5 V gestartet. Sie braucht etwas Zeit weil der ADC-Takt herabgesetzt ist.

ADC-Resultat gelesen Das Ergebnis der Wandlung, 0x7F oder 127 dezimal, wurde in das Register rAdcH in R14 eingelesen.

Taste gefunden Nach Ausführung der Wandlung findet der Assembler-Code, dass Taste 5 gedrückt ist (in rTab oder R15).

©2018 by http://www.avr-asm-tutorial.net