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