Forum: Mikrocontroller und Digitale Elektronik Probleme mit resistivem Touchscreen


von Tobias N. (silberkristall)


Lesenswert?

Hallo,

da ich nun erfolgreich einige dinge ans laufen bekommen habe unter 
anderem auch ein GLCD wollte ich dieses nun mit einem Touchscreen 
versehen.

Ansteuerung laut datenblatt ausgeführt. An 4 ADC port angeschlossen und 
in einer while schleife die abfrage ausgeführt.

Laut Datenblatt soll ich,

MCU: Atmega8

Belegung: Pin1 -> PC1, Pin2 -> PC2, Pin3 -> PC3, Pin4 -> PC4

X-Coordinate

Pin1 (X+) auf VCC schalten, Pin2 (X-) auf GND schalten.
An Pin4 soll ich dann die Messung vornehmen, Pin3 bleibt unbenutzt.

Y-Coordinate

Pin3 (Y+) auf VCC schalten, Pin4 (Y-) auf GND schalten.
An Pin2 soll ich dann die Messung vornehmen, Pin1 bleibt unbenutzt.

Nun läuft das ganze in der while schleife,

für X,

PC1 auf Ausgang dann auf High
PC2 auf Ausgang dann auf Low
PC4 auf Eingang und ADC einlesen

für Y,

PC3 auf Ausgang dann auf High
PC4 auf Ausgang dann auf Low
PC2 auf Eingang und ADC einlesen

Die Werte stehen dann in den variablen xcor und ycor.

Solange ich das Touchscreen nicht berühre werde mir auf dem Display die 
Werte für X und Y mit 1023 ausgegeben, klar, kein widerstand als 5V 
somit höchster ADC wert. Berühre ich das Touchscreen dann ändern sich 
die Werte nicht oder "springen", dann werden für einige Sekunden jeweils 
verschiedene Werte angezeigt also z.b. so: 1023, 6483, 4830, 7473, 0480, 
1023.

Dann stehen die werte wieder konstant auf 1023 bis ich das Touchscrren 
wieder berühre, dann werden wieder irgendwelche Werte angezeigt und 
danach stehen sie wieder auf 1023.

Meines wissens nach ist der höchste ADC wert doch 1023, demnach kann ich 
mir das nicht erklären, und auch das "springen" der Werte, selbst wenn 
ich ganz ruhig einen Kugelschreiber oder ähnliches benutze springen die 
Werte.

Die Werte gebe ich mittels itoa(xcor, Buffer, 10); und dann 
lcd_puts(small_font, Buffer); mit der mylcd libraray auf dem Display 
aus. Genau so auch mit der Y Coordinate.

Ich hoffe mir kann da jemand helfen.

Danke schonmal.

von Eumel (Gast)


Lesenswert?

Klappt ohne Code bestimmt gut.
Löscht du das Display bevor du schreibst oder überschreibst du nur?

von Sam P. (Gast)


Lesenswert?

Stellst du den jeweils ungenutzten Pin auch auf hochohmig? Bei deiner 
Beschreibung klingt es so, als ob der jeweils ungenutzte Pin auf high 
bleibt, was natürlich nicht funktionieren kann. Er muss auch als Eingang 
konfiguriert werden, auch wenn du ihn nicht auswertest.

von Tobias N. (silberkristall)


Lesenswert?

Hallo,

danke erstmal für die antworten.

Also vor der neuen ausgabe auf dem Display überschreibe ich die Zahl mit 
leerzeichen und schreibe dann wieder neu.

Also den jeweils nicht genutzten Pin lasse ich so wie er ist/war. Also 
muss ich den auch als Eingang und dann auf High setzten, richtig?

von Sam P. (Gast)


Lesenswert?

Nicht auf High. Hochohmig. Das ist beim AVR immer dann wenn er als 
Eingang konfiguriert ist.

von Tobias N. (silberkristall)


Lesenswert?

ok,

also schalte ich für x dann die x ports auf ausgang und dann x+ auf 
high, x- auf low, die ports y- und y+ auf eingang und dann messe ich am 
y- mittels adc. für y das gleiche nur halt mit den entsprechenden ports.

von Sascha W. (sascha-w)


Lesenswert?

Tobias N. schrieb:
> ok,
>
> also schalte ich für x dann die x ports auf ausgang und dann x+ auf
> high, x- auf low, die ports y- und y+ auf eingang und dann messe ich am
> y- mittels adc. für y das gleiche nur halt mit den entsprechenden ports.

genau, und an den Eingangsports auf keinen Fall den Pullup aktivieren.
Du musst allerdings nicht dauernd messen, sondern nur wenn auch eine 
Berührung stattfindet. Dazu legst du die eine Achse auf GND (z.B. X+ & 
X-) und schaltest die andere auf Eingang, wobei du an einem Eingang auch 
den Pullup einschaltest. Dort kannst du nun abfragen ob eine Berührung 
stattfindet. Im Ruhezustand hast du durch den Pullup immer H-Pegel, 
sobald der Touch berührt wird bekommst du L-Pegel und kannst die Messung 
starten.
Und du musst für ein brauchres Ergebnis immer mehrere Messungen machen 
und den Durchschnitt der Messwerte nehmen.

Sascha

von Tobias N. (silberkristall)


Lesenswert?

Ich habe jetzt so einiges Probiert aber alles ohne erfolg,

hier mal der letzte getestete Code.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdio.h>
4
#include <avr/interrupt.h>
5
6
#include "ow.h"
7
#include "mylcd.h"
8
#include "small_font.h"
9
#include "mega.h"
10
#include "image_load.h"
11
12
#define XPLUS  PC3  // X+ Port
13
#define XMINUS  PC1  // X- Port
14
#define YPLUS  PC0  // Y+ Port
15
#define YMINUS  PC2  // Y- Port
16
17
18
/* ADC initialisieren */
19
void ADC_Init(void) {
20
 
21
  uint16_t result;
22
 
23
  // interne Referenzspannung als Refernz für den ADC wählen:
24
  ADMUX = (1<<REFS1) | (1<<REFS0);
25
  
26
  // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
27
  // schon auf 0, also single conversion
28
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
29
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
30
 
31
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
32
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
33
 
34
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
35
  while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der Konvertierung warten
36
  }
37
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
38
     Wandlung nicht übernommen. */
39
  result = ADCW;
40
}
41
42
/* ADC Einzelmessung */
43
uint16_t ADC_Read( uint8_t channel )
44
{
45
  // Kanal waehlen, ohne andere Bits zu beeinflußen
46
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
47
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
48
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
49
  }
50
  return ADCW;                    // ADC auslesen und zurückgeben
51
}
52
53
54
int main (void)
55
{
56
57
  char Buffer[20];
58
  
59
  int xcor = 0;
60
  
61
  //init lcd
62
  lcd_init();
63
  lcd_clear();
64
  
65
  lcd_draw_fullscreen_bmp(img);
66
  
67
  ADC_Init();
68
  
69
  // Ausgänge
70
  DDRC |= (1<<YPLUS);
71
  DDRC |= (1<<YMINUS);
72
  
73
  //Eingänge
74
  DDRC &= ~(1<<XPLUS);
75
  DDRC &= ~(1<<XMINUS);
76
  
77
  while(1)
78
  {
79
  // X Coordiante
80
  
81
  
82
  
83
  // High / Low
84
  PORTC |= (1<<YPLUS);
85
  PORTC &= ~(1<<YMINUS);
86
  
87
  _delay_ms(200);
88
  xcor = ADC_Read(XPLUS);
89
  
90
  itoa( xcor, Buffer, 10 );
91
    
92
  lcd_set_cursor(80,LINE3);
93
  lcd_puts(small_font, "                        ");
94
  lcd_puts(small_font, Buffer);
95
  _delay_ms(10);
96
97
  
98
  // X Coordiate ende
99
  }
100
}

von Rene S. (Firma: BfEHS) (rschube)


Lesenswert?

Also ich würde mir das nicht so umständlich machen. Warum alles in den 
armen kleinen uC reinhacken?

Nimm z.B. einen ADS7846. Der macht das alles und mit den sprichst du 
über SPI und fertig. Außerdem hat der noch ein paar nützliche 
Zusatzfunktionen. Und der kann deinen uC per IRQ-Leitung aufwecken wenn 
am Touch was passiert.

von Tobias N. (silberkristall)


Lesenswert?

das ist nur mein test µc, hinterher wird dann dann an einem mega32 
betrieben, also nur das display und das touch, der soll als "grafikchip" 
dienen, der komuniziert dann mittels spi, kriegt halt noch eine sd karte 
und ein paar ds1820 aber mehr soll der mega32 dann nicht machen, also 
display, touch, sdkarte und ds1820, der rest passiert dann mittels spi.

ich will halt das ganze mehr verstehen etc. pp. demnach muss ich mich da 
wohl durch kämpfen ;) lerning by doing :)

von spess53 (Gast)


Lesenswert?

Hi

Such mal bei ATMEL nach:

AVR341: Four and five-wire Touch screen Controller using tinyAVR and 
megaAVR devices

Da gibte es auch Software.

MfG Spess

von Sascha W. (sascha-w)


Lesenswert?

@Tobias,

// interne Referenzspannung als Refernz für den ADC wählen:
ADMUX = (1<<REFS1) | (1<<REFS0);

Damit kann es ja überhaupt nicht gehen!!
Dein Touch wird ja schießlich über die Portpins, also Vcc mit Spannung 
versorgt, also muss auch die Referenzspannung des ADC Vcc sein!

Sascha

von Tobias N. (silberkristall)


Lesenswert?

naja, also bei

ADMUX = (0<<REFS1) | (1<<REFS0);

macht er weiter wie bisher gibt mir einfach immer irgendwelche zahlen 
aus, pendelt sich aber nicht einmal bei 1023 ein.

bei

ADMUX = (0<<REFS1) | (0<<REFS0);

steht er konstant auf 1023 und egal ob ich was drücke oder nicht der 
wert verändert sich nicht.

also irgendwas ist doch hier falsch :(

von Tobias N. (silberkristall)


Lesenswert?

so, es läuft, also als ich mir dann mal dachte ich lese Y auch noch mit 
aus, voila, die werte werden angezeigt.

alles tutti, aber schon stellt sich mir die nächste frage.

ich versuchte also mal "einen" bereich also taste zu nutzen, also ganz 
viele ifs und wenn es stimmt zeige mir was an, beim wieder drauf drücke 
mache die anzeige wieder weg. das klappt auch alles soweit aber sehr 
"langsam" also "schnelles" tippen wird nicht erkannt.

"menu" anzeigen geht schneller als "menu" nicht mehr anzeigen. wenn ich 
halte dann zeigt der mir das etwa im sekunden wechsel an. also text da, 
text weg, text da, text weg

muss/kann man die touch eingaben auch "entprellen" halten ein anderer 
zustand als tippen?

wie kann man einstellen "wie schnell" er reagieren soll, denn ein kurzes 
tippen wie z.b. beim handy endet mit garkeiner reaktion.

es läuft jetzt mit der internen referenzspannung vcc, mit avcc erhalte 
ich konstand 1023 und keine reaktionen aufs tippen. beim messen mittels 
multimeter funktioniert aber alles nur er misst halt nicht.

danke euch.

von Eumel (Gast)


Lesenswert?

Vielleicht hast du Avcc falsch beschaltet...

von Tobias N. (silberkristall)


Lesenswert?

100nF zwischen AVCC und AGND und die dann mit 5V vom 7805 beschaltet. 
Und dann nochmal einen 100nF zwischen AREF und AGND. Die aber dann nicht 
beschaltet also nur den 100nF dazwischen.

von Eumel (Gast)


Lesenswert?

Willst du denn nun Aref nutzen oder nicht?

von Tobias N. (silberkristall)


Lesenswert?

nunja, also wenn es mir vorteile bringt dann natürlich. wenn es mit AVCC 
gleichgestellt ist dann brauche ich es ja nicht zwingend nutzen, oder?

von Eumel (Gast)


Lesenswert?

Tobias N. schrieb:
> nunja, also wenn es mir vorteile bringt dann natürlich. wenn es mit AVCC
> gleichgestellt ist dann brauche ich es ja nicht zwingend nutzen, oder?

Wenn du an Aref eh nur die 5 Volt anschließen würdest ist es besser AVCC 
zu benutzen. Geh aber eigentlich beides.

siehe:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC#Referenzspannung_AREF

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.