Forum: Mikrocontroller und Digitale Elektronik Problem mit 8-Wire-Touchpanel


von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Community,

Wir arbeiten zurzeit an einem Projekt, bei dem es darum geht, eine Kugel 
auf einer Fläche zu balancieren. In etwa so: 
https://www.youtube.com/watch?v=enlQMUE9df4

Als Rückmeldung der aktuellen Kugelposition verwenden wir diesen 
Touchscreen-Sensor: 
http://ch.rs-online.com/web/p/touchscreen-sensoren/7105238/

Nun zu unserem Problem: Betreiben wir den Touchscreen-Sensor "statisch", 
d.h. ohne Umschaltung von X- und Y-Richtung, erhalten wir saubere 
Messwerte (logischerweise nur in einer Achse). Das funktioniert jeweils 
für beide Achsen. Sobald aber zwischen diesen beiden Schritten 
umgeschalten wird, um auch wirklich eine zwei-Achsige Position auslesen 
zu können, erhalten wir merkwürdige Störungen.

Woher kommen diese Spannungsspitzen? Parasitäre Kapazitäten des 
Touchscreens?  Wie lassen sich diese unterdrücken?

Die Messwerte werden über die serielle Schnittstelle an den PC 
übertragen und dort für Debug-Zwecke angezeigt (siehe Bilder). (Bei den 
Versuchen mit der statischen Ansteuerung wird der Messwert jeweils für 
das Protokoll doppelt gesendet, und dementsprechend auch doppelt 
angezeigt). Die Elektronik besteht aus einem PIC18F25K22.

Anbei den Code für den relevanten Teil:
1
#define right       1<<6
2
#define left        1<<7
3
#define top         1<<4
4
#define bottom      1<<5
5
#define right_sens  1<<0
6
#define left_sens   1<<1
7
#define top_sens    1<<3
8
#define bottom_sens 1<<2
9
#define adc_right   0
10
#define adc_left    1
11
#define adc_bottom  2
12
#define adc_top     3
13
14
unsigned short ADC_Read(unsigned char ch) {
15
    ADCON0bits.CHS=ch;
16
    GODONE = 1; //Start conversion
17
    while (GODONE); //wait for the conversion to finish
18
    return ((ADRESH << 8) | ADRESL); //Return result
19
}
20
21
void Get_Ball_Position(unsigned short *data) {
22
    /*For X Axis*/
23
    TRISA = 0b00111111;
24
    LATA = left; //Left=1, Right=0
25
    data[0] = ADC_Read(adc_bottom);
26
   // data[1] = ADC_Read(adc_bottom);//send same data twice, for test purposes
27
    
28
    /*For Y Axis*/
29
    TRISA =0b11001111; 
30
    LATA=bottom; //Bottom=1; Top=0
31
    data[1]=ADC_Read(adc_left);
32
   // data[0]=ADC_Read(adc_left);//send same data twice, for test purposes
33
34
}

Die Funktion Get_Ball_Position wird regelmässig von einem 
Timer-Interrupt aufgerufen.

Mit freundlichen Grüssen,

Stefan

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ihr müsst zwischen Spalten- und Zeilen Abfrage ein wenig Zeit 
verstreichen lassen. Ich weiss zwar nicht, wie schnell euer 
Timerinterrupt feuert, aber bei meinen Abfragen eines resistiven 
Touchpads mit einem AVR frage ich z.B. X ab, speichere das, stelle um 
auf Y Abfrage, starte den ADC und verlasse den ADC IRQ. Beim nächsten 
Durchlauf wird Y gelesen und gespeichert, es wird auf X umgestellt und 
dann wieder die ISR verlassen
1
/* called everytime the ADC has completed a conversion */
2
ISR(ADC_vect)
3
{
4
  switch (ADMUX)              // the setup of ADMUX is covered with constants
5
  {
6
  case ADMUX_HOR:
7
      xPos = ADCH;          // read the value
8
      ADMUX = ADMUX_VER;    // switch to vertical scan
9
      TOUCH_DDR |= ((1<<X1)|(1<<X2)); // and prepare the port for proper setup
10
      TOUCH_DDR &= ~((1<<Y1)|(1<<Y2));  // vertical read input
11
      TOUCH_PORT &= ~(1<<X1);    // left side low
12
      TOUCH_PORT |= (1<<X2);     // right side high
13
      break;
14
  case ADMUX_VER:
15
      yPos = ADCH;          // read X value
16
      ADMUX = ADMUX_HOR;   // and switch to reading horizontal touch
17
      TOUCH_DDR |= ((1<<Y1)|(1<<Y2));
18
      TOUCH_DDR &= ~((1<<X1)|(1<<X2));  //  horizontal read input
19
      TOUCH_PORT |= (1<<Y1);         // downside high
20
      TOUCH_PORT &= ~(1<<Y2);        // upside low
21
  break;
22
    
23
  } 
24
// restart the ADC and clear any pendings
25
  ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | (1 << ADIE) | ADC_PRESCALER;
26
};
Das ganze geschieht etwa alle 40 - 60ms, also recht gemächlich.

: 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.