Forum: Projekte & Code 4-wire resistive Touchscreen Schaltung TWI USART-Anbindung ATmega8 Assembler LS-7 LS-8


von Bernhard S. (bernhard)



Lesenswert?

Eine mögliche Variante, wie ein resistiver Touch abgefragt werden kann.

Das vorhandene LCD-Display zeigt für Testzwecke die ermittelten 
Koordinaten an.


Dieser Beitrag animierte mich:
Beitrag "Display-Set LS-8 Touchscreen allgemeine Fragen + Probleme"

Das kleine Assembler-Programm stellt die X-Y-Koordinaten im Bereich von 
0...1000 zur Verfügung.

Die Koordinaten sind somit unabhängig vom verwendeten Display, kann aber 
bei Bedarf durch eine Berechnung oder durch eine hinterlegte Tabelle 
angepasst werden.

Links unten ist X/Y=0;0, rechts oben 1000;1000

Die Genauigkeit der Koordinaten ist nach meiner Meinung recht gut, wobei 
ich noch keine Erfahrung mit dieser Hard- und Software sammeln konnte.

Einen Kugelschreiber drückte ich bei den Genauigkeits-Versuchen immer an 
die gleiche Stelle.


Das Prinzip :

- Im Standby-Modus wird eine Schicht auf GND gezogen, der andere Schicht 
auf Betriebsspannung, die internen Pull-UPs sorgen für das entsprechende 
Betriebsspannungs-Potential.

- Beim drücken des Touchs verändert sich die Spannung der mit den 
PULL-UPs versorgten Schicht und erst jetzt beginnt die Exaktmessung und 
Probleme lassen nicht lange auf sich warten.

- Bei der stromfressende Exaktmessung wird ein PIN einer Schicht gegen 
GND gezogen, der andere auf nahezu Betriebsspannung (abhängig vom 
Innenwiderstand des µC-Ausganges.

-Die andere Schicht schalten wir an an beiden Elektroden hochohmig und 
messen dann die anliegende Spannung an diesen Elektroden.

-Anschließend wiederholen wir diesen Vorgang, tauschen aber vorher 
softwaremäßig die Schichten


Probleme :

Das ganze System muss angemessen entprellt werden !


Beim geringsten Antippen des Touchs sollte nicht gleich eine Aktion 
durchgeführt werden.

Lässt sich einstellen durch:

.equ TOUCH_ENTPRELLZEIT_ANTIPPEN  =35     ;(1=1ms)


Auch beim Loslassen des Touchs sollte aufs Entprellen nicht verzichtet 
werden, sonst meldet ev. das System eine weitere ungewollte 
Toch-Betätigung.


Lässt sich einstellen durch:

.equ TOUCH_ENTPRELLZEIT_LOSLASSEN  =100     ;(1=1ms)



Probleme gab es auch mit der relativ hohen Kapazität zwischen der X und 
Y-Schicht bzw. der Schichten zum Gehäuse ca. 10nF. Bei Umschalt- und 
Messvorgängen sind abgemessene Pausenzeiten nicht von Nachteil.


Das Mess-Prinzip und die Genauigkeit ist theoretisch unabhängig von der 
höhe der Betriebsspannung.

Und Software vorbereitet für 1MHz, 8Mhz und 16MHz.

Die ermittelten Koordinaten können per TWI, USART oder SPI zur Verfügung 
gestellt werden (ist aber in dieser Version noch nicht eingebunden).

Desweiteren meldet ein zusätzlicher PIN am AVR eine Touch-Aktivität, 
kann bei Bedarf genutzt werden.

Ein BEEP meldet eine erfolgreiche Touch-Betätigung.


Das System lässt sich auch in andere Systeme einbinden, da nur 2xADC für 
X+ und Y+ zur Verfügung stehen müssen.



X- und Y- können auf anere PINs umprogrammiert werden:

; TOUCH(X-)
.equ TOUCH_XN_PIN_NR        = 3
.equ TOUCH_XN_DDR          = DDRC
.equ TOUCH_XN_PORT          = PORTC
.equ TOUCH_XN_PIN          = PINC


Nach meiner Meinung ist ein Multi-Touch-Screen mit diesem Verfahren 
nicht möglich, oder?



Das Assembler-Programm könnte etwas effektiver programmiert werden.

Für Anregungen und konstruktive Hinweise bin ich sehr dankbar.


Bernhard

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bernhard S. schrieb:
> Nach meiner Meinung ist ein Multi-Touch-Screen mit diesem Verfahren
> nicht möglich, oder?

Das sehe ich auch so. Nicht nur deswegen sind resistive Touchscreens 
glücklicherweise am Aussterben.

von Robert W. (robwa)


Lesenswert?

Hallo Bernhard,

schön, dass Du in so kurzer Zeit zu diesem Ergebnis gekommen bist!

Eine kleine Anregung was Du evtl. noch ändern könntest hätte ich noch:
Bernhard S. schrieb:
> Das kleine Assembler-Programm stellt die X-Y-Koordinaten im Bereich von
> 0...1000 zur Verfügung.

statt 0..1000 könntest Du doch gleich die aktuelle Pixelposition 
zurückgeben. Du müsstest nur in der Initialisierung Deinen 
ADC-Messbereich (Maximumwert - Minimumwert) durch die Pixelanzahl des 
Displays dividieren und hättest dann den Messbereich für ein Pixel. Nach 
einer Messung brauchst Du den Messwert nur mehr durch den 
Pixel-Messbereich zu dividieren und hast die aktuelle Pixelposition. 
Damit lässt sich z.B. einfach ein kleines "Zeichenprogramm" 
programmieren, dass das gemessene Pixel am Display anders färbt. Damit 
hat man eine schnelle Rückmeldung wie genau die Touchauswertung 
funktioniert.

Robert.

von Thomas F. (igel)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Nicht nur deswegen sind resistive Touchscreens
> glücklicherweise am Aussterben.

Zum Leid des Bastlers.
Was täten wir denn den lieben langen Tag, wenn nicht Touch-Routinen für 
unsere Atmegas (und PICs) entwerfen und auf uC.net drüber diskutieren;-)

von Bernhard S. (bernhard)



Lesenswert?

Das ist der Spannungsverlauf an einer Schicht, wenn sie vom 
GND-Potential mit einem internen PULL-UP-Widerstand des ATmega8 gegen 
Betriebsspannung gezogen wird.

Die Spannung steigt nicht sprunghaft, deutlich ist eine e-Funktion 
erkennbar.

Während dieser "Aufladezeit" sollte eine Exaktmessung vermieden werden.


Im 2. Bild wird der PIN des µC zuerst auf Ausgang geschaltet, dann auf 
HIGH und anschließend der PULL-UP aktiviert, das geht natürlich 
schneller.


Diese Kapazitive Wirkung der Schichten hat natürlich nicht nur 
Nachteile, diese systembedingte Tiefpass-RC-Kombination mag der ADC des 
AVR.


@Robert
>statt 0..1000 könntest Du doch gleich die aktuelle Pixelposition
>zurückgeben.

Du hast mich überzeugt, ich werd's auch umsetzen. Danke für den Tipp.


Bernhard

von Thomas F. (igel)


Angehängte Dateien:

Lesenswert?

Hallo Bernhard,

du verwendest Warteschleifen zwischen den einzelnen Schritten der 
Abfrage.

Um keine Warteschleifen zu bekommen benutze ich eine Art Ablaufsteuerung 
für die einzelnen Schritte der Touch-Abfrage. Ein Timer-Irq löst dabei 
eine Abfrage aus, welcher Schritt als nächstes dran ist und dann wird zu 
diesem Programmteil gesprungen. Dort wird dann auch der Schrittzähler 
erhöht.

Den Ausschnitt aus meinem Code habe ich mal angehängt.

von Bernhard S. (bernhard)


Lesenswert?

@Thomas

>Um keine Warteschleifen zu bekommen benutze ich eine Art Ablaufsteuerung
>für die einzelnen Schritte der Touch-Abfrage.

Danke für Dein Beispiel. Die "Ablaufsteuerungs-Metode" ist eine sehr 
gute Variante, um unnötige Wartezeiten (Prozessorbelastungen) zu 
reduzieren.

Momentan schwebt mir noch folgende Lösungsvariante vor (um den 
Programmcode "einfach" zu halten, also ohne IRQ), daß in den 
"Wartezeiten" die X und Y Koordinatenumrechnung erfolgt.

Kann aber bei Bedarf sofort auf Deine "Ablaufsteuerungs-Metode" 
umgerubelt werden.


Bin mir noch nicht ganz sicher, wie die ADC-Messung erfolgen sollte, 
momentan messe ich 32x und bilde dann den Mittelwert.

Zumal liegt bei der "Exaktmessung" die eine Elektrode physikalisch 
gesehen nicht exakt auf GND und die andere nicht auf Betriebsspannung.

Dazu kommt noch, dass z.B. Temperatureinfüsse dafür sorgen, dass diese 
Potentiale wegdriften können.

Es könnte auch sein, dass elektromagnetischer Schmutz eine 
Messungenauigkeit verursachen könnte.

Bernhard

: Bearbeitet durch User
von Robert W. (robwa)


Lesenswert?

Hallo Bernhard,

in meinem Projekt habe ich die Messung und Kalibrierung folgendermaßen 
umgesetzt:
- Ich benutze eine XMega und habe das Touchpanel über vier Widerstände 
(R1..R4 aus Appnote AVR341, Fig. 2-4) angeschlossen und in c 
programmiert.
In einem Testdurchlauf habe ich die ADC- min- und max-Werte der x- und 
y-Koordinaten ermittelt.
- Die min-Werte habe ich etwas nach oben korrigiert und die max-Werte 
nach unten, dadurch ergibt sich ein leicht eingeschränkter Bereich. Der 
y-Bereich lag etwa zwischen 630 und 2560, daraus habe ich die Startwerte 
mit y_min=700 und y_max=2500 und Extremwerte mit y_extr_min=500 und 
y_extr_max=2700 festgelegt.
- Beim Start des µC wird der Messbereich mit den modifizierten min- und 
max-Werten initialisiert.
- Bei der ADC-Messung messe ich dzt. 5x und bilde den Mittelwert 
(schließe aber vorher "unplausible" Messwerte, die außerhalb der 
Extremwerte liegen, aus).
- Wenn der Mittelwert außerhalb des gespeicherten min- und max- 
Wertebereiches liegt, wird der jeweilige min- oder max-Wert 
überschrieben und der Messbereich neu berechnet. Dadurch kalibriert sich 
das Touchpanel von selbst indem man zwei diagonal gegenüberliegende 
Ecken berührt.
- Im Menü habe ich eine Reset-Funktion eingebaut, die die min- und 
max-Werte zurücksetzt, diese Funktion habe ich aber bis jetzt noch nicht 
benötigt.

Vielleicht hilft Dir das als Anregung.

Robert.

von Bernhard S. (bernhard)



Lesenswert?

Die Messungen an einem ATmega8 mit einer Beriebsspannung von 5,0V und 
einem Touchscrenn vom LS-8 lieferten folgende Ergebnisse:

Wird die niederohmigere horizontale Y-Schicht bestromt fließt ein Strom 
von ca. 14mA (311 Ohm).

Dieser Strom belastet die Ausgänge des µC, so dass "Y-" auf 0,3V liegt, 
wir erinnern uns, Y- sollte gegen GND gezogen werden.

Und Y+ liegt nicht auf 5,0V sondern dümpelt bei 4,68V herum.


Käme jetzt noch eine weitere Strombelastung dazu, wenn wir den TOUCH 
berühren und die internen PULL-UP-Widerstände des µC noch fleißig aktiv 
sind, provozieren wir noch eine Spannungsänderung an Y- und somit einen 
kleinen Messfehler (1Digit).


Bereits jetzt höre ich "na Du bist aber pingelig"....

Robert hat angefangen, er wollte die "...Rückmeldung wie genau die 
Touchauswertung funktioniert."

:-)




Bernhard

: Bearbeitet durch User
von Bernhard S. (bernhard)


Lesenswert?

Robert, danke für Deine Anregungen,

einiges möchte ich dazu noch hinterfragen.

> das Touchpanel über vier Widerstände (R1..R4 aus Appnote AVR341
> Fig. 2-4) angeschlossen

Wozu dienen diese Widerstände, welchen Zweck sollen sie erfüllen?


>Bei der ADC-Messung messe ich dzt. 5x und bilde den Mittelwert

Momentan messe ich 32x und bilde den Mittelwert. Die 32 ist der 
Tatsache geschuldet, da die Division durch 2, 4, 8, 16, 32 usw. in 
Assembler sich sehr einfach und mit wenigen kostbaren Prozessortakten 
realisieren lässt.

Folgende Variante zur ADC-Messung viel mir ein:

Ich messe z.B. 8x und bilde den Mittelwert und merke mir diesen Wert,
anschließend messe ich wieder 8x und bilde wieder den Mittelwert,
schlussendlich werden beide Mittelwerte miteinander verglichen,
sind sie gleich, dann ist alles schön, wenn nicht.... noch einmal messen 
und das Ergebnis mit dem letzten Mittelwert vergleichen.



Bernhard

von m.n. (Gast)


Lesenswert?

Bernhard S. schrieb:
> Ich messe z.B. 8x und bilde den Mittelwert und merke mir diesen Wert,
> anschließend messe ich wieder 8x und bilde wieder den Mittelwert,
> schlussendlich werden beide Mittelwerte miteinander verglichen,
> sind sie gleich, dann ist alles schön, wenn nicht.... noch einmal messen
> und das Ergebnis mit dem letzten Mittelwert vergleichen.

Wozu?
Die mir vorliegenden Datenblätter zu touch-screens geben zur Linearität 
<= 1,5% an. Da reicht das Ergebnis eines 8 Bit ADC ohne weitere 
Mittelwertbildung.

Bernhard S. schrieb:
> sich sehr einfach und mit wenigen kostbaren Prozessortakten
> realisieren lässt.

Taste nicht im 1 ms Raster, sondern im 10 ms Raster ab. Da sparst Du 
viel mehr der 'kostbaren' Zeit.

von Bernhard S. (bernhard)


Lesenswert?

Das kurzzeitige Antippen des Touchs ist nichtganz einfach auszuwerten.

Durch die angenehme Antipp-Entprell-Routine ist der Benutzer gezuwungen 
sich etwas Zeit für die Bedienung zu nehmen, der Touch ist dadurch nicht 
zu empfindlich.

Aber dann sollte die Messung schnell erfolgen, denn es ist nicht 
auszuschießen, daß in der Zwischenzeit der Touch wieder losgelassen 
wird.

Die Methode mit der mehrfachen Mittelwertbildung hat sich als ungünstig 
erwiesen.

Also, weniger ist manchmal mehr.


Kann mir bitte jemand verraten, welche Schicht beim LS-8 die obere ist ?
(wegen Entladung des Bedieners bei elekrostatische Aufladung)


Bernhard

von Robert W. (robwa)


Lesenswert?

Hallo Bernhard,

zu den vier Widerständen:
Ich benutze am XMega für den ADC die interne Stannungsreferenz VCC/1,6. 
Daraus ergibt sich ein Messbereich von 0..2,0625V bei einer 
Spannungsversorgung von 3,3V.
Wenn ich während einer ADC-Messung auf der gegenüberliegenden Folie VCC 
anlege, bekäme ich im ungünstigsten Fall (Berührung an der Kante, die an 
VCC liegt)3,3V auf den ADC und wäre somit außerhalb des Messbereiches. 
Das erklärt die "oberen" Widerstände die während der Messung an VCC 
liegen. Ich habe die "unteren" Widerstände (die während einer Messung 
gegen GND geschaltet werden eingebaut um den Mindestspannungspegel etwas 
anzuheben (mit meinen Widerständen ca. auf 0,27V), damit lassen sich 
Fehlmessungen, die 0 liefern ausschließen.
Durch meine gewählten Widerstände (die ich sicherlich günstiger hätte 
wählen können), komme ich auf einen unteren Spannungspegel von ca. 0,27V 
und auf einen oberen von ca. 1,2 - 1,3V.
Für den oberen Wert hätte ich besser gegen 1,8V gehen können, aber da 
der ADC des XMega mit 12 Bit arbeitet, bleibt mir so noch immer eine 
Auflösung von 1800 Bit für die y-Koordinate und 2000 Bit für die 
X-Koordinate übrig. Die Wert der einzelnen Widerstände sind: untere 
Widerstände: 100 Ohm, obere Widerstände: 750 Ohm, Ry=332 Ohm und Rx=377 
Ohm. Für die "oberen" Widerstände wären Werte um die 400 Ohm besser 
gewesen, damit hätte ich den oberen Spannungsbereich auf ca. 1,8V 
angehoben.

Deinen Einwand mit den 8 statt der 5 Messungen finde ich gut, dieser 
Vorteil ist mir im c-Programm in der Eile damals nicht aufgefallen.

.. und übrigens: ich wollte nicht

Bernhard S. schrieb:
> "...Rückmeldung wie genau die
> Touchauswertung funktioniert."

, ich habe es nur als Anregung vorgeschlagen! ;-)

Robert.

von Bernhard S. (bernhard)


Lesenswert?

Hallo Robert,

eine sehr gute Erklärung, das Gehemnis der 4 Widerstände ist somit 
gelüftet.

Übrigens:

>In einem Testdurchlauf habe ich die ADC- min- und max-Werte der x- und
>y-Koordinaten ermittelt.

Deine Anregung habe ich momentan wie folgt umgesetzt:

- Bei Programmstart werden nacheinander die beide Schichten bestromt und 
die Spannungspegel, also die ADC-Werte, an den Anschlüssen ermittelt.

- somit liegen schon mal die physikalischen MIN/MAX- Werte vor

- Anschließend, so wie Du es auch realisiert hast, wird ein Offsetwert 
addiert bzw. subtrahiert.
Bin noch am nachdenken/vordenken, ob ev. eine prozentualer Offset-Wert 
günstiger wäre, um kompatibel zu anderen Touchs zu sein.



Bernhard

von Robert W. (robwa)


Lesenswert?

Hallo Bernhard,

das klingt gut! Aber ich verstehe Deine Initialisierung nicht ganz. Wenn 
Du eine Folie mit Spannung versorgst, musst Du ja auf das Touchpanel 
drücken um eine Spannung für die Startwerte messen zu können. Wie hast 
Du das gelöst?

Robert.

von Bernhard S. (bernhard)


Lesenswert?

Hallo Robert,

> Wenn Du eine Folie mit Spannung versorgst, musst Du ja auf das
> Touchpanel drücken um eine Spannung für die Startwerte messen zu können.

Muss nicht sein.

Warum?

Bsp: Y+ wird gegen Betriebsspannung geszogen (PIN PC0 auf HIGH),
Y- gegen GND (PIN PC2 auf LOW), d.h. die Y-Schicht wird bestromt.

Obwohl diese PINs auf Ausgang geschaltet sind und ein Stom fließt, ist 
eine ADC-Messung an diesen PINs möglich, zumindest beim ATmega8 
(PC0=ADC0 / PC2=ADC2).

Somit könnte z.B. während der Bestromung der Y-Schicht ein ADC-Wert für
Y- (ADC2) von 61 und für Y+ (ADC0) von 959 ermittelt werden.

Anmerkung: 10Bit ADC / Uref=Betriebsspannung=5V / ohne die 
"4-Widerstände"

Der ADC-Wert von 61 ist demnach der physikalisch niedrigste Wert, der 
je an diesem (Y-)Anschluss während einer Bestromung entstehen könnte, 
bzw.
wenn der TOUCH gedrückt wird, an der X-Schicht entstehen kann.

Noch was, würde bei Dir auch funktionieren, trotz der "4-Widerstände",
wenn Deine ADC-Eingänge direkt am Y+/Y- und X+/X- Anschluss des Displays 
liegen würden.

Bernhard

: Bearbeitet durch User
von Robert W. (robwa)


Lesenswert?

Hallo Bernhard,

ja, jetzt ist mir das auch klar - danke für die gute Erklärung!
Das geht bei mir wegen der Widerstände nicht, da ich zwischne den 
Widerständen und dem Touchpanel keine Anschlüsse zum µC geführt habe 
(sonst müsste ich noch weitere vier Portpins für das Touchpanel 
verwenden). Aber wie bereits geschrieben funktioniert es so auch recht 
zufriedenstellend.

Robert.

von Bernhard S. (bernhard)



Lesenswert?

Dieser kleine TWI / I2C Slave kann bis zu 64 Touchs in seinem Buffer 
speichern.

Befinden sich Daten im Buffer (Koordinaten vom Touch) dann wird der 
SBUF-PIN gegen GND gezogen.

Und bei der TWI-Ausgabe meldet ein Byte die Anzahl der noch vorhandenen 
Touchs.

Der Buffer kann per Befehl auch komplett gelöscht werden, erspart das 
Auslesen aller gespeicherten Touchs.

USART sendet sofort die die TOUCH-Koordinaten.

Bei Programmstart kalibriert sich der TOUCH hinreichend genau.

Ein BEEP meldet TOUCH-Berührungen, kann aber per TWI deaktiviert werden, 
wenn's nervt.

Die SLAVE-Adresse, Touch-PIXEL, PIN-BELEGUNG, TOUCH-OFFSET usw. lässt 
sich in der "TOUCH_ini.asm" einstellen.

Das Display braucht man nicht, dient nur zu Kontrollzwecken.

Bernhard

: Bearbeitet durch User
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.