Kapazitiver
Berührungsschalter mit der Pingpong-Platine
Einfach
eine Glasfläche oder ein Display mit dem Finger
berühren und
damit etwas steuern, das liegt jetzt voll im Trend. Man findet diese
Technik in allen möglichen Geräten vom PC bis zum
Smartphone.
Dahinter stecken meist kapazitive Sensoren. Atmel
hat die Qtouch-Technologie von Quantum gekauft und bietet z.B. den
QT113A für eine kapazitive Schaltfläche an. Eine
Anwendung
des ICs findet man in Elektor 7/8/2010. Außerdem stellt Atmel
eine komplette und kostenlose C-Bibliothek für AVR-Controller
zur
Verfügung, mit der man kapazitive Schalter, Slider und
Drehknöpfe realisieren kann. Man braucht jeweils zwei ganz
normale
Ports, einen Kondensator und eine isolierte Metallfläche. Zur
Vermeidung von Funkstörungen sollte noch ein Widerstand
verwendet
werden.
Aber
kann man das z.B. auch in Bascom machen? Dazu habe ich zuerst einmal
das Arbeitsprinzip untersucht. An den Portpins sieht man eine Serie
schneller Schaltimpulse, die den Kondensator allmählich
aufladen.
Das
Bild zeigt die Aktion der Ports in vier Phasen, die sich immer
wiederholen. Wie man sieht, liegt der Kondensator niemals gleichzeitig
an GND und VCC. Er dürfte sich deshalb bis in alle Ewigkeit
nicht
aufladen.
Aber
jetzt kommt der kleine Kondensator Cx der Schaltfläche hinzu.
In
der Phase 2 liegen beide Kondensatoren in Reihe an VCC und GND. Bei 10
pF und 10 nF würde sich der große Kondensator zwar
nur um
ein Tausendstel der Spannung des kleinen Kondensators aufladen, aber
die vielen kleinen Schritte addieren sich schließlich zu
einer
Spannung die bei ihrer Auswertung in Phase 4 die
Eingangs-Schaltspannung des Ports erreicht. Bei 10 pF würde
man
z.B. 500 Zyklen brauchen, bei 20 pF nur 250 Zyklen.
Hier eine Lösung für Bascom und die Pingpong-Platine:
Download: Touch2.zip
$crystal = 8000000
$regfile = "m8def.dat"
$hwstack = 64
$swstack = 64
$framesize = 64
Dim D As Integer
Open "comb.4:9600,8,n,1,inverted" For Output As #1
Open "comb.5:9600,8,n,1,inverted" For Input As #2
Ddrc.4 = 1
Ddrc.5 = 1
Portc = 0
Print #1 , "Touch"
Do
D = 0
'Do
' D = D + 1
For D = 1 To 500
Ddrc.4 = 0 'C4 hochohmig
Portc.5 = 1 'C5 high
Ddrc.5 = 1 'C5 niederohmig
If Pinc.4 = 0 Then Exit For 'C4 low?
Ddrc.5 = 0 'C5 hochohmig
Portc.5 = 0 'ohne Pullup
Ddrc.4 = 1
Next D 'C4 low
'Loop
Portc.4 = 0
Portc.5 = 0
Ddrc.4 = 1
Ddrc.5 = 1
Print #1 , D
Waitms 500
Loop
End
Ein
Kondensator mit 10 nF wird direkt an den freien Ports C4 und C5
angeschlossen. Der Kondensator bildet in diesem Versuch zugleich die
Sensorfläche. Man berührt also die Isolierung des
Scheibenkondensators. Ohne Berührung zeigt das Programm
zuverlässig und konstant z.B. 454 Ladezyklen.
Jetzt
soll der Sensor das LED-Display schalten. Man muss dazu
während
der Sensorabfrage den Interrupt sperren. Außerdem wurde eine
automatische Anpassung der Schaltschwelle eingebaut.
Download Touch4.zip
$crystal = 8000000
$regfile = "m8def.dat"
$hwstack = 64
$swstack = 64
$framesize = 64
Dim Leds(12) As Word
Dim X As Byte
Dim Y As Byte
Dim N As Word
Dim D As Word
Dim Dmax As Word
Dim Dx As Word
Declare Sub Standby
Declare Sub Test
Declare Sub Initialisierung
Declare Sub Led1(byval X As Byte , Byval Y As Byte)
Declare Sub Led0(byval X As Byte , Byval Y As Byte)
Initialisierung
Do
D = 0
Disable Interrupts
Portc.4 = 0
Portc.5 = 0
Ddrc.4 = 1
Ddrc.5 = 1
For D = 1 To 500
Ddrc.4 = 0 'C4 hochohmig
Portc.5 = 1 'C5 high
Ddrc.5 = 1 'C5 niederohmig
If Pinc.4 = 0 Then Exit For 'C4 low?
Ddrc.5 = 0 'C5 hochohmig
Portc.5 = 0 'ohne Pullup
Ddrc.4 = 1
Next D 'C4 low
Portc.4 = 0
Portc.5 = 0
Ddrc.4 = 1
Ddrc.5 = 1
Enable Interrupts
If D > Dmax Then Dmax = D
Dx = Dmax - 30
If D < Dx Then
For N = 1 To 12
Leds(n) = 255
Next N
Waitms 1000 'LED an
Else
For N = 1 To 12
Leds(n) = 0
Next N 'LED an
End If
Waitms 10
Loop
Ein
Test mit einer zusätzlichen Metallfolie als
Sensorfläche
zeigt, dass die Touch-Funktion durch das Kartongehäuse des
Pingpong-Spiels hindurch funktioniert.
Eine Version des Programms für den ATtiny13:
'Kapazitiver Touch-Sensor
'1,5 nF zwischen B3 und B4
'Sensorplatte an B4
'LED mit 1 k an B1
$regfile = "attiny13.dat"
$crystal = 1200000
Dim D As Integer
Ddrb.1 = 1
Do
D = 0
'Do
' D = D + 1
For D = 1 To 1500
Ddrb.3 = 0 'B3 hochohmig
Portb.4 = 1 'B4 high
Ddrb.4 = 1 'B4 niederohmig
If Pinb.3 = 0 Then Exit For 'B3 low?
Ddrb.4 = 0 'B4 hochohmig
Portb.4 = 0 'ohne Pullup
Ddrb.3 = 1 'B3 low
Next D
'Loop
Portb.3 = 0
Portb.4 = 0
Ddrb.3 = 1
Ddrb.4 = 1
If D < 30 Then
Portb.1 = 1
Else
Portb.1 = 0
End If
Waitms 50
Loop
End
Download: CAPsensor.zip
Kapazitiver Sensor für die Modellbahn von Marcus Gedanitz
Die
Schaltung mit dem Tiny13 funktionierte auf Anhieb. Gleich habe ich
weitere Anwendungsmöglichkeiten ausprobiert, als da wären:
Gleisfreimeldeanlage für die Modellbahn.
Dazu
habe ich einen Draht in das Gleis gelegt, und siehe da, der Tiny
reagiert auf ein Fahrzeug. Dabei ist es völlig egal, ob das Fahrzeug
Kunststoff oder Metallachsen besitzt. Es ist nämlich so, dass viele
Modellbahner keine Veränderung wie Magnete, oder Widerstandsachsen
an ihren Fahrzeugen verbauen möchten.
Das ganze funktioniert,
aber es funktioniert nicht zuverlässig genug. Ok, die Sache war dafür
ja auch nicht gedacht. Nun, da ich das heruntergeladene HEX File dazu
verwendet habe, wollte ich in dem Basic Programm etwas herumspielen.
Dazu habe ich mir die original BAS Datei in mein Bascom Demo geladen.
Nachdem ich den Wert der Wenn Dann Abfrage der Variable D geringfügig
verändert habe, wollte ich ein neues HEX File erstellen, und erhalte
folgende Fehlermeldung: Error : 22 Line : 42 Out of SRAM Space ,
in File: Pfad Dateiname
Hinweis zum Kompilieren:
Es liegt an den Stack-Speichereinstellungen, die vielleicht für einen
anderen Controller größer eingestellt waren. In bin inzwischen dazu
übergegangen, die passenden Einstellungen gleich in den Quelltext
zu schreiben:
$regfile = "attiny13.dat"
$crystal = 1200000
$hwstack = 8
$swstack = 4
$framesize = 4
Hinweis zum Sensor: Erstaunlich, dass so ein kurzer Draht gereicht hat. Mit etwas mehr Fläche müsste es noch besser gehen.
Schreibtischlampe mit Touchsensor von Marcus Gedanitz
Der Touchsensor lässt mir einfach keine Ruhe. So habe ich versucht
ihm eine sinnvolle Aufgabe zu geben. Herausgekommen ist dabei eine
Schreibtischlampe mit Touchsensor. Doch vorerst musste ich das
Bascom-Programm auf meine Bedürfnisse anpassen. Die Lampe soll bei
einer Berührung einschalten, und bei der nächsten Berührung wieder
ausschalten.
Programmschnipsel Ursprung:
If D < 30 Then
Portb.1 = 1
Else
Portb.1 = 0
End If
Programmschnipsel Änderung:
If D < 35 Then
Toggle Portb.1
Wait 2
Else
End If
Dies
geht sicher auch eleganter, nur war dies für mich die einfachste
Lösung. Mit den Befehlen Bitwait, Reset bin ich leider nicht
weitergekommen. Hauptsache es funktioniert.
Die
Schaltung habe ich auf einem Rest Punkt- Streifenraster so eng wie nur
irgendwie möglich aufgebaut. Diese Finder Relais passen vom Rastermaß
leider in keiner Position. So habe ich es mit Heißkleber auf die
Platine montiert. Dort wo ursprünglich der Schalter der Lampe gesessen
hat, klemmt nun ein genau zurechtgefeiltes Stück Platinenmaterial,
welches die Sensorfläche bildet.
Der
Nachteil der Schaltung ist, dass der Trafo nun leider unter
Dauerspannung steht. Da kommt schnell die Idee auf, den Steuerteil über
ein Kondensatornetzteil zu versorgen. Davon rate ich ab. Mit
Netzspannung ist nicht zu spaßen. Je nachdem wie rum der Stecker
steckt, trennen nur die 1,6mm stärke der Sensorplatine die
Netzspannung vom Finger. Man stelle sich vor, ein Kind hat nasse Hände,
und ein Tropfen Wasser krabbelt in einen kleinen Ritz zwischen Gehäuse
und Sensorplatine. Das ist ein Kondensatornetzteil niemals wert.
Touch-Sensor mit nur einem Port
Software für die Pingpong-Platine:
'Touch1, Sensorfläche an PC.4
'LED an PC.5
$crystal = 8000000
$regfile = "m8def.dat"
$hwstack = 32
$swstack = 8
$framesize = 24
Config Portc = Output
Do
Ddrc.4 = 1 'entladen
Portc.4 = 0
Ddrc.4 = 0 'hochohmig
Portc.4 = 1 'pullup
If Pinc.4 = 1 Then 'schon high?
Portc.5 = 0
Else
Portc.5 = 1 'LED an
End If
Ddrc.4 = 1
Portc.4 = 0 'wieder entladen
Waitms 10
Loop
End