beim download des aktuellen avr studios ist mir der eintrag qtouch
aufgefallen. hat sich schon jemand mit dieser technologie beschäftigt.
ist es ein muss oder nur einen neue sau die durchs dorf getrieben wird?
Ich schalte das Licht in der Dusche mit einem hinter den Fliesen
angebrachten TouchPad. Die Routinen habe ich nach einem Besuch beim
QTouch-Seminar nochmal nachempfunden und in einen Mega88 geflasht, die
Libraries von ATMEL benutze ich nicht, weil falsche Programmiersprache
;-). Ich empfinde die Touch-Technik als nützlich, gerade im "IP67 oder
besser Bereich".
Ich hab mir letztens die QTouch Libs angesehen (mit AVR GCC) und musste
feststellen, dass die Messung eines Touchsensors etwas unempfindlich
ist. Oder ich hab die falschen Einstellungen getroffen (keine Ahnung).
Jedenfalls ist die Technik ja relativ leicht nachprogrammiert und
funktioniert bei mir jetzt auch besser (empfindlicher). Hab aber noch
keine Driftkompensation drinnen wie es in der Atmel Lib drinnen ist.
mfg
Andreas
Die Driftkompensation ist nichts weiter als ein Tiefpaß, der den
Mittelwert als Differenz für die Meßwerte stetig anpaßt (etwa um einen
Meßwert pro Sekunde) wenn kein Touch ausgelöst ist. Nach Toucherkennung
wird der Mittelwert nicht verändert, bis der Touch wieder weg ist oder
ein Timeout von, sagen wir mal, 15 Sekunden verstrichen ist.
Ich habe bisher nur gesehen, daß zwar die tollsten Erklärungen für die
Sensor-ICs gemacht werden, aber es letztendlich auf eine
Kapazitätsmessung hinausläuft.
Es kochen also alle nur mit Selters.
Peter
Nee, Peter. Es ist keine Kapazitätsmessung sondern eine
Charge-Transfer-Messung. Gegenüber der reinen Kapazitätsmessung mit
einer an einem Pin angeschlossenen Meßplatte ist diese Version mit
definierter Paketladung über einen Transferkondensator über 2 Pins
empfindlicher und reproduzierbarer.
@Travel Rec.:
Hast du dir für deine Anwendung eine Platine machen lassen?? Wenn ja,
wie sieht da deine "Touch-Fläche" aus?? Vorallem würde mich
interessieren, wie groß die Fläche ist und ob du im Layer darunter eine
Massefläche hast?!
Achja... und das funktioniert bei dir noch hinter den Fliesen?! Ich hab
schon Probleme, wenn ich bisschen Kunststoff oder Papier drüber hab.
Andreas Auer schrieb:
> @Travel Rec.:> Hast du dir für deine Anwendung eine Platine machen lassen??
Ja, von mir selber ;-)
> Wenn ja,> wie sieht da deine "Touch-Fläche" aus??
Ist eine mit kurzem Kabel abgesetzte, einseitig kupferkaschierte
Hartpapier-LP in der Größe eines 2-EUR Stücks, vielleicht ein wenig
größer.
> Vor allem würde mich> interessieren, wie groß die Fläche ist
Wie gesagt...
> und ob du im Layer darunter eine> Massefläche hast?!
Natürlich NICHT!
> Achja... und das funktioniert bei dir noch hinter den Fliesen?! Ich hab> schon Probleme, wenn ich bisschen Kunststoff oder Papier drüber hab.
Ja. Geht durch 1cm Keramik und 1.25cm Rigips.
Travel Rec. schrieb:
> Nee, Peter. Es ist keine Kapazitätsmessung sondern eine> Charge-Transfer-Messung.
Gibt es irgendwo ne verständliche Beschreibung und Schaltplan mit
Dimensionierung?
Braucht man die speziellen ICs dazu oder reicht ein normaler MC?
Ich bin von den Flyern und Werbung auf der Atmel Seite schon ganz
wuschig im Kopf. Nirgends findet man was sinnvolles.
> Gegenüber der reinen Kapazitätsmessung mit> einer an einem Pin angeschlossenen Meßplatte ist diese Version mit> definierter Paketladung über einen Transferkondensator über 2 Pins> empfindlicher und reproduzierbarer.
Läßt sich das irgendwie belegen?
Ich denke mal, daß auch diese Methode eine Art Kalibration durchführen
muß, um auf Empfindlichkeit zu kommen.
Peter
Peter Dannegger schrieb:
> Gibt es irgendwo ne verständliche Beschreibung und Schaltplan mit> Dimensionierung?> Braucht man die speziellen ICs dazu oder reicht ein normaler MC?> Ich bin von den Flyern und Werbung auf der Atmel Seite schon ganz> wuschig im Kopf. Nirgends findet man was sinnvolles.
Es gab mal einen Thread da hat Travel Rec. selbst seinen Code und
Schaltplan gepostet. Mit dem war es mir möglich das ganze
nachzuvollziehen und in C zu implementieren.
Beitrag "Quantum Chips"
Die Atmel Seite ist in diese Richtung in der Tat etwas unübersichtlich.
Peter Dannegger schrieb:
> Braucht man die speziellen ICs dazu oder reicht ein normaler MC?> Ich bin von den Flyern und Werbung auf der Atmel Seite schon ganz> wuschig im Kopf. Nirgends findet man was sinnvolles.
Die Touch-ICs liefern fertige Schaltsignale und lassen sich geringfügig
von außen konfigurieren. Beim µC kann man die Libraries benutzen oder
selber loslegen. Bedingung ist, daß de µC abschaltbare PullUps hat,
sonst funktionieren die Meßbursts nicht. Touch funktioniert also u.a.
auf allen neueren AVRs und XMegas und den AVR32-Controllern.
Hallo,
ich klinke mich an der Stelle mal ein. :-)
Leider habe ich bezüglich der QTouch-Sache ein wenig ein Brett vor dem
Kopf.
Ich verstehe das funktionsprinzip anhand der Zeichnung im Anhang (die
ist aus dem Atmel-Datasheet) folgendermaßen:
1. Zu beginn wird die Sensorplatte entladen indem PB1 als Eingang und
auf "0" geschaltet wird.
2. PB1 wird nun zur Bursterzeugung kurz auf "1" geschaltet, danach wird
der Pin umkonfiguriert als Eingang, Pull-Ups sind generell
ausgeschaltet.
3. Das ganze Spiel unter 2. wiederholt sich bis der Pin wenn er als
Eingang geschaltet ist als logisch "1" gelesen wird. Die Anzahl der
notwendigen Ladezyklen wird dabei gezählt.
4. Steigt die Anzahl der notwendigen Ladezyklen auf einmal stark an,
geht der Chip davon aus das einer Seine Flossen vor den Sensor hält. Die
Auslöseschwelle wird natürlich ständig langsam nachgeführt (Stichwort
Tiefpass)
Was ich nicht ganz kapiere, für was braucht man den Kondensator Cs?
Warum der eine Verbindung zu PC1 hat und nicht nach GND kapiere ich
nicht so ganz.
Es schwirren viele Infos und Codeschnipsel im Netz rum, auch hier im
Forum, aber eine einfache Erklärung des Funktionsprinzips habe ich bis
jetzt noch nicht gefunden. "Charge Transfer" hört sich zwar interessant
an, aber an klaren Erklärungen mangelt es mir zur Zeit irgendwie. ;-)
Vielleicht kann mir jemand Erklären wie das mit dem Kondensator im
ganzen funktioniert. Für irgendwas muss Cs ja gut sein...
Nachtrag: Ich vermute das durch das Umladen der einen Seite des
Kondensators, etwas Ladung auf die "andere" seite des Kondensator
geschaufelt wird. Stimmt das ?
Nachtrag2: Gehe ich recht in der Annahme das man zum das QTouch Prinzip
zu realisieren keinen ADC benötigt, dies also rein mit den normalen
Pins, wie auch mit den kleineren Tinys, oder dem Tiny2313 der keinen ADC
hat, klappt?
Roland
@Travel Rec.
Die Eingänge werden digital eingelesen, d.h. eine Drift der
Eingangsschwelle spielt keine Rolle?
Die Eingänge werden eingelesen, wenn alles tristate ist, muß das dann
nicht sauempfindlich gegen HF-Störungen sein?
Und der Eingang, der später eingelesen wird, müßte störempfindlicher
sein.
Sollte man nicht besser erst die SBIS-Befehle machen und danach das
ADIW?
Könnte man die Schleife nicht schon abbrechen, wenn beide Eingänge low
sind?
Können die 33nF Keramik sein?
Wenn ja, die haben ja große Toleranzen und Drift, wirkt sich das auf die
Werte der beiden Tasten aus?
D.h. können die stark unterschiedlich sein?
Die Ausgänge TOUCH1A/2A werden nirgends gesetzt, müssen sie low sein,
oder ist das egal?
Vom Prinzip her erinnert mich das an nen DAC mit geschalteten
Kondensatoren. Der Unterschied ist nur, daß beide Kondensatoren nicht
gleich groß sind, sondern stark unterschiedlich.
Das Prinzip hat man früher auch als Rampengenerator verwendet (ein
kleiner Kondensator lädt kleine Ladungen auf einen großen).
Letztendlich ist also auch eine Kapazitätsmessung. Die Frage ist nur,
welcher Unterschied sich bezüglich Bauelementedrift und Störspannungen
gegenüber anderen Meßmethoden ergibt.
Peter
@Roland:
Ich weiß nicht, ob die Beschreibung von Peter jetzt ausreicht um deine
Fragen zu beantworten, da er doch sehr stark auf die Implementierung von
Travel Rec. eingeht.
Ich hab das ganze so implementiert:
1. definierten Zustand für die Kondensatoren herstellen. D.h. PB1 und
PC1 als Ausgänge schalten und auf low ziehen um alles Cs zu entladen
(genügend lange warten).
2. PB1 auf high und PC1 auf low schalten (aber immernoch als Eingänge)
3. PB1 als Ausgang schalten und kurze Zeit (z.B. 5us) warten bis der
unbekannte Touchkondensator geladen ist.
4. PB1 wieder als Eingang schalten und PC1 als Ausgang schalten. Damit
liegt jetzt der "Sampling Kondensator Cs" quasi parallel zum
Touchkondensator und es müssen sich die Ladungen so umverteilen, dass
beide die gleiche Spannung haben (Parallelschaltung). D.h. es wird Cs
leicht geladen, da dieser ja viel größer ist.
5. Überprüfe ob PB1 schon als high eingelesen wird. Wenn nicht, dann
beginne wieder bei Punkt 3 und erhöhe einen Zähler. Wenn PB1 bereits
high ist, dann ist der Zählerstand ein Maß für die Anzahl der
Ladezyklen.
Der Endstand des Zählers wird sich verändern, wenn du mit dem Finger auf
den Touchsensor greifst.
Als C code sieht das so aus:
Andreas Auer schrieb:
> @Roland:> Ich weiß nicht, ob die Beschreibung von Peter jetzt ausreicht um deine> Fragen zu beantworten, da er doch sehr stark auf die Implementierung von> Travel Rec. eingeht.>> Ich hab das ganze so implementiert:>> 1. definierten Zustand für die Kondensatoren herstellen. D.h. PB1 und> PC1 als Ausgänge schalten und auf low ziehen um alles Cs zu entladen> (genügend lange warten).
Habe ich, soweit kein Problem
>> 2. PB1 auf high und PC1 auf low schalten (aber immernoch als Eingänge)
Aha, dann beide Pins als Eingänge Konfigurieren. Aber wie soll ich dann
High und Low schalten? Ist das eventuell ein Schreibfehler deinerseits
und sollte Ausgang (also für die Konfig der Pins) heißen?
>> 3. PB1 als Ausgang schalten und kurze Zeit (z.B. 5us) warten bis der> unbekannte Touchkondensator geladen ist.>
Hier komme ich gar nicht mehr mit, was macht dann PC1? Ist das immer
noch ein Ausgang und auf Low?
> 4. PB1 wieder als Eingang schalten und PC1 als Ausgang schalten. Damit> liegt jetzt der "Sampling Kondensator Cs" quasi parallel zum> Touchkondensator und es müssen sich die Ladungen so umverteilen, dass> beide die gleiche Spannung haben (Parallelschaltung). D.h. es wird Cs> leicht geladen, da dieser ja viel größer ist.>
Sorry jetzt komme ich nicht mehr mit, PC1 als Ausgang kapiere ich aber
was für einen Pegel, High oder Low?
> 5. Überprüfe ob PB1 schon als high eingelesen wird. Wenn nicht, dann> beginne wieder bei Punkt 3 und erhöhe einen Zähler. Wenn PB1 bereits> high ist, dann ist der Zählerstand ein Maß für die Anzahl der> Ladezyklen.>> Der Endstand des Zählers wird sich verändern, wenn du mit dem Finger auf> den Touchsensor greifst.>> Als C code sieht das so aus:>
1
>staticintsense(void)
2
>{
3
>unsignedchari=0;
4
>DDRC=0x00;
5
>PORTC=0x00;
6
>
7
>DDRC|=_BV(PC1);
8
>DDRC|=_BV(PC0);
9
>_delay_us(5);
10
>DDRC&=~_BV(PC1);
11
>DDRC&=~_BV(PC0);
12
>
13
>PORTC|=_BV(PC0);
14
>for(i=0;i<255&&!(PINC&_BV(PC0));i++)
15
>{
16
>DDRC|=_BV(PC0);
17
>_delay_us(5);
18
>DDRC&=~_BV(PC0);
19
>DDRC|=_BV(PC1);
20
>_delay_us(20);
21
>DDRC&=~_BV(PC1);
22
>}
23
>DDRC|=_BV(PC1);
24
>DDRC|=_BV(PC0);
25
>PORTC=0x00;
26
>
27
>returni;
28
>}
29
>
Könntest du vielleicht mal das Funktionsprinzip genauer erklären oder
den genauen Status der Pins darstellen? Der C-Code ist zwar interessant
aber ich würde gerne das Funktionsprinzip generell verstehen, also wo
die Ladungen hingehen usw.
Leider fehlen bei deiner Erklärung auch einige Teile die zum Verständnis
notwendig sind, sprich ich verstehe das nicht komplett.
Roland
So, hier mal mein Beispiel, vorausgesetzt, ich habe das Prinzip richtig
verstanden:
1
#include<atomic.h>
2
#include"mydefs.h"
3
4
#define MAX_CYCLE 1000
5
6
#define SENSKEY_A0 SBIT( PORTB, 0 ) // connect to senspad
7
#define SENSKEY_A0_DDR SBIT( DDRB, 0 )
8
9
#define SENSKEY_B0 SBIT( PORTB, 1 ) // connect to cap to A0
10
#define SENSKEY_B0_DDR SBIT( DDRB, 1 )
11
#define SENSKEY_B0_PIN SBIT( PINB, 1 )
12
13
/*
14
A0 B0 B0_PIN
15
0 0 full discharge
16
loop:
17
Z Z gap
18
Z 1 partial charge over pin A0 and senspad
19
Z Z gab
20
0 Z partial charge over pin B0 only
21
0 Z 1 end
22
*/
23
24
uint16_tread_senskey(void)
25
{
26
uint16_ti=MAX_CYCLE+1;
27
28
SENSKEY_A0=0;
29
SENSKEY_A0_DDR=1;
30
SENSKEY_B0=0;
31
SENSKEY_B0_DDR=1;// discharge cap
32
33
ATOMIC_BLOCK(ATOMIC_FORCEON){
34
do{
35
SENSKEY_A0_DDR=0;// A0 = tristate
36
SENSKEY_B0=1;// B0 = weak high
37
SENSKEY_B0_DDR=1;// B0 = strong high
38
SENSKEY_B0_DDR=0;// B0 = weak high
39
SENSKEY_B0=0;// B0 = tristate
40
SENSKEY_A0_DDR=1;// A0 = strong low
41
if(--i==0)
42
break;// timeout
43
}while(SENSKEY_B0_PIN==0);// until charged
44
}
45
SENSKEY_B0_DDR=1;// discharge cap
46
returnMAX_CYCLE-i;// big value = key touched or timeout
47
}
Ich habe es etwas geändert.
Es wird der Pin eingelesen, der nicht mit dem Pad verbunden ist und
während das Pad auf low gezogen wird. Damit können Störungen auf dem Pad
nicht die Lesung beeinflussen.
Das Prinzip ist das eines Treppengenerators, wie er z.B. früher zum
Erzeugen des Fernsehtestbildes verwendet wurde. Interessant, wie man für
altbekannte Schaltungen neue Einsatzfelder findet.
Peter
@Peter Danneger,
heißt das du wertest die durch den Kondensator transportierte Ladung
aus, bzw lässt den Ladezyklus so lange laufen bis der Pin als Logisch 1
gelesen wird.
Klingt interessant, somit hat man keine Probleme bei Störverseuchter
Umgebung auf die das Pad wie eine Antenne wirken würde....
Roland
@Roland:
Wird eigentlich alles schön in entsprechenden Dokumenten erklärt, wozu
und wie das funktioniert, zb. in der TouchLib Doku:
The QTouch™ acquisition method charges an electrode of unknown
capacitance to a known potential. The resulting charge is transferred
into a measurement capacitor (Cs). The cycle is repeated until the
voltage across Cs reaches a voltage. The signal level is the number of
charge transfer cycles it took to reach the voltage. Placing a finger on
the touch surface introduces external capacitance that increases the
amount of charge transferred each cycle, reducing the total number of
cycles required for Cs to reach the voltage. When the signal level
(number of cycles) goes below the present threshold, then the sensor is
reported as in detect.
Aber am besten wenn man sich erstmal das Design Guide reinzieht. QMatrix
ist da natürlich viel robuster.
http://www.atmel.com/dyn/resources/prod_documents/doc10620.pdfhttp://www.atmel.com/dyn/products/app_notes_touch.asp?family_id=697
Und immer schön das Routing beachten ;-)
@Joe,
Das Design Guide habe ich gelesen, würde ich das genaue Funktionsprinzip
verstehen, würde ich hier ja nicht fragen. Mir will einfach nicht in den
Kopf wie der verdammte Kondensator Cs funktioniert, also wie das mit der
Ladungsmengenmessung funktioniert. Auf welcher seite des Kondensators
messe ich die Ladung und wie kommt die dahin? Sinn würde es ja nur
machen wenn man an PC1 (auf mein obriges Bild bezogen) Messen würde, nur
wie muss sich dieser Pin während des Ladezyklus verhalten? Dauernd als
Eingang Schalten und warten bis er logisch 1 wird? Meine Frage ist wie
und wo kommt die Ladung in den Kondensator und an welchem Pin messe ich
das.
Dein zitierter Text von Atmel ist etwas allgemein gehalten, es wird
nicht darauf eingegangen wie die Ladung in den Kondensator kommt und
welche Zustände die beteiligten Pins einnehmen.
Es geht mir um das GENAUE Funktionsprinzip, nicht um das allgemeine, da
ich das Verstehen will. ;-)
Nachtrag: Mit dem Routing hast du recht, habe mal bei der Verwendung des
QT100 seltsame Fehler in der Schaltung gehabt. Schlussendlich lags am
Routing, waren zwei "heisse" Leiterbahnen zu dicht beisammen... So kanns
gehen.
Roland
Habe die Schaltung gerade mal aufgebaut und es funktioniert.
Dank an Andreas Auer (und alle anderen).
@Roland Z.:
Im Prinzip hast du 2 Kondesatoren:
Cs als Speicher und die "Touch" Electrode gegen Erde.
Am Anfang werden beide entladen.
In einer Schleife wird dann zuerst der Touch Kondensator
über PB1 aufgeladen (Hat nur wenige pf). Der Port PC1
ist als Eingang geschaltet damit in den Cs kein Strom
fließen kann. Es wird kurz gewartet.
PB1 wird als Eingang konfiguriert und PC1 als Ausgang mit
0V. Jetzt wandert die Ladung aus dem Touch Kondensator
in Cs (welcher viel grösser ist und sich nur gering auflädt).
Es wird gewartet damit die Elektronen wandern können.
Wenn die Spannung am Cs ausreicht um vom AVR als 1 gelesen
zu werden wird die Schleife beendet.
Wenn nicht PC1 wieder als Eingang konfigurieren (Cs in die
Luft hängen) und Schleife von vorne.
Mit dem Touch Kondensator wird also Cs aufgepumpt.
Die Anzahl der Pumpvorgänge hängt von der "Größe"
des Touch Kondensator ab. Und die wiederum von seiner
Umgebung (Finger).
Man darf aber nur die Änderungen des Schleifenzählers auswerten und
nicht den Absoluten Wert, der ist nicht langzeit stabil.
Wichtig ist das die Pullups des AVRAUS sind (siehe SFIOR).
Peter Dannegger schrieb:
> @Travel Rec.>> Die Eingänge werden digital eingelesen, d.h. eine Drift der> Eingangsschwelle spielt keine Rolle?
Durch den implementierten Tiefpaß spielt das keine Rolle.
> Die Eingänge werden eingelesen, wenn alles tristate ist, muß das dann> nicht sauempfindlich gegen HF-Störungen sein?
Nö. Ich werte die Spannung im Cs aus, da gibt´s keine HF
> Und der Eingang, der später eingelesen wird, müßte störempfindlicher> sein.> Sollte man nicht besser erst die SBIS-Befehle machen und danach das> ADIW?
Konnte keinen Unterscheid feststellen, müßte man mal mit noch mehr
Tasten testen.
>> Könnte man die Schleife nicht schon abbrechen, wenn beide Eingänge low> sind?
Ja, aber das verändert die Laufzeit des Programms bei jedem Zyklus. So
kann man die Meßzyklen quasi auch als Timer für die nachgeschalteten
Tiefpässe nehmen -> starre Kopplung.
> Können die 33nF Keramik sein?> Wenn ja, die haben ja große Toleranzen und Drift, wirkt sich das auf die> Werte der beiden Tasten aus?> D.h. können die stark unterschiedlich sein?
Kein Problem. Tiefpaß und dynamische Auswertung der Abweichung vom
Mittelwert rechnen Toleranzen heraus. Zwischen 22n und 47n gab es keinen
nennenswerten Unterschied.
> Die Ausgänge TOUCH1A/2A werden nirgends gesetzt, müssen sie low sein,> oder ist das egal?
Die sind immer low. Sorry.
> Vom Prinzip her erinnert mich das an nen DAC mit geschalteten> Kondensatoren. Der Unterschied ist nur, daß beide Kondensatoren nicht> gleich groß sind, sondern stark unterschiedlich.> Das Prinzip hat man früher auch als Rampengenerator verwendet (ein> kleiner Kondensator lädt kleine Ladungen auf einen großen).
Ja, kann man so sagen.
> Letztendlich ist also auch eine Kapazitätsmessung. Die Frage ist nur,> welcher Unterschied sich bezüglich Bauelementedrift und Störspannungen> gegenüber anderen Meßmethoden ergibt.
Meinen Langzeittest hat die Schaltung schon überstanden. Läuft seit
August in unserem Badezimmer ;-)
>Ich habe es etwas geändert.>Es wird der Pin eingelesen, der nicht mit dem Pad verbunden ist und>während das Pad auf low gezogen wird. Damit können Störungen auf dem Pad>nicht die Lesung beeinflussen.
Mache ich doch auch :-)
Im Prinzip wurde es eigentlich schon erklärt, hier nochmal zum
Nachvollziehen:
Cs >> Cx : z.B. Cs = 10nF, Cx = 10pF (1000:1 ratio)
S1,S2 und S3 sind ja CMOS IO pins. Wenn man S1,S2 und S3 richtig
kontrolliert, kann man die Ladung in den Cx über Cs transferrieren.
Indem man das einige Male wiederholt, kann man Cx messen. Wobei messen
hier heißt eine relative Messung z.b. Änderung in Cx (delta Cx). Die
TouchLib wird hier z.b. so eingestellt, das ein delta Cx von 10
ausreicht, um ein Touch zu erkennen.
Jetzt gehts tiefer ins Detail:
1. S1: closed, S2: open, S3: closed -> Cx und Cs entladen
2. S1: open, S2: open, S3: open -> Float Cs
3. S1: open, S2: closed, S3: open -> Charge transfer
4. S1: open, S2: open, S3: open -> Float Cs / erlaubt settling time
5. S1: closed, S2: open, S3: open -> Vcs messen und Cx entladen
Nun wird bei 2 weitergemacht.
#1: Initialisierung, start der Akquisation (braucht etwas Zeit)
#2: Verhindert Durchfluß zwischen P und N-Kanal Transistor in der IO
Zelle
Sog. "Cross conduction ist ein Desaster für die Konservierung der
Ladung im Cs!
#3 Steigende Flanke am SNS Pin treibt die Ladung durch den Cs in den Cx
Das Kirchoffsche Gesetzt sagt, das derselbe Strom durch Cs und Cx
fließen muß, also ist die Ladung in beiden C dieselbe
#4 Wie bei 2
#5 Entladen des Cx durch das Einspannen des SNSK zu GND, der Vcs auf dem
SNS pin wird gemessen. Cs Ladung hat sich erhöht und wurde
"konserviert".
Die Wiederholung führt nun dazu dass die Ladung aus dem Cx in den Cs
gepumpt wird. Man stellt sich einfach einen großen Behälter vor, einen
kleinen Behälter füllt man nun mit Wasser und gießt das Wasser aus dem
kleinen Behälter in den großen. Das wiederholt man nun ein paar male.
Wenn man nun die Sensorfläche berührt, werden weniger Pulse benötigt,
die "burst time" ist kürzer. Wenn das Delta groß genug ist, wird ein
Touch als "erkannt" gemeldet.
Fangfrage: Was passiert wenn man etwas Wasser auf die Sensorfläche
drübergießt? ;-)
@Joe,
ahhhh, danke für die Ausfühliche Erklärung, jetzt hats bei mir "klick"
gemacht. Wenn man das mal Verstanden hat ist es eigentlich sehr einfach
das Prinzip. Maximaler Effekt bei wenig externen Bauteilen... Da haben
bei Qantum sicherlich etlichen Entwicklern Wochenlang die Köpfe geraucht
als die das Prinzip erstellt haben... ;-)
Zur Fangfrage mit dem Wasser:
Ich könnte mir vorstellen das der Sensor dann "betätigt" meldet, da das
Wasser ja auch die Kapazität der Sensorplatte erhöht. Liege ich richtig?
@Tim,
auch dir Danke für die Erklärung, die hat mir geholfen das ganze mal zu
Testzwekcne in einen Tiny13 zu integrieren (zwei-Kanalig). Ist zwar noch
ne Baustelle aber "gut Ding will weile haben" frei Nach Brösels Werner.
:-))
Roland
Nachdem nun die Wirkungsweise des Qtouch klar ist, stellt sich immer
noch die Frage, welche und warum sie Vorteile gegenüber anderen Methoden
der Kapazitätsmessung haben soll?
Sie hat zumindest einige Nachteile:
- es werden 2 IO-Pins benötigt
- es erfolgt eine größere Störaussendung auf den Sensor
- die Messung dauert länger und muß unter Interruptsperre erfolgen.
Wenn man sich die verschiedenen Applikationen bei Atmel ansieht, fällt
auch auf, welchen entscheidenden Einfluß der mechanische und elektrische
Aufbau auf die Eigenschaften hat. Warscheinlich ist dieser viel größer,
als der Einfluß der Meßmethode.
Ich hätte z.B. nicht vermutet, daß eine LED nahe dem Sensor die Messung
stören kann.
Peter
Noch eine Frage. Der Kondensator Cx, wo genau befindet der sich? Ist das
der menschliche Körper? Oder ist der Körper die eine Platte des
Kondensators und die Kontaktfläche die andere Platte?
Wenn der Charge Transfer stattfindet, wird ja die Ladung "ausgeglichen",
sodass beide Kondensatoren die gleiche Ladung haben. Wenn dann die
Kondensatoren wieder auf hochohmig geschaltet werden, wer lädt dann Cx
wieder auf? Der menschliche Körper?
Der Vorteil liegt denke ich mal darin, dass man nicht zwingend das
Gebilde als Schalter nutzen muss, sondern auch zum Beispiel als Touchpad
nutzen kann (Indem man die Ladung im Cs misst und nicht auf einen
Komparator gibt).
Oder man kann so Ipod-Like Slider damit machen.
So, ich hab mal beide Methoden ausprobiert, die Ladungspumpe (Qtouch)
und die Messung der Entladezeit über einen Widerstand.
Im Prinzip gehen beide, aber die Qtouch-Methode ist deutlich
störunempfindlicher, d.h. die Auslesungen sind sehr stabil.
Bedingt wird das durch die Tiefpaßwirkung des Integrationskondensators
und durch die Abtastung bei kurzgeschlossenem Sensorpad.
Ich hab die Schaltung allerdings auch unter verschärften Bedingungen
getestet, am Notebook, welches keinen Schukostecker hat, d.h. die ganze
Schaltung liegt auf 115V 50Hz gegen Erde (durch die Filter-Kondies vorm
Schaltnetzteil).
Das Qtouch ist also doch nicht nur Selters.
Ich hab 2 * 1,8k und nen 10nF genommen. Die Sensorfläche sind 4*4 Pads
einer Rasterplatine, Berührung auf der Bestückungsseite.
Es ergeben sich 382 Counts ungedrückt und 352 Counts gedrückt.
Peter
Mit einem größeren Integrations-C bekommst Du noch etwas weiter
auseinanderliegende Auslesungen für Touch und kein Touch, 22...33nF sind
optimal für 10Bit Auflösung. Hierbei können die Sensorflächen auch
größer sein.
Guten Mittag,
sorry dass ich dieses Thema hier nochmal rausziehe nur eine Frage habe
ich noch. Das Funktionsprinzip habe ich glaube ich soweit verstanden.
Nur hat es eine besondere Bewandniss dass für die beiden Pins zwei
unterschiedliche Ports verwendet werden?
Würde das gerne auf einem Atiny25 programmieren, da habe ich nur einen
Port zur Verfügung.
Vielen Dank schonmal.
Toni
Danke.
Ich habe ein Pad aus 3x3 Lochrasterpunkten gemacht.
uC ------ 1K ---- Pad
|
|
22nF
|
|
uC ---
Den 1k Widerstand und den 22nF habe ich als SMD Bauteile nahe ans Pad
gemacht und dann per Freiluftverdrahtung an den Controller
angeschlossen.
Am empfindlichsten ist die Fläche zwischen Pad und den beiden Bauteilen.
Auch die Leitung ist touchsensitiv, aber das steht ja schon in der
Appnote.
Mal sehen, ob man das so für irgendwas verwenden kann...
Guten Abend,
hab mich die letzten Tage auch nochmal daran versucht ... aber ich komme
auf keinen grünen Zweig :(. Ich wollte das ganze mit einem
Timerinterrupt programmieren, damit ich nicht die vielen delays
verwenden muss.
Habe mich dazu an die Beschreibung von Roland Z und Andreas Auer
gehalten. Nach dieser Beschreibung habe ich auch das Prinzip verstanden.
Jetzt frag ich mich bzw euch: wo habe ich den Fehler gemacht :) .. die
einzelden Schritte macht mein asm Programm in der Simulation genau
gleich wie der obige C-Code :/. Habe versucht alles möglichst
ausführlich zu kommentieren ... viel. entdeckt von euch jeamnd einen
Fehler :/ Mir gehen langsam die Ideen aus.
Die anzahl der Pulse beträgt immer 1 :/ ich versteh beim besten willen
nicht warum :(.
Schönen Abend noch.
Toni
Ich glaube nicht, daß das mit nem Timerinterrupt funktioniert.
Das sind ja nur sehr kleine Ladungen, wenn man da zu langsam schaltet,
ist die Selbstentladung zu hoch.
Es reichen die Delays durch die Ausführungszeit der Meßloop vollkommen
aus, um die wenigen pF umzuladen.
Nur für die Entladung des 33nF bis zur nächsten Messung sollte man etwas
Zeit lassen.
Hier noch ein Beispiel für 3 Tasten:
Hi,
hab mir jetzt mal eine Platine gemacht mit 3 Touchelementen (ca.
15x15mm² Touchfläche pro Element, 33n Messkondensator, 1k
Serienwiderstand zur Touchfläche) drauf. Funktioniert grundsätzlich
auch. Sehr gut funktioniert es natürlich wenn man direkt die durch
Lötstopplack geschützten Flächen berührt. Jedoch sinkt die
Empfindlichkeit drastisch, wenn man die Touchfläche hinter anderen
Materialien anbringt, sodass es kaum mehr möglich ist die Berührung zu
detektieren.
Deshalb wollt ich euch mal fragen wie eure Erfahrungen sind. Ich hab
gestern mal die Wirkung meines Fingers durch ein paar Materialien
untersucht (ein paar Seiten Papier, Cover einer CD) und war etwas
enttäuscht, da ich meist nur noch eine ganz geringe Änderung (Delta im
Bereich von 1 oder 2) messen konnte.
Ich wollte die Platine eigentlich hinter einer dünnen Plexiglasscheibe
montieren. Hat jemand sowas schonmal gemacht?? Wäre für jeden Tipp zur
Verbesserung dankbar!
mfg
Andreas
Andreas Auer schrieb:
> Deshalb wollt ich euch mal fragen wie eure Erfahrungen sind. Ich hab> gestern mal die Wirkung meines Fingers durch ein paar Materialien> untersucht (ein paar Seiten Papier, Cover einer CD) und war etwas> enttäuscht, da ich meist nur noch eine ganz geringe Änderung (Delta im> Bereich von 1 oder 2) messen konnte.>> Ich wollte die Platine eigentlich hinter einer dünnen Plexiglasscheibe> montieren. Hat jemand sowas schonmal gemacht?? Wäre für jeden Tipp zur> Verbesserung dankbar!Beitrag "Re: qtouch - sekt oder selters"
Und du hast auch einen Serienwiderstand zum Touchpad drin!? Bzw. deine
Schaltung sieht wie folgt aus??
------ ----
PORTx -----------+--------|______|---------| | Touchpad
| R |____|
----- C
-----
|
PORTy -----------+
Danke,
Andreas
Hi all,
bin gerade auf diesen Thread gestoßen und gleich eine Frage:
Travel Rec. schrieb:
> Nicht ganz. Ich habe noch ein zusätzliches R zwischen Portx und C, Wert> ist 2.2k. Der Widerstand zum Touchpanel ist bei mir 10k.
Wozu dient dieser Widerstand, Strombegrenzung beim Entladen?
Gruß Stefan
Natürlich geht es ohne die Widerstände. Aber durch den niedrigen
Portinnenwiderstand ist der Transfer-C dann sehr schnell aufgeladen und
es traten mehr Rauschanteile im Meßsignal aus. Das R zwischen Port und C
brachte sehr viel mehr Ruhe und eine größere Meßauflösung. Das R zur
Taste ist zum Dämpfen der Störaussendung und Verhindern von statischen
Entladungen in die Portpins gedacht. Wie gesagt.
Hallo,
ich hab das ganze mal aufgebaut und mit dem code von Andreas Auer
versucht. Das hat nicht funktioniert, nach einigen messungen und kleinen
anpassungen wurd es schon besser.
Mein problem ist ich bekomme nur einen unterschied von 1 bei berührung.
Mein erster aufbau war mit bedrahtetetn bauelementen, um das
auszuschliesen habe ich jetz das ganze in smd aufgebaut, was leider
keine verbesserung brachte.
Wenn ich den code ohne abruchbedingung (code zeile 111 sieht dann so aus
}while(i<510); ), laufen lasse und mir das ganze am osziloskop ansehe
ändert sich die Kurve bei berührung nur sehr gering.
noch kurtz zum aufbau:
- µC: Atmega8
- Touch fläche: ca. 15x15 mm mit tesa abgeklebt.
- Die messungen in den bildern habe ich zwischen GND und dem im
Schematic eingezeichnetetn messpunkt gemacht.
- Auf dem Osziloskop ist die untere kurve PB1 und kurzz nach der
steigenden flanke wird TA ausgewertet.
Nun meine frage hat jemand eine idee an was das liegen könnte?
Danke im voraus.
mfg
kr2
Ich finde die Peaks ziemlich breit, mehr als 200ns sollten sie nicht
sein, sonst ist der Speicherkondensator zu schnell voll. Deshalb ergibt
sich eine relative Unempfindlichkeit. Du brauchst mindestens 256 Pulse
(8-Bit) Auflösung, bis der Kondensator so weit geladen ist, daß der Pin
kippt. Die Pausen zwischen den Peaks ist auch recht lang, so daß sich
eine unnötig lange Meßzeit ergibt.
Ob das Timing kritisch ist, kann man überprüfen, indem man den CPU-Takt
halbiert (CLKPR entsprechend setzen).
Die Zählwerte dürfen sich nur wenig ändern.
Peter
Hi,
sehe ich das richtig, das man für dieses Projekt
1 Atmega8,
2 Kondensatoren von 22nF,
1 10K Widerstand und
eine Touchfläche von 15x15mm
benötigt.
Und ist der Code in C oder Bascom geschrieben. Wie gesagt habe ich noch
nicht viel am Hut mit proggen usw.
Wieviel Strom wird bei der Schaltung benötigt? Wären da auch mehrere
Flächen möglich. Habe irgendwo mal gehört, das der Mega nur einen
gewissen Strom aufnimmt (abgibt)von ca 100mA.
LG Lutz
hallo allerseits, ich würde gerne ein touch wheel verwirklichen und
wollte mal fragen ob irgendjemand ein layout zur verfügung stellen
könnte...
habe hier nur eine datei gefunden wo schon die fertigen gerberdaten
vorhanden waren.... wäre echt super
schönen gruß sebi
Moin,
Du hast schon Gerberdaten? Wo ist dann das Problem?
Das nach einem Gerber-Plot im Layoutprogramm der Wahl nachzubauen,
sollte doch nicht wirklich schwierig sein.
ggf. lassen sich die Daten sogar auf irgendeinem Weg als Vektorsymbol
ins Layoutprogramm importieren...
Zusätzlich würde ich noch einen Blick in das
Touch_Sensors_Design_Guide von Atmel werfen:
http://www.atmel.com/dyn/resources/prod_documents/doc10620.pdf
die gehen darin auch auf Probleme wie den ESD-Schutz ein.
Nachtrag: Für EAGLE gibts ein Tool, um Grafikdaten in diversen Formaten
(auch Gerber) zu importieren: EAGLE PCB Power Tools V5.06 ->
http://www.cadsoft.de/cgi-bin/download.pl?page=/home/cadsoft/html_public/download.htm.de&dir=eagle/userfiles/misc
Gruß,
Thorsten
danke für die schnelle antwort, dachte nur dass jemand dass vl als pcb
layout hat...
das mit dem importieren klappt dann wohl bei mir nicht da ich nicht mit
eagle arbeite...
dann muss ich es wohl selbst zeichnen...
gruß sebi
Hier der Versuch, die qtouch-Variante in Bascom umzusetzen.
1
$regfile = "m8def.dat"
2
$crystal = 8e6
3
$baud = 9600
4
5
$hwstack = 32 ' default use 32 for the hardware stack
6
$swstack = 32 ' default use 10 for the SW stack
7
$framesize = ' default use 40 for the frame space
8
9
Dim Cycles As Byte
10
11
'PC5--- 2K2 ---+---- 100K ---- Touchpad
12
' |
13
' ---
14
' --- 22n
15
' |
16
'PC4-----------+
17
18
Do
19
Cycles = 0
20
21
'Alles Entladen
22
'beide out - beide low
23
Ddrc.5 = 1 : Portc.5 = 0
24
Ddrc.4 = 1 : Portc.4 = 0
25
26
'auf vollstaendige Entladung warten
27
Waitus 5
28
29
Do
30
31
'beide als tristate inp schalten, damit keine Ladung abfliessen kann
32
Ddrc.5 = 0 : Portc.5 = 0
33
Ddrc.4 = 0 : Portc.4 = 0
34
Waitus 5
35
36
'PC4 Out und high schalten, um C aufzuladen
37
Ddrc.4 = 1 : Portc.4 = 1
38
Waitus 2
39
40
'und wieder aus
41
Ddrc.4 = 0 : Portc.4 = 0
42
43
'Die Ladung aus C jetzt nach PD5 auf GND abfuehren
44
Ddrc.5 = 1 : Portc.5 = 0
45
46
'messen, ob Ladung schon fuer eine 1 an PD4 reicht, sonst von vorn
47
If Pinc.4 = 1 Then Goto Printout
48
Incr Cycles
49
50
Loop Until Cycles >= 254 'wiederholen und im Zweifel beenden
51
52
Printout:
53
Print Cycles
54
Waitms 100
55
56
Loop
Es ergeben sich Werte zwischen 15 und 25 ungedrückt und 40 - 80 gedrückt
(Direkter Kontakt).
Als Sensor verwende ich eine Kotflügelscheibe mit 30mm Durchmesser.
Allerdings ergibt sich bei Verwendung einer isolierenden Folie kaum noch
ein messbarer Ausschlag.
lg,
arne
ich hab das ganze grade mal schnell aufgebaut.
ein kurzes video findet man auf Youtube:
http://www.youtube.com/watch?v=z3nLNGeyadU
Aufbau:
- Schaltung auf der Rückseite von einer Lochrasterplatine
- Vorderseite Tastenlayout mit Papier beklebt
------ ----
PORTx -----------+--------|______|---------| | Touchpad 4x4
Lötraster
| R = 1Kohm |____|
-----
----- C = 33nF
|
PORTy -----------+
Code von peter Dannegger:
1
include<avr\io.h>
2
#include<util\atomic.h>
3
4
#define SK_A0 (1<<5)
5
#define SK_B0 (1<<4)
6
#define SK_A1 (1<<2)
7
#define SK_B1 (1<<3)
8
#define SK_A2 (1<<0)
9
#define SK_B2 (1<<1)
10
#define SK_A012 (SK_A0 | SK_A1 | SK_A2)
11
#define SK_B012 (SK_B0 | SK_B1 | SK_B2)
12
#define MAX_CYCLE 2000
13
14
uint16_tkeys[3];
15
16
voidread_senskey(void)
17
{
18
uint16_ti=MAX_CYCLE;
19
uint8_ta,b,x,y;
20
21
ATOMIC_BLOCK(ATOMIC_FORCEON){
22
a=DDRA&~(SK_A012|SK_B012);
23
b=PORTA&~(SK_A012|SK_B012);
24
y=SK_B012;// input mask
25
do{
26
DDRA=a;// tristate
27
PORTA=b|SK_B012;
28
DDRA=a|SK_B012;// Bx = strong high
29
DDRA=a;// tristate
30
PORTA=b;
31
DDRA=a|SK_A012;// Ax = strong low
32
if(--i==0)// timeout
33
break;
34
x=y&PINA;// not immediately after set DDRA !!!
35
if(x){
36
if(x&SK_B0)
37
keys[0]=i;
38
if(x&SK_B1)
39
keys[1]=i;
40
if(x&SK_B2)
41
keys[2]=i;
42
}
43
y^=x;// clear processed input
44
}while(y);// all inputs done
45
DDRA=a|SK_A012|SK_B012;// discharge
46
}
47
}
Funktioniert super!!
Es funktioniert auch, wenn ich zwischen den Tasten und meinem Finger
noch eine 3mm Plexiglasscheibe lege.
Die Scheibe sollte dafür mit auf die Lochrasterplatine geklebt sein -->
also kein Luftspalt, wegen Ladungsausbreitung
Eine genaue Beschreibeung folgt dann auch noch bald.
martin
Hi Martin,
tolle Sache dein Touchfeld.
Könntest du bitte deinen Quellcode (auch den Rest) zeigen, denn
irgendwie will das ganze bei mir nicht so recht funktionieren. Mit
welchem Takt läuft dein System?
MFG Fred
Das hier ist der Code für die Auswertung der 3 tasten.
hat jemand eine Idee wie man am besten und einfachsten solch ein
Touch-Scrollrad sinnvoll auswerten kann?
Die einzelnen Sensoren funktionieren.
Ist ein Sensorfeld betätigt, also aktiv, so wird bei der Abfrage eine 1
zurückgegeben, ansonsten eine 0.
Das Scrollrad besteht aus 9 einzelnen Touchsensoren.
Ich habe mir zwar schon einige Gedanken gemacht, aber so richtig bin ich
auf noch keine Idee gekommen, wie es am besten gehen könnte.
Danke martin
is mir dann doch etwas zu teuer ;-)
aber ne idee zum auswerten von solch einem Touch Scrollrad hat wohl
keiner?
--> Das Scrollrad besteht aus 9 einzelnen Touchsensoren.Ist ein
Sensorfeld
betätigt, also aktiv, so wird bei der Abfrage eine 1 zurückgegeben,
ansonsten eine 0.
Ich hab grade noch eine Autokallibrierung für Touchsensoren hinzugefügt.
Die Basis bildet eine gleitende Mittelwertberechnung der Sensorwerte,
wenn der Sensor nicht aktiv ist.
--> Sensor aktiv = Messung > kallibrier_Mittelwert + 20;
Code muss ncoh bisschen überarbeitet werden.
Bis dann
über Ideen zu dem Scrollrad würd ich mcih freuen.
Hallo zusammen
Hab gerade die Sache auf einem MSP430 zum laufen gekriegt und endlich
mal das "eZ430-F2013 Development Tool" einsetzen können, welches schon
seit Jahren im Schrank verstaubt...
Dankeschön an alle die ihre Erfahrungen hier geteilt haben!
Habe übrigens auch die Schaltung mit dem 1k Widerstand und 33n
Kondensator verwendet.
Hab den Bascom-Code vom Andi mal auf meinem Atmega8 überspielt. Leider
funktioniert das Ganze bei mir nicht.
Kann es sein, dass in dem Code viel zu viel auskommentiert wurde? z.b.
wurden sämtliche Wartezeiten auskommentiert, was sicherlich nicht
richtig sein kann. Nach dem Entladen muss man doch immer warten.
Muss mich korrigieren. Der Bascom-Code läuft ganz hervorragend.
Allerdings musste ich "Cycles" als word deklarieren, weil es ungedrückt
ca 410 ist.
Ansonsten dickes Dankeschön.
Ich habe die application notes und design guides von Quantum gelesen und
habe nicht herausgefunden, ob man ohne weiteres auch multiplexer
verwenden kann. Hat hier jemand erfahrungen gemacht?
Es geht mir vor allem darum auf einem grösseren Board Leiterbahnen
einzusparen. Das PCB ist sehr lange, aber schmal und es sollten doch
etwa 15 Tasten realisiert werden :-). Was passiert wohl mit dem Signal
wenn ich 2 Mux hintereinander schalte, aber immer mit denselben Pins
auslese?
Ich habe noch ein Symbolbild angehängt, MCU wäre ganz rechts auf dem
PCB, der letzte Sensor ganz links. Die mux steuerleitungen könnten
eventuell auch mit einem Schieberegister betrieben werden.
Grüsse
Hier wurde ja schon mehrfach die Funktionsweise von qtouch erklärt, doch
ist mir noch nicht ganz klar wie Cx in einer batteriebetriebenen
Schaltung (also wo GND nicht Erde ist) aufgeladen werden kann. Wenn Cx
aufgeladen wird müsste doch ein geschlossener Stromkreis existieren, was
nach meinem Verständnis hier nicht der Fall ist. Bin dankbar, wenn mir
jemand erklären könnte wie bzw. wodurch Cx aufgeladen wird.
Gruß
Übrigens, das Schöne an der Methode ist, die Umladungsschleife kann
jederzeit für (relativ kurze Zeit) unterbrochen werden (durch
Interrupts), ohne dass sich etwas ändert (da die Ladung ja erhalten
bleibt, abgesehen von Leckströmen - deshalb ist die Zeit trotzdem kurz
zu halten).
Ich habe mit dem usb-Stack von obdev auf einem attiny2313 eine simple
usb-"Tastatur" (mit nur einer Taste) mit dem qtouch-Prinzip gebaut, es
funktioniert einwandfrei, obwohl die Messroutine jederzeit vom
einkommenden usb-Poll unterbrochen werden kann.
Gruß,
droelf
Peter B. schrieb:> Hier wurde ja schon mehrfach die Funktionsweise von qtouch erklärt, doch> ist mir noch nicht ganz klar wie Cx in einer batteriebetriebenen> Schaltung (also wo GND nicht Erde ist) aufgeladen werden kann. Wenn Cx> aufgeladen wird müsste doch ein geschlossener Stromkreis existieren, was> nach meinem Verständnis hier nicht der Fall ist.
Das ist auch nicht nötig.
Ein Kondensator speichert Elektrische Energie in einem el. Feld indem er
Elektronen auf seinen Elektroden verteilt. Bis auf Nebeneffekte wandert
kein Elektron durch einen Kondensator hindurch. Ein Kondensator ist also
immer eine Unterbrechung des Stromkreises und es dürfte mit diesem
klassischen Leitsatz zu keinem Strom kommen.
Durch den Potentialdruck werden aber auch den Elektroden die Elektronen
näher zusammengeschoben, abhängig davon, wie sich die elektrischen
Feldlinien ausbilden können. Das liegt an Form, Größe und Material und
Ladung(~Potentialdruck) der Umgebung. Diese Veränderung wird über die
Anzahl der Ladezyklen registriert. Der Strom fließt also "nur" weil sich
Elektronen anders verteilen nicht, weil sie einem Kreislauf im
herkömmlichen Sinne folgen. Ihre Menge bleibt innerhalb des Teilsystems
gleich. Ein Ladungstransfer also Strom von System-qTouch und System-Erde
findet nicht statt.
Martin J. schrieb:> beschreibst du deinen aufbau ncoh etwas genauer mit bilder, zeichungen> software .... ?
Anbei die Software sowie ein Bild des Aufbaus. Die Software besteht
hauptsächlich aus dem 1-Key-Keyboard mit dem VUSB-Stack von hier:
http://blog.flipwork.nl/?x=entry:entry081009-142605
Informationen zur Beschaltung finden sich in der main.c im zip.
Ich verwende einen ATTiny2313 mit 16MHz, mit 3,3V, die ich aus USB und
einem Festspannungsregler (ist auf der Rückseite der Platine, deshalb
nicht sichtbar) gewinne.
Ebenso auf dem Bild ist die serielle Debugschnittstelle zu sehen. Erste
Versuche den AVR direkt mit 5V zu betreiben (und Z-Dioden an den
USB-Pins) lieferten recht verrauschte Messwerte, mit dem Spannungsregler
geht das wesentlich besser.
Die Sensorplatte ist einfach ein ca. 1,5cmx3cm großes Metallplättchen,
welches auf einem Stück Plastik in ca. 1,5cm Höhe über der Platine
angebracht ist.
Die Firmware ist sehr schnell zusammengehackt und nicht sonderlich
schön, zumal ist der Tiny mit dem USB-Stack schon ziemlich voll, aktuell
haben nur noch 2 Bytes Platz im Flash.
Im Unterschied zu anderen Beispielen verwende ich den eingebauten
Komparator, um die Aufladeschwelle zu erkennen (habe aber keine Versuche
gemacht, ob das was bringt ggü. normalem Portpin). Die
Signalverarbeitung der Rohdaten sieht folgendermaßen aus:
- Vergleich, ob der gemessene Rohwert unter Vergleichswert minus
Threshold liegt (der Threshold ist über das "#define th 5" einstellbar).
- die Ausgabe dieses Vergleichs geht in ein 8-Bit Schieberegister, d.h.
es werden immer die letzten 8 Messungen berücksichtigt.
- Nur wenn dieses SR mehr als "#define filtth 6" Nullen bzw. Einsen
enthält wird abhängig vom aktuellen Zustand in einer fsm in den anderen
übergegangen.
Damit erreiche ich eine sehr stabile Auswertung ohne Fehlauslösungen,
schon bei knapp unter 1cm Entfernung eines Fingers zur Sensorplatte.
Solange die Taste "gedrückt" wird, wird einfach eine gedrückte
Space-Taste ausgegeben.
Was noch fehlt, ist u.A. eine ständige Nachkalibrierung, bisland wird
nur einmal beim Start der Schnitt von 8 Messungen genommen als
Vergleichswert. Leider ist jedoch wiegesagt der Platz sehr beschränkt,
ich habe bereits die Vendor- und Device-Strings auf nur je 2 Zeichen
gekürzt, um mehr Platz zu haben ;-).
Gruß,
droelf
Nachtrag: Es werden alle nicht benötigten Pins auf Ausgang und 0
geschaltet, ich hatte mit dem seriellen Kabel angesteckt, aber uart-tx
nicht an (das tx-Pin also auf Eingang) eine Verschlechterung der
Empfindlichkeit festgestellt.
Außerdem habe ich noch auf der Lochrasterplatte die Lötinseln rund um
die beiden benötigten Pins, den Kondensator und den Widerstand zur
Sensorfläche weggekratzt, um eben möglichst wenige zusätzliche
Kapazitäten an der Sensorplatte zu haben.
Hallo,
ich hab mir hier aus dem Thread mal die sense_key Funktion von Andreas
Auer (Beitrag "Re: qtouch - sekt oder selters") geholt und
zwischen Port C0 und C1 10nF und daran über 1kohm eine Touchfläche mit
20x20mm.
Das Ergebnis der sense_key Funktion soll nun auf dem LCD ausgegeben
werden. Dies funktioniert auch soweit aber leider wird immer nur eine
Null angezeigt.
1
#include<avr/io.h>
2
#include<stdio.h>
3
#include<stdlib.h>
4
#include<inttypes.h>
5
#include<util/atomic.h>
6
#include<oldmacros.h>
7
#include"lcd-routines.h"
8
#include<util/delay.h>
9
#define TAKT 16000000UL;
10
11
staticintsense(void)
12
{
13
unsignedchari=0;
14
DDRC=0x00;
15
PORTC=0x00;
16
17
DDRC|=_BV(PC1);
18
DDRC|=_BV(PC0);
19
_delay_us(5);
20
DDRC&=~_BV(PC1);
21
DDRC&=~_BV(PC0);
22
23
PORTC|=_BV(PC0);
24
for(i=0;i<255&&!(PINC&_BV(PC0));i++)
25
{
26
DDRC|=_BV(PC0);
27
_delay_us(5);
28
DDRC&=~_BV(PC0);
29
DDRC|=_BV(PC1);
30
_delay_us(20);
31
DDRC&=~_BV(PC1);
32
}
33
DDRC|=_BV(PC1);
34
DDRC|=_BV(PC0);
35
PORTC=0x00;
36
37
returni;
38
}
39
40
41
intmain(void)
42
{
43
44
while(1)
45
{
46
lcd_init();
47
lcd_string("Sensekey:");
48
lcd_data(sense());
49
lcd_setcursor(0,2);
50
51
{
52
charBuffer[20];
53
itoa(sense(),Buffer,10);
54
lcd_string(Buffer);
55
}
56
}
57
}
Was mache ich falsch?
Meine Sensorfläche ist einfach ein Stück Leiterplatte mit Tesa darauf
als Berührungsschutz, also nur eine Kupferfläche. Ich hab mir auch schon
mal den Designguide von Atmel angesehen, aber wurde auch nicht schlau
daraus.
Vielen Dank schon mal im Vorraus
Update:
Ich hab jetzt ne Sensorfläche dran wo aussen rum ein streifen geerdet
ist und die Fläche hängt am Capture bin.
Der Wert am Display ändert sich allerdings nur wenn ich mit dem Finger
direkt auf die Platine zwischen GND und der Sensorfläche drücke von 0
auf so an die 30 mein Kondensator zwischen den beiden Ports hat 100nF.
Hat jemand ne Idee für diesen Fehler? Warum ist das so?
Johannes Huber schrieb:> Was mache ich falsch?
Vielleicht solltest Du mal Deinen Code kommentieren. Das macht es
anderen und vor allem Dir einfacher zu sehen, was er macht und ob das
richtig ist.
Kombibedingungen im for()-Ausdruck halte ich für besonders
unübersichtlich.
Gibt es weitere Abbruchmöglichkeiten, nehme ich dafür ein break.
Und Du mußt schon sagen, was Du wo angeschlossen hast, ein Schaltplan
wäre natürlich noch besser.
Und statt nichtssagenden PC0, PC1 usw. nenne ich die Portpins nach ihrer
Funktion.
Dann ist es auch einfacher, die Pins zu wechseln.
Mindestens ein Fehler ist, daß Du den einen Pin ständig auf high läßt,
dadurch lädt Dir der interne Pullup den Kondensator sofort auf, so kanns
nicht gehen.
Peter
Sorry,
ich hab gestern nur in aller schnelle vl ein bisschen unüberlegt
gepostet also nochmal:
Ich benutzte nen Mega8 am Capture PIN PB0 hängt über 1kohm die
Touchfläche und zwischen PB1 und PB0 hängt bei mir ein 100nf Elko.
1
#include<avr/io.h>
2
#include<stdio.h>
3
#include<stdlib.h>
4
#include<inttypes.h>
5
#include<util/atomic.h>
6
#include<oldmacros.h>
7
#include"lcd-routines.h"
8
#include<util/delay.h>
9
10
staticintsense(void)//Funktion aus Andreas Auers Beitrag auf nen Mega8 angepasst
Hi @All
Ich habe mal versucht den code auf einen Atmega8 zu übertragen, aber
iergendwie klappt das alles nicht, habe leider auch Kein LCD was ich zum
laufen bekomme, könnte mal jemand nen kompletten C code für nen atmega8
posten, an einem Port einfach LED's geschaltet werden?
Währe nett wenn ihr mir helfen könntet
MfG
NickJag
hier hast du nochmal alles schön zusammengefasst...
damit sollte man das schon hinbekommen
nen beispiel gibt es glaub ich auch noch weiter unten auf der Seite
Ich habe heute auch angefangen, mit QTouch rumzuexperimentieren.
Habe auf Lochraster einen ATmega8 und ein 4x4-Rasterfeld für einen
Touch-Key neben minimalst-Beschaltung des mega ( ja, nicht einmal die
Abblock-Kondensatoren habe ich drin ).
Eine LED signalisiert, wenn man am Key rumdrückt/sich in der Nähe
aufhält.
Der Code von Andreas Auer hat mir leider immer nur 0 zurückgeliefert,
aber mit dem Code von Peter Dannegger läuft es nun ( musste MAX_CYCLE
nur anpassen, vielen Dank nochmal ).
Mein Aufbau ist alles andere als Ideal ( 100nF Kondensator, hatte gerade
keinen besser passenden da ), trotzdem ist es für einen ersten Test
wunderbar.
Werde das ganze demnächst auf einer geätzten Platine ( mit richtigen
Werten und "guter" Beschaltung ) aufbauen, und habe prompt eine Frage
...
Hat einer von euch schon einen Slider ( 3 Channels ) zum laufen bekommen
( am liebsten ohne die Lib von Atmel ) ? Wie müsste man die 3 Werte
miteinander verrechnen, um einen schönen linearen Weg zu haben ?
nein ich bin noch nciht wieder dazu gekommen, aber würde mich über deine
erfahrungen freuen.
mit der atmel lib hab ich mich noch nicht groß beschäftigt
Kann evtl. einer von euch nen Quellcode posten mit dem man mit einem
Sensorfeld ne LED zum leuchten bringen kann?
Muss die elektrode noch zusätzlich an GND oder so angeschlossen werden?
Quellcodes wurden ja schon mehrere gepostet.
Musst ggf. noch den LED-Teil dazucoden, aber das kriegt ja wohl jeder
Anfänger hin ;)
Die Elektrode sollte bloß nicht an GND, sonst kriegst du gar nix mehr
mit.
http://www.atmel.com/dyn/resources/prod_documents/doc10620.pdf
Dort ist alles über Elektroden erklärt, was man für den Anfang wissen
muss.
Hallo,
nimm den Code von Peter Dannegger
Beitrag "Re: qtouch - sekt oder selters"
der reicht für deine Zwecke völlig aus, kann sogar 3 Tasten auswerten.
Rufe die Funktion Sense_key in deiner main datei auf und lege den
Schwellwert fest welchen die Sensorfläche liefern muss.
Zum testen des Schwellwerts ist die Ausgabe der kapazitiven Tasten auf
ein LCD Display super, da man einfach die Werte ablesen kann.
Nein, die Sensorfläche muss nicht zusätzlich auf GND gelegt werden.
allerdings erhöht ein Kondensator gegen Erde die Empfindlichkeit der
Platte habe ich festgestellt.
Hallo,
meiner Meinung passt dein Code für einen ersten Test mit einer LED
allerdings den Wert keys[0]>1 finde ich etwas unrealistisch =)) bei
einer sensorplatte von 20x20mm und einem 100nf Kondensator habe ich
werte um die 1500 wenn sich keine Hand in der Nähe befindet oder
sonstige Störfaktoren.
Am besten du holst dir deinen Wert mit nem LCD display und trägst diesen
dann entsprechend ein, oder schreibst dir ein unterprogramm welches
einige male den wert von keys[0] misst und diesen dann in einer varible
speichert zu beginn deines Programms und dann bei einer Abweichung nach
oben von so ca. 20 von dem gespeicherten Wert in der Variable auslöst
oder du machst es echt mit nem LCD.
Das ist im Moment die einfachste Lösung meiner Meinung nach.
Ich würde auch noch ne kleine Warte Funktion direkt nach dem Einschalten
der LED einfügen da Sie sonst so schnell wieder ausgeht dass du gar
nicht mitkriegst dass se ein war ;)
OK das hört sich gut an, an welche pins muss ich nach dem Programm von
Peter an das Touchpad anschließen? Seh da noch nicht wirklich durch:
#define SK_A0 (1<<5)
#define SK_B0 (1<<4)
#define SK_A1 (1<<2)
#define SK_B1 (1<<3)
#define SK_A2 (1<<0)
#define SK_B2 (1<<1)
Sind das auch die Ports A0 A1 A2 B0 B1 und B2???
Zwischen Port A0 und Port B0 den Kondensator, da laut Datenblatt des
Mega8 B0 dein Capture PIN ist schließt du da deine Sensorfläche an
A0 B0 ist ein Paar
A1 B1 und A2 B2 bilden ein Paar wo jeweils eine Taste angeschlossen
werden kann.
Es funktioniert! Das merkwürdige daran ist das ich das Touchpad an Pin
A4 und Pin A5 vom Mikrocontroller angeschlossen habe. Den Keys Wert habe
ich wie folgt eingestellt durch testen:
if( keys[0]>1887 )
Kann es sein das die Belegung wie folgt ist?
#define SK_A0 (1<<5) //Pin A5
#define SK_B0 (1<<4) //Pin A4
#define SK_A1 (1<<2) //Pin A3
#define SK_B1 (1<<3) //Pin A2
#define SK_A2 (1<<0) //Pin A1
#define SK_B2 (1<<1) //Pin A0
Servus,
wollte das q-touch Programm jetzt mal in ein anderes Programm einbinden,
ging auch so weit ganz gut, mein neues Problem: Ich benötige den Port A
für meinen ADC, also habe ich das Touch-Pad einfach an Port C
angeschlossen und folgendes geändert:
/*Definition für Touch Pad*/
#define TP1_A (1<<0) //
#define TP1_B (1<<1) //
#define TP2_A (1<<2) //
#define TP2_B (1<<3) //
#define TP3_A (1<<4) //
#define TP3_B (1<<5) //
#define TP4_A (1<<6) //
#define TP4_B (1<<7) //
#define TP1234_A (TP1_A | TP2_A | TP3_A | TP4_A)
#define TP1234_B (TP1_B | TP2_B | TP3_B | TP4_B)
#define MAX_CYCLE 2000
uint16_t keys[4];
void read_senskey( void )
{
uint16_t i = MAX_CYCLE;
uint8_t a, b, x, y;
ATOMIC_BLOCK(ATOMIC_FORCEON){
a = DDRC & ~(TP1234_A | TP1234_B);
b = PORTC & ~(TP1234_A | TP1234_B);
y = TP1234_B; // input mask
do{
DDRC = a; // tristate
PORTC = b | TP1234_B;
DDRC = a | TP1234_B; // Bx = strong high
DDRC = a; // tristate
PORTC = b;
DDRC = a | TP1234_A; // Ax = strong low
if( --i == 0 ) // timeout
break;
x = y & PINC; // not immediately after set
DDRA !!!
if( x ){
if( x & TP1_B )
keys[0] = i;
if( x & TP2_B )
keys[1] = i;
if( x & TP3_B )
keys[2] = i;
if( x & TP4_B )
keys[3] = i;
}
y ^= x; // clear processed input
}while( y ); // all inputs done
DDRC = a | TP1234_A | TP1234_B; // discharge
}
}
Das erste der 7 Touchfelder funktioniert auch weiter einwandfrei, das
zweite und dritte reagiert nicht mehr auf die Berührung und das vierte
geht gar nicht.
Woran könnte das liegen? Kann man das Touchfeld evtl. nur an Port A
betreiben? Habe das Pollin-Board falls das irgendwie hilft.
Gruß Andi
Hallo Andi,
ändere mal DDRC und PORTC überall auf DDRA und PORT A dann sollte es
funktionieren.
Und warum hast du 7 Touchfelder? Mit deinem geposteten Code kannst du
maximal 4 haben oder?
Ich hofffe ich konnte dir helfen.
Gruß Sepp
Entschuldigt bitte, wenn ich diesen Thread noch einmal raus krame, aber
ich komme nur zu sehr unbefriedigenden Ergebnissen. Ich bin in C nicht
so fit, wie ich es gern wäre, aber ich glaube eigentlich alles korrekt
umgesetzt zu haben:
1
voidGetCap(void){
2
3
wdt_reset();
4
5
sens=MAX_CYCLE;
6
uint8_ta,b;
7
8
9
ATOMIC_BLOCK(ATOMIC_FORCEON)
10
{
11
a=DDRB&~(_BV(B_SENS)|_BV(B_VGND));// contains DDRB with all unused bits
12
b=PORTB&~(_BV(B_SENS)|_BV(B_VGND));// contains PORTB with all unused bits
13
14
do
15
{
16
DDRB=a;// both inputs floating
17
PORTB=b|_BV(B_SENS);// prepare charging
18
DDRB=a|_BV(B_SENS);// charge sens
19
DDRB=a;// weak high
20
PORTB=b;// floating
21
DDRB=a|_BV(B_VGND);// transfer load
22
if(--sens==0)// failed
23
break;
24
}
25
while(bit_is_clear(PINB,B_SENS));// complete
26
DDRB=a|_BV(B_SENS);// discharge
27
}
28
}
Ich bekomme auch eine Reaktion, aber die Ergebnisse schwanken mehr, als
ich erwarten würde. Ich habe einmal eine Grafik angehängt, die die
Messwerte darstellt. Sowohl die Idle, als auf die Touch-Phase sind sehr
unruhig; kann man auswerten, aber das soll doch so nicht aussehen, oder
?
Ich bin für jeden Gedanken und jede Anregung dankbar :)
Vielen Dank, Stefan
Also ich weiß nicht genau wie das bei mir aussieht. Ich kann mal
schauen, dass ich mir auch diese Werte ausgeben lasse und dann kann ich
mehr dazu sagen, ob das bei dir normal ist oder nicht!
Vom Programm her könnte ich jetzt nichts besonderes feststellen!
mfg
Andreas
Es könnte helfen, wenn Du das Programm compilierbar postest.
Also mit allen nötigen Variablen, Defines und Includes und als Anhang.
Und der Schaltplan wäre auch nicht zu verachten.
Peter
Hat von euch schon jemand nen Vergleichstest verschiedener Sensorflächen
gemacht? Bis jetzt hab ich nur Kupfermünzen als Sensorfläche
verwendet...funktioniert zwar ganz gut, aber gibts da vielleicht etwas
besseres? Das ganze soll hinter eine 4mm Plexiglasscheibe
Hi,
also ich hab vor kurzem einen Prototypen mit 3 Sensortasten gebaut. Die
Sensorflächen sind quadratische Kupferflächen direkt auf der Platine mit
ca. 1,2cm x 1,2cm und mit Lötstopplack bedeckt.
Die Tasten sind hinter 2mm Plexiglas und 2mm Luftspalt ist zwischen
Sensorfläche und Plexiglas auch noch. Funktioniert einwandfrei.
Ich mach die Messung aber nicht in Software sondern mit den fertigen
Chips von Atmel AT42QT1010.
Ach ja... hab ich noch vergessen. Ich hab auch noch eine Bohrung mitten
in der Sensorfläche wo ich eine LED durchscheinen lasse.
mfg
Andreas
Kann man diese Charge-Transfer Methode uneingeschränkt verwenden, oder
hält jemand (Atmel) Patente? Oder gelten etwaige Einschränkungen nur für
deren Bibliothek?
Hans schrieb:> Kann man diese Charge-Transfer Methode uneingeschränkt verwenden, oder> hält jemand (Atmel) Patente? Oder gelten etwaige Einschränkungen nur für> deren Bibliothek?
Atmel verfolgt die Philosophie, die Anwender der verschiedensten
Bausteine mit Applikationen zu unterstützen. Daher kann man das
qTouch-Prinzip überall und uneingeschränkt anwenden. Bei den Lehrgängen
zu dem Thema wurde dies auch ausdrücklich betont ;-)
Bernhard B. schrieb:> Das ganze soll hinter eine 4mm Plexiglasscheibe
Gar kein Problem. Die Flächen müssen nur groß genug sein. In deinem Fall
etwa 2cm Kantenlänge bei quadratischen oder 3cm Durchmesser bei runden
Flächen. Die Kapazität des Ladekondensators sollte in dem Fall etwas
höher gewählt werden.
Andreas Auer schrieb:> Die> Sensorflächen sind quadratische Kupferflächen direkt auf der Platine mit> ca. 1,2cm x 1,2cm und mit Lötstopplack bedeckt.> Die Tasten sind hinter 2mm Plexiglas und 2mm Luftspalt ist zwischen> Sensorfläche und Plexiglas auch noch. Funktioniert einwandfrei.
Das klingt echt gut, ich denke ich werde das ebenfalls mit den
Kupferflächen probieren. Ist einfach & billig. Danke!
Andreas Auer schrieb:> Ach ja... hab ich noch vergessen. Ich hab auch noch eine Bohrung mitten> in der Sensorfläche wo ich eine LED durchscheinen lasse.
Rein aus Interesse: Wie groß hast du das Loch gemacht?
Knut Ballhause schrieb:> Gar kein Problem. Die Flächen müssen nur groß genug sein. In deinem Fall> etwa 2cm Kantenlänge bei quadratischen oder 3cm Durchmesser bei runden> Flächen. Die Kapazität des Ladekondensators sollte in dem Fall etwas> höher gewählt werden.
Ok, dann werde ich die Fläche quadratisch machen, das ist mechanisch
einfacher herzustellen. Bezüglich der Kapazität: Ich hätte da an
irgendetwas zwischen 33nF und 50nF gedacht. Passt das?
Danke!
Bernhard B. schrieb:> Bezüglich der Kapazität: Ich hätte da an> irgendetwas zwischen 33nF und 50nF gedacht. Passt das?
Je größer im Verhältnis zur Kapazität der Sensorfläche, desto länger
braucht die Messung.
Bernhard B. schrieb:> Rein aus Interesse: Wie groß hast du das Loch gemacht?
Ich hab jetzt meine Eagle Files nochmal angesehen... und zwar war meine
Sensorfläche 14mm x 10mm groß. Und die Kreisfläche ohne Kupfer (ist ja
etwas größer als die Bohrung selbst) hatte einen Durchmesser von ca.
3mm.
Als Kondensator hab ich 33nF verwendet. War ohne Plexiglas und Luftspalt
sehr sehr empfindlich. Mit Plexiglas und Luftspalt hats dann gepasst.
Bessere wäre bei mir auch gewesen, wenn die Platine direkt am Plexiglas
aufgelegen wäre (war nicht möglich, da noch ein OLED Display dazwischen
war). Der Luftspalt ist sehr ungünstig. Sollte also in deinem Fall ganz
leicht funktionieren.
mfg
Andreas
Hans schrieb:> Je größer im Verhältnis zur Kapazität der Sensorfläche, desto länger> braucht die Messung.
Stimmt, aber nur so kann man große Flächen überhaupt messen und eine
gescheite Reichweite erzielen. Ist die Fläche zu groß und der
Kondensator zu klein, gibt es zu wenig Hub, den man auswerten könnte.
Ist also alles ein wenig experimentell, aber wenn man die richtigen
Werte hat, sehr zuverlässig.
Andreas Auer schrieb:> Ich hab jetzt meine Eagle Files nochmal angesehen... und zwar war meine> Sensorfläche 14mm x 10mm groß. Und die Kreisfläche ohne Kupfer (ist ja> etwas größer als die Bohrung selbst) hatte einen Durchmesser von ca.> 3mm.>> Als Kondensator hab ich 33nF verwendet. War ohne Plexiglas und Luftspalt> sehr sehr empfindlich. Mit Plexiglas und Luftspalt hats dann gepasst.> Bessere wäre bei mir auch gewesen, wenn die Platine direkt am Plexiglas> aufgelegen wäre (war nicht möglich, da noch ein OLED Display dazwischen> war). Der Luftspalt ist sehr ungünstig. Sollte also in deinem Fall ganz> leicht funktionieren.
Danke für die ausführliche Beschreibung!
Nachdem ich mich jetzt mehrere Tage lang an der (zuverlässigen)
Auswertung von Tastendrücken beschäftigt habe, haben sich noch ein paar
Fragen aufgetan.
Wie schirmt man die Verbindung vom Touchpad zum Mikrocontroller am
besten ab? Im Moment verwende ich dafür ein geschirmtes, ca. 20cm langes
Kabel (da fällt mir ein: den Schirm des Kabels hab ich im Moment nicht
angeschlossen - den ich sollte den vielleicht mal einseitig auf Masse
legen) Ich weiß, man sollte die Verbindung möglichst kurz halten, doch
kürzer kann ichs für den Testaufbau nicht machen. Die Auswertung des
Tastendrucks klappt eigentlich ganz zufriedenstellend, aber nur solange
ich das Kabel nicht bewege. Wenn ich das Kabel wenige cm nach rechts
oder links bewege, kann ich nur noch mit Mühe einen Tastendruck
erkennen, da sich die Schwellwerte ändern. Mit dieser Einschränkung kann
ich jedoch leben, da ich das Verbindungskabel einfach mit Heisskleber an
einer Stelle montiere wo man nicht so leicht hinlangen kann.
Was mich wesentlich mehr stört, ist folgendes: Auf der Platine wo der uC
sitzt, der die Auswertung des Tastendrucks vornimmt befindet sich noch
ein Anschluss für den USART. Jedes Mal wenn ich da ein Kabel anschließe,
dann funktioniert die Auswertung nicht mehr. Meine Vermutung ist, dass
das USART Kabel wie ne Antenne wirkt und die Schwellwerte dadurch
verschoben werden. Kann man da schaltungstechnisch vielleicht etwas
machen?
Bernhard B. schrieb:> da fällt mir ein: den Schirm des Kabels hab ich im Moment nicht> angeschlossen - den ich sollte den vielleicht mal einseitig auf Masse> legen)
keine schlechte Idee.
Hallo,
in der Application Note von Atmel und auch hier wurde erwähnt, dass
Wasser auf der Sensorfläche die Messung beeinflussen kann. Nun möchte
ich aber genau das: ein Regensensor mittels qtouch. Im Atmel-Forum hat
ein Mitarbeiter bestätigt, dass das geht, aber "it needs some
experiments". Hat das schon mal jemand ausprobiert?
Wie sollte das Ganze dimensioniert werden, und welche Sensorgeometrie
eignet sich dafür? Bei einer einfachen Kapazitätsmessung wäre ja eher
eine mit einer GND-Fläche kammarting verzahnte Sensorfläche geeignet.
Wie schaut das hier aus? Einmal GND außenrum oder GND ganz weglassen?
Die Messung kann/soll sehr langsam erfolgen - es macht nichts, wenn der
Regen erst nach 10 oder 30 Sekunden oder noch später registriert wird,
aber es soll ignoriert werden wenn mal jemand kurz mit dem Finger
hinfasst. Zur Not kann das aber auch per Software rausgerechnet werden.
Gruß, Christian
Im Prinzip funktioniert das mit Wasser genauso wie mit einem Finger. Die
Zeit die man braucht um den Speicherkondensator aufzuladen sinkt. Um wie
viel ist dann die Frage.
Das langsame Auslösen kann man durch 1-2 Mittelwertfilter realisieren
und eine durch Timer geregelte Abfrage. Der positive Nebeneffekt ist
dabei, dass kurze Berührungen, wie eben mit dem Finger, nicht mehr
erfasst werden.
Ich könnte mir gut vorstellen, dass du zu einem akzeptablen Ergebnis
kommst wenn du alle 300-500ms eine Messung vornimmst und die Werte dann
in unterschiedlich gewichtende Mittelwertfilter übernimmst. Entweder
wartest du dann in einer Statusmaschine bis sich dein Filter dem
aktuellen Wert wieder angenähert hat oder arbeitest mit einem Threshold.
Dabei würdest du deinen Sensor einmal Kalibrieren und deinen
Mittelwertfilter als Auslöser nutzen. Die Kalibrierung kann durch einen
zweiten Filter geschehen der Werte noch langsamer aufnimmt als dein
Messfilter.
Zur Dimensionierung des Sensors kann ich nur sagen, dass es theoretisch
ohne Massefläche funktionieren sollte. Das ist quasi nur ein Schirm
gegen Störeffekte da bei X/Y-Elektroden von Y nach GND eine Kapazität
aufgebaut wird. Viel wichtiger ist die Dimensionierung des
Speicherkondensators und des Entladewiderstandes, sowie die Auslegung
der Filter und des Timings.
Alles wichtige dazu steht in der Atmel Design Guide:
http://www.atmel.com/dyn/resources/prod_documents/doc10620.pdf
Ich persönlich habe die Erfahrung gemacht, dass Form und Größe zwar
wichtige Faktoren, nicht aber entscheidend sind. Störeinflüsse von
anliegenden Schaltungen oder der Umgebung, Integration der Strompfade
und die Beschaltung sind wesentlich kritischer. Das steht aber auch
alles in der Design Guide. Nebenbei kannst du deinen Sensor mit Masse
auch "Totschirmen", also lieber weniger als mehr ;-).
Regensensor mit qTouch ist nicht ratsam. Gerade bei diesem Prinzip hat
Wasser ohne Bezugspotenzial zur Erde einen verschwindend geringen
Einfluss. Ich kann mit meiner Dusche voll auf die Fliese draufhalten,
hinter der die Elektrode liegt, ohne den Schaltvorgang auszulösen. Kommt
hingegen die Hand auf die nasse oder trockene Fliese, wird sicher
geschaltet. Besorge Dir besser eine Sensorfläche mit vergoldeter
Kammstruktur (einfach) oder nutze einen Reflexkoppler unter einer zu
beregnenden Scheibe (schwieriger).
Das stimmt wohl aber für den Bezug kann man sorgen. Die Idee an sich ist
nicht schlecht und wie schon der Atmel-Mitarbeiter meinte: Es muss wohl
etwas experimentiert werden. Unter Umständen wird dann doch ein Sensor
mit Masse nötig. Wer nichts wagt der nichts gewinnt.
Für einen Regensensor wäre es wohl sinnvoller, statt einer einfach
angeschlossenen Kondensatorplatte dessen andere Seite durch den Finger
gebildet wird, beide Platten auf die Platine aufzubringen (evtl. in
einer kammartigen Struktur). Eine Seite kommt dabei auf Masse, die
andere ganz normal an den AVR. Zwischen den beiden wird nun ein kleiner
Kondensator gebildet, dessen relative Kapazität durch das ganz normale
QTouch-Programm ausgewertet wird. Befindet sich im Feldweg zwischen den
beiden Leiterbahnen genug Wasser, wird die Kapazität ausreichend erhöht,
um sicher erkannt zu werden.
Hallo,
hab mich nun auch mal an deisem Thema versucht.
Leider bis jetzt mit mäsigen Erfolg.
Ich verwernde einen ATmega32 den PinD6 und PinD7, sowie einen 1k
Widerstand, und einen 33nF Kondensator.
Das Programm habe ich mit Hilfe von Codevision geschrieben.
Den Zähler "i" gebe ich über RS232 aus.
Die Schaltung wird über den ISP-USP-Programmer mit 5V versorgt.
Anbei findet ihr einige Bilder vom Aufbau, Schaltplan und den gesamten
Code.
Leider bekomme ich immer "0" als Rückmeldung.
Woran könnte denn der Fehler liegen?
Danke für die Infos.
mfg Stefan
.
1
do
2
{
3
// PD6-----1k----PAD
4
// |
5
// 33nF
6
// |
7
// PD7--
8
9
// 1. definierten Zustand für die Kondensatoren herstellen. D.h. PB1 und
10
// PC1 als Ausgänge schalten und auf low ziehen um alles Cs zu entladen
11
// (genügend lange warten).
12
13
14
DDRD|=(1<<PD6);// PD6 als Ausgang schalten
15
DDRD|=(1<<PD7);// PD7 als Ausgang schalten
16
PORTD&=~(1<<PD6);// Ausgang PD6 auf LOW
17
PORTD&=~(1<<PD7);// Ausgang PD7 auf LOW
18
delay_us(5);
19
20
// 2. PB1 auf high und PC1 auf low schalten (aber immernoch als Eingänge)
21
22
DDRD&=~(1<<PD6);// PD6 als Eingang schalten
23
DDRD&=~(1<<PD7);// PD7 als Eingang schalten
24
25
PORTD|=(1<<PD6);// Eingang PD6 mit Pull-UP, bzw. später Ausgang auf HIGH
26
27
// 3. PB1 als Ausgang schalten und kurze Zeit (z.B. 5us) warten bis der
28
// unbekannte Touchkondensator geladen ist.
29
30
for(i=0;i<65535&&!(PORTD&(1<<PD6));i++)
31
{
32
DDRD|=(1<<PD6);// PD6 als Ausgang schalten, da "PORTD |= (1<<PD6)" Ausgang auf HIGH
33
delay_us(5);
34
35
// 4. PB1 wieder als Eingang schalten und PC1 als Ausgang schalten. Damit
36
// liegt jetzt der "Sampling Kondensator Cs" quasi parallel zum
37
// Touchkondensator und es müssen sich die Ladungen so umverteilen, dass
38
// beide die gleiche Spannung haben (Parallelschaltung). D.h. es wird Cs
39
// leicht geladen, da dieser ja viel größer ist.
40
41
DDRD&=~(1<<PD6);// PD6 als Eingang schalten, da "PORTD |= (1<<PD6)" Eingang mit Pull-UP
42
DDRD|=(1<<PD7);// PD7 als Ausgang schalten, da "PORTD &= ~(1<<PD7)" Ausgangn auf LOW
43
delay_us(20);// Warten weil das Umladen Zeit braucht ???
44
45
DDRD&=~(1<<PD7);// PD7 als eingang schalten, da "PORTD &= ~(1<<PD7)" Eingang ohne Pull-UP
46
47
// 5. Überprüfe ob PB1 schon als high eingelesen wird. Wenn nicht, dann
48
// beginne wieder bei Punkt 3 und erhöhe einen Zähler. Wenn PB1 bereits
49
// high ist, dann ist der Zählerstand ein Maß für die Anzahl der
Eine schöne Idee das QTouch, einfach und billig. Auch die Funkschalter
von EnOcean sind was Innovatives. ABER: Handbetätigte Schalter egal
welcher Art sind doch öfter als man glaubt entbehrlich. Viel sinnvoller
ist dann gleich die Investition in automatisiertes Erkennen menschlicher
Absichten. Die Anwesenheitserkennung (z.B. via Radarmelder) zum Ersatz
von Lichtschaltern ist hier nur das einfachste Beispiel...
Nochmal eine kurze Verständnisfrage: Was meint Atmel mit
QTouch-Channels? Kann ich nicht x-beliebige Pins hernehmen? Beim
ATmega16M1 werden z.B. 12 Channels angegeben. Das Ding hat 32 Pins,
davon 27 I/O Pins. Bei allen sind die PullUps abschaltbar. Da ich für
einen Channel immer 2 Pins brauche, wären das also 13 Channels. Schaut
12 einfach nur schöner aus oder darf ich 3 bestimmte Pins nicht
verwenden?
Hallo,
ja ich mal ganz kurz. Nachdem die Lib aber nicht wirklich gut
funktioniert hat - vielleicht war ich auch nur zu doof - und ich sowieso
wissen wollte wie es funktioniert, hab ich es auch selbst implementiert.
mfg
Andreas
Hallo,
Ja ich habe auch schon einen selbst Programiert.
Die Lib. habe ich instaliert und auch schon passende gefunden für den
ATmega32. Wen ich mein Sensor im QTouch Studio zeichne, dann spuckt der
mir irgendwelche Parameter aus. Und mit einem kleinen Wizard kann man
die MCU wählen und welche Pin und Ports man verwendet und dan kommen
noch mehr Parameter raus.
Ich habe aber nicht begriffen, wie ich das ganze nun zu einem
brauchbaren Programm zusammen schachtle? Vieleicht kann mir jemand
weiterhelfen ?
danke mfg hans
Stefan schrieb:> Leider bekomme ich immer "0" als Rückmeldung.> Woran könnte denn der Fehler liegen?
Du läßt immer den Pullup eingeschaltet, da kann das nichts werden.
Schau Dir mal meinen Code an:
Beitrag "Re: qtouch - sekt oder selters"
Peter
Stefan schrieb:
> Leider bekomme ich immer "0" als Rückmeldung.> Woran könnte denn der Fehler liegen?
Bei der Abfrage:
for(i=0; i<65535 && !(PORTD & (1<<PD6)); i++)
Probier mal PIND anstelle von PORTD.
Das Register PIN dient der Abfrage, wenn du PORT [&] verknüpfst,
schreibst du den Wert raus und deine Ladung wird Möglicher weise wieder
entladen.
mfg
Hallo Nochmal
Ich schlage mich grade mit der Touch library rum.
Die librarys sind ja solche .a Files, welche man laut Atmel in das
Projekt hinein linken muss. Ich habe das jedoch nochnicht hinbekommen.
Kann mir bitte jemand erklären wie mann ein file.a in ein Projekt linkt
?
mfg Hans
Danke =)
Hallo,
ich habe den Bascom-Code von Andreas aus diesem Beitrag
Beitrag "Re: qtouch - sekt oder selters"
dahingehend geändert, daß es jetzt möglich ist, mehrere Sensoren
gleichzeitig zu verwenden. Dazu schalte ich jeweils die kompletten Ports
B und C um. Somit sind, wie in dem Beispiel dem Atmega8, 6 Sensoren
gleichzeitig bei voller Auflösung möglich. Bei Controllern mit vollen
Ports mit jeweils 8 Pins sind dann 8 Sensoren möglich.
Anschlußbild, als Beispiel die Pins5 der Ports B und C:
PC.5-----------+
|
---
--- 10n
|
PB.5-----------+---- 1K ---- Touchpad
die restlichen Pins sind entsprechend zu beschalten. Nichtbenutzte
müssen mit GND verbunden werden, am Besten mit Pull-Down.
Die Schaltschwelle in der Zeile
"Loop Until Cycles >= 100"
muß so gewählt werden, daß die Kondensatoren gerade noch nicht soweit
geladen sind, daß ein High-Zustand erkannt wird.
Bei mir sind bei Berührung der Pads noch ca. 60 Zyklen nötig, die
Kondensatoren zu laden. Der Unterschied ist schon deutlich. Als Pads
verwende ich metallene Reißnägel.
Das Ergebnis ist dann im Register PinC zu finden, z.B. bei Betätigung
des Pads der Pins im Anschlußbild-Beispiel &B00100000.
1
$regfile = "m8def.dat" ' specify the used micro
2
$crystal = 8000000 ' used crystal frequency
3
$baud = 19200 ' use baud rate
4
$hwstack = 32 ' default use 32 for the hardware stack
5
$swstack = 10 ' default use 10 for the SW stack
6
$framesize = 40 ' default use 40 for the frame space
Hab ich nun auch an den Aufbau der Schaltung gewagt.
hatte aber leider nicht den passenden Kondensator da.
Hab also den nächst größeren genommen. Einen 4,7uF + 4,8 Ohm Widerstand.
Da dieser ja theoretisch mehr Zyklen zum Aufladen braucht, hab ich die
Begrenzung im Code rausgenommen. Beim ersten versuch hat mir der Code
nur Nullen geliefert und beim zweiten Versuch nichts (berührt und
unberührt).
Hab den Elko so gelötet, dass Minus zum Pin geht und Plus zur
Touchelektrode. Ist doch richtig oder?
Läd sich der Kondensator eventuell garnicht auf oder dauert es einfach
nur extrem lange?
Dann hab ich es noch mit einem 104pF Kondensator probiert. Unberührt hat
der mir auch keine Werte geliefert. Bei direkter Berührung gabs dann
irgendwelche Werte (von 0-300 alles dabei). Durch ein Blatt papier wurde
dann wieder garnichts angezeigt.
Ich hab hier im Thread irgendwas von einem Capture Pin gelesen. Wofür
ist der gut bzw. ist der relevant für den Aufbau? Ich hab meinen Aufbau
an PortA.4 und PortA.7 angeschlossen.
Domsk schrieb:> Hab also den nächst größeren genommen. Einen 4,7uF + 4,8 Ohm Widerstand.
Das ist ein verspäteter Aprilscherz, oder?
Im QTouch Bild oben im thread stehen als Beispielswerte 22nF und 1KOhm.
Jetzt rechne mal aus, wieviele Dekaden Du da weg von bist....
Leider nein.
Hups, da hab ich das wohl falsch verstanden. Dachte damit sind
Widerstände von 1Ohm bis 10kOhm gemeint. Aber den werd ich hier zuhause
wohl noch auftreiben können.
Das erklärt auch, warum kein Wert ausgegeben wurde.
Domsk schrieb:> Dann hab ich es noch mit einem 104pF Kondensator probiert.
Soso, ein 104pF Kondensator also...
Sieh dir mal an, wie Kondensatoren gekennzeichnet werden. Könnte es
sein, dass auch dein 104 pF Kondensator (wie so viele andere auch) in
Wirklichkeit 10_0000 pF hat (also eine 10 und 4 Nullen), und mithin ein
100nF Kondensator ist?
Ja, Ich weiß, dass der Kondensator so am besten ist, aber es müsste mit
größeren ja auch nach längerer Zeit eine Ausgabe erfolgen. Ich hatte
einfach keine da.
Habs jetzt noch einige gefunden. Einen 22nF und einen 10nF Kondensator.
Beidesmal keine Ausgabe.
Entweder es steckt ein blöder Fehler drin, oder meine Kondensatoren sind
kaputt, da sie schon etwas älter sind.
Einmal diesen hier: http://www.wima.de/DE/products_rfi.htm
Oben drauf steht "0u(Mikro-Zeichen)022" (heißt doch 22nF, wenn ich mich
nicht irre)
Der zweite ist etwas länglich, platt und silbern und es steht "103J"
drauf, also 10000pF und J als Toleranz oder? Vielleicht ist es auch kein
Kondensator, man weiß es nicht :D
Oh ja, da hab ich mich wohl versehen. Hab das Codierungssystem von
Kondensatoren auch erst heute entdeckt.
Folgender Code:
[c] $regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
$hwstack = 100 ' default use 32 for the hardware
stack
$swstack = 100 ' default use 10 for the SW stack
$framesize = 100 ' default use 40 for the frame space
Dim Cycles As Word
'PA7-----------+---- 10K ---- Touchpad
' |
' ---
' --- 22n
' |
'PA4-----------+
Do
Cycles = 0
'Alles Entladen
'beide out - beide low
Ddra.7 = 1 : Porta.7 = 0
Ddra.4 = 1 : Porta.4 = 0
'auf vollstaendige Entladung warten
Waitus 5
Do
'beide als tristate inp schalten, damit keine Ladung abfliessen kann
Ddra.7 = 0 : Porta.7 = 0
Ddra.4 = 0 : Porta.4 = 0
Waitus 5
'PC4 Out und high schalten, um C aufzuladen
Ddra.4 = 1 : Porta.4 = 1
Waitus 2
'und wieder aus
Ddra.4 = 0 : Porta.4 = 0
'Die Ladung aus C jetzt nach PD5 auf GND abfuehren
Ddra.7 = 1 : Porta.7 = 0
'messen, ob Ladung schon fuer eine 1 an PD4 reicht, sonst von vorn
If Pina.4 = 1 Then Print Cycles
Incr Cycles
Loop 'wiederholen und im Zweifel beenden
Loop[c]
Ich hab mich jetzt auch mal mit dem Thema beschäftigt und dabei ist mir
aufgefallen, dass es ja auch die Variante QTouch per ADC gibt. Kann mir
jemand erläutern worin der essentielle Unterschied liegt? Schließlich
ist das ja von der Beschaltung einfacher. Nur 1 Rs am ADC Pin und hinten
raus ein Tiefpass.
@Joe
also eben mal getestet, es löst wunderbar aus, wenn man das Wasser
berührt - wenn der Finger aber schon im Wasser ist führt eine
Abstandsänderung des Fingers zum Sensor innerhalb des Wassers zu keiner
Auslösung (bis ca. 10cm getestet).
Also für eine sinnvolle Anwendung - NEIN.
Sascha
Liebes Forum,
Eigentlich scheint diese Touch-Geschichte ja nicht sonderlich
anspruchsvoll zu sein, dennoch habe ich meine liebe Mühe, das ganze ans
laufen zu bekommen.
Aufbau:
RN-Control 1.4 mit Atmga1284P, 20MHz Quarz, ohne L293
An Porta.4 und Porta.5 ein WIMA 33nF sowie 1ct über 1kOhm als Sensor.
Folgender Code liefert leider kein vernünftiges Ergebnis:
Habe schon mit verschiedenen Kapazitäten, Sensoren und Zeiten probiert,
es scheint jedoch irgendwo ein "Bock" drin zu sitzen, den ich einfach
nicht sehe.
Ich tippe mal auf einen dummen Fehler... sieht ihn jemand!?
Danke!
Verwendeter Bascom-Code:
1
$regfile = "m1284Pdef.dat"
2
$crystal = 20e6
3
$hwstack = 64
4
$swstack = 48
5
$framesize = 64 'default use 40 for the frame space
Genau genommen wird immer der Maximalwert für "Cycles" ausgegeben, wird
der Kondensator entfernt jedoch "0", was ja auch nachvollziehbar ist.
Hat niemand einen Tip?
gelöst. Finde ich irgendwie übersichtlicher.
Kannst du checken, was die Ports machen, d.h. ob sie die erwarteten
Zustände einnehmen?
Wait xxx dazwischen packen und ausmessen!
Oszi zur Hand??
Gruß,
Hans
Das Qtouch für die AVRs benötigt ja 2 Pins pro "Taste".
Die Qtouch ICs besitzen ne Matrixschaltung (zB QT60240) wobei dort nur
die Spalten den Ladekondi haben.
Hat also schonmal jemand versucht die Matrixschaltung mit nem AVR zu
realisieren?
Hallo zusammen,
ich habe auch versucht den oben aufgeführten Code zu
implementieren...mit Erfolg.
Soweit so gut, leider stoße ich jetzt mit meinen C Programmier und
Verständnis "Künsten" an meine Grenzen. Ich habe eine Anwendung bei der
ich mehr als 10 Taster einlesen muss und möchte diese Taster gerne gegen
die Touch Sensoren (Flächen) ersetzen. D.h. ich muss die Prozedur für 2
Ports durchführen was mir einiges an Schwierigkeiten bereitet. Ich habe
den Code schon so umgebaut, dass er mit 2 unterschiedlichen Ports
funktioniert aber der Code ist sehr unschön bzw. in 2 Funktionen
getrennt da ich es nicht hinbekomme eine Funktion zu programmieren die X
Ports mit den von mir gewünschten PINs einliest.
Nachfolgend der Code mir den 2 Funktionen zur Abfrage...
DDRC|=(1<<PC0)|(1<<PC1)|(1<<PC2);// set PC0, PC1, PC2 as output
89
90
LED2_OFF;
91
LED3_OFF;
92
LED4_OFF;
93
94
LED2_ON;
95
_delay_ms(500);
96
LED3_ON;
97
_delay_ms(500);
98
LED4_ON;
99
_delay_ms(500);
100
101
LED2_OFF;
102
LED3_OFF;
103
LED4_OFF;
104
105
while(1)
106
{
107
108
read_senskey_PortB();
109
110
if(keys_PortB[0]>2000)
111
{
112
LED2_ON;//LED an
113
}
114
else
115
{
116
LED2_OFF;//LED aus
117
}
118
119
read_senskey_PortD();
120
121
if(keys_PortD[0]>2000)
122
{
123
LED4_ON;//LED an
124
}
125
else
126
{
127
LED4_OFF;//LED aus
128
}
129
}
130
}
Also wie gesagt der Code funktioniert aber sehr unschön...könnte jemand
mir helfen und nen Code posten wie ich die Funktion umschreibe und
mehrere Ports übergreifend in Abhängigkeit von den einzelnen PINs
abfragen kann... und das in einer Funktion und nicht in 2 getrennt wie
aktuell bei mir
Wäre euch echt sehr dankbar!
Viele Grüße
Rey
Tut jetzt auch bei mir, 20MHz sind einfach etwas flott gewesen. 1x
"waitus 1" und schon gehts :)
was spricht dagegen, einfach 2+2 ports komplett umzuschalten und die
portzustände einzulesen??
Hi,
ich hab das ganze vor einiger Zeit mal in ein kleines "Framework"
(Framework ist etwas hochgegriffen... habs halt bisschen universeller
gestaltet und in ein eigenes File) verpackt.
Muss aber erst heute Abend schauen, wo ich es auf meinem Rechner hab.
Das ganze sieht so aus, dass du über eine Struktur angeben kannst
welcher Port und welcher Pin als Touchsensor verwendet wird und einen
Schwellwert. Ich glaub ich hab sogar einen Filter eingebaut, der das
ganze Tiefpass filtert bzw. könnte man wenn ich mich recht erinnere auch
eine eigene Funktion übergeben, in der man einen Filter implementiert.
Falls ihr interesse habt, kann ich es ja mal hier hochladen. Ist aber
rein für C (also avrgcc) geschrieben.
mfg
Andreas
TouchFreund schrieb:> Tut jetzt auch bei mir, 20MHz sind einfach etwas flott gewesen. 1x> "waitus 1" und schon gehts :)>> was spricht dagegen, einfach 2+2 ports komplett umzuschalten und die> portzustände einzulesen??
Hallo nochmal,
folgendes macht mich an meiner Programmierung stutzig...nach folgender
Vorgabe:
...
1
#define MAX_CYCLE_PortB 4000
2
#define MAX_CYCLE_PortD 4000
wenn ich nun den Wert an Port B und C abfrage:
1
read_senskey_PortB();
2
read_senskey_PortD();
funktioniert alles blendend...
allerdings ist mir aufgefallen, wenn ich nun eine Abfrage auskommentiere
z.B.
1
read_senskey_PortB();
2
// read_senskey_PortD(); AUSKOMMENTIERT
funktioniert der Tousch-Schalter nicht mehr bzw. der Wert in der
Abfrage:
1
if(keys_PortB[0]>1600)
2
{
3
LED2_ON;//LED an
4
}
5
else
6
{
7
LED2_OFF;//LED aus
8
}
es muss > 1600 abgeändert werden z.B. in den Wert 2300 dass alles
funktioniert.!?
Kann mir einer erklären wie der Zählwert der Auslesfunktion von Port B
mit dem Aktivieren bzw. deaktivieren der Auslefunktion von Port C
zusammenhängt???
Wäre euch super dankbar, es ärgert mich das es funktioniert, ich aber
nicht weiss ob es ein Zufall ist oder nicht bzw. ich nicht verstehe wie
das zusammenhängt ;-)
Danke und VG Rey
Andreas Auer schrieb:> Hi,>> ich hab das ganze vor einiger Zeit mal in ein kleines "Framework"> (Framework ist etwas hochgegriffen... habs halt bisschen universeller> gestaltet und in ein eigenes File) verpackt.> Muss aber erst heute Abend schauen, wo ich es auf meinem Rechner hab.>> Das ganze sieht so aus, dass du über eine Struktur angeben kannst> welcher Port und welcher Pin als Touchsensor verwendet wird und einen> Schwellwert. Ich glaub ich hab sogar einen Filter eingebaut, der das> ganze Tiefpass filtert bzw. könnte man wenn ich mich recht erinnere auch> eine eigene Funktion übergeben, in der man einen Filter implementiert.>> Falls ihr interesse habt, kann ich es ja mal hier hochladen. Ist aber> rein für C (also avrgcc) geschrieben.>> mfg> Andreas
;-) wäre echt nett, bin für alles dankbar dass mich (oder vlt. auch noch
andere) weiterbringt!
VG Rey
Abgesehen davon würde ich nicht den absoluten Zählerstand nach der
read_senskey_XXX() Funktion auswerten, sondern eher die Änderung des
Wertes zu einem initialen Referenzwert. Also das Ganze beim Einschalten
mal machen lassen und der Wert der rauskommt ist dann der Referenzwert.
Und die Differenz zu diesem Referenzwert wenn du den Finger draufhälst
kannst du auswerten. Damit ist dir am Anfang ziemlich egal, ob das jetzt
bei 1600 schaltet oder bei 2000.
Optional ist auch noch möglich, dass du die Drift für den Referenzwert
berücksichtigst... damit der Touchsensor nicht auf einmal von alleine
einschaltet oder gar nicht mehr einschaltet.
mfg
Andreas
TouchFreund schrieb:> Es ändert sich ja die Gesamtkapazität der Kondensatoren, die aufgeladen> werden wollen. So dauert es eben ein paar Zyklen Länger, bis der C Voll> ist.
obwohl es jetzt eigentlich ein "Kondensator" bzw. eine Abfrage weniger
gibt?
hmm ich stehe irgendwie auf dem Schlauch...
Ich überleg mal weiter Danke
Rey <-- Grübel Grübel
Hallo Andreas,
auch dir danke für deine Antwort...habe das nun seit 2 Stunden versucht
zu verstehen und in C umzusetzen, leider ohne Erfolg ;-( ich muss jetzt
wohl erst mal aufs Fahrrad und an die frische Luft...
Du schreibst
> Abgesehen davon würde ich nicht den absoluten Zählerstand nach der> read_senskey_XXX() Funktion auswerten, sondern eher die Änderung des> Wertes zu einem initialen Referenzwert. Also das Ganze beim Einschalten> mal machen lassen und der Wert der rauskommt ist dann der Referenzwert.
Das heisst vor der Hauptschleife einmal die keys Variable mit einem Wert
von z.B. 1600 in meinem Fall vergleichen und die Differenz speichern?
Ist das der Referenzwert den du gemeint hast?
Danke
Rey
Wenn D die Zyklenzeit ist, gilt:
If D > Dmax Then Dmax = D
D_on = Dmax - 20
D_off = Dmax - 10
Vorher nen gleitenden Mittelwert bilden, dann läuft das sehr stabil und
ohne "prellen".
So sollte die Kapazität wurscht sein.
Rey N. schrieb:> Das heisst vor der Hauptschleife einmal die keys Variable mit einem Wert> von z.B. 1600 in meinem Fall vergleichen und die Differenz speichern?> Ist das der Referenzwert den du gemeint hast?
Bevor du in die Hauptschleife kommst kannst du doch 8 mal jede einzelne
Taste auslesen, dann jedes mal durch 8 teilen und diesen Wert als
Referenzwert für die entsprechende Taste benutzen.
Du kannst auch gleich das Maximum der ermittelten Werte bestimmen und du
setzt die Differenz für jeden "Touche-Taster" auf die ermittelte
Differenz plus ein bisschen (mindestens +1).
Wenn der Wert darüber liegt wird der Taster als gedrückt gewertet.
Ich mache das so bei meinem einfacheren Verfahren (wie bei Elm-Chan)
dazu brauche ich nur einen 1MOhm Widerstand nach +3.3V und einen Pin pro
Taster.
Mike J. schrieb:> Rey N. schrieb:>> Das heisst vor der Hauptschleife einmal die keys Variable mit einem Wert>> von z.B. 1600 in meinem Fall vergleichen und die Differenz speichern?>> Ist das der Referenzwert den du gemeint hast?>> Bevor du in die Hauptschleife kommst kannst du doch 8 mal jede einzelne> Taste auslesen, dann jedes mal durch 8 teilen und diesen Wert als> Referenzwert für die entsprechende Taste benutzen.
Hab ich vertsanden und umgesetzt, nicht schön aber sollte passen:
1
voideval_val_keys_ref_max_PortB_AB0(void)
2
{
3
inti=0;
4
intj=0;
5
intnum_keys_mesh=8;
6
7
read_senskey_PortB();
8
val_keys_PortB_AB0_[0]=keys_PortB[0];
9
read_senskey_PortB();
10
val_keys_PortB_AB0_[1]=keys_PortB[0];
11
read_senskey_PortB();
12
val_keys_PortB_AB0_[2]=keys_PortB[0];
13
read_senskey_PortB();
14
val_keys_PortB_AB0_[3]=keys_PortB[0];
15
read_senskey_PortB();
16
val_keys_PortB_AB0_[4]=keys_PortB[0];
17
read_senskey_PortB();
18
val_keys_PortB_AB0_[5]=keys_PortB[0];
19
read_senskey_PortB();
20
val_keys_PortB_AB0_[6]=keys_PortB[0];
21
read_senskey_PortB();
22
val_keys_PortB_AB0_[7]=keys_PortB[0];
23
24
/***************** found ref value *****************/
25
for(j=0;j<num_keys_mesh;j++)
26
{
27
ref_val_PortB_AB0+=val_keys_PortB_AB0_[j];
28
29
}
30
31
ref_val_PortB_AB0=ref_val_PortB_AB0/8;
32
33
/***************** found max value ******************/
> Du kannst auch gleich das Maximum der ermittelten Werte bestimmen und du> setzt die Differenz für jeden "Touche-Taster" auf die ermittelte> Differenz plus ein bisschen (mindestens +1).> Wenn der Wert darüber liegt wird der Taster als gedrückt gewertet.
Das Maximum sowie die Differenz von Max zu Ref-Wert hab ich auch
gebildet, also vor der Hauptschleife...
aber den Rest hab ich nicht so ganz verstanden... auch nach 2 Sunden
frischer Luft nicht ... versuche es morgen früh mal so, hab die Hardware
in der Firma...
1
while(1)
2
{
3
4
read_senskey_PortB();
5
6
if(keys_PortB[0]>max_val_PortB_AB0)
7
{
8
LED2_ON;//LED an
9
}
10
else
11
{
12
LED2_OFF;//LED aus
13
}
hat dann allerdings glaube ich nichts mit der von euch erwähnten
Differenz zu tun...
weiss aber im Moment nicht wie ich das umsetzen soll.
> Ich mache das so bei meinem einfacheren Verfahren (wie bei Elm-Chan)> dazu brauche ich nur einen 1MOhm Widerstand nach +3.3V und einen Pin pro> Taster.
DANKE für eure Hilfe auch wenn ich immer noch auf dem Schlauch stehe...
VG Rey
Rey N. schrieb:> Was meint Ihr dazu?
Lass dir mal deinen aktuellen Wert des Tasters ausgeben, es kann sein
dass der niedriger ist als der beim starten ermittelte Wert.
Hi,
hat leider etwas gedauert, aber anbei sind die Sourcen für die
kapazitive Touch Sensor Geschichte. Es ist auch eine Demoapplikation
dabei, die das Softwaregerüst verwendet (leider undokumentiert). Aber
durch die Applikation erklärt sich das eine oder andere sicher von
selbst.
lg.
Andreas
Mike J. schrieb:> Rey N. schrieb:>> Was meint Ihr dazu?>> Lass dir mal deinen aktuellen Wert des Tasters ausgeben, es kann sein> dass der niedriger ist als der beim starten ermittelte Wert.
Hy,
sobald das Display bei mir eintrifft (das alte hatte einen Kurzschluss
nicht überlebt...) werde ich mal die Werte auslesen...
Danke
Andreas Auer schrieb:> Hi,>> hat leider etwas gedauert, aber anbei sind die Sourcen für die> kapazitive Touch Sensor Geschichte. Es ist auch eine Demoapplikation> dabei, die das Softwaregerüst verwendet (leider undokumentiert). Aber> durch die Applikation erklärt sich das eine oder andere sicher von> selbst.>> lg.> Andreas
Hy Andreas,
danke für die Files... versuche das mal nachzuvollziehen und melde mich
ggfls. hab da mit Sicherheit noch die ein oder andere Frage
Vg Rey
Hallo,
Mal eine frage:
Ergeben sich Unterschiede bei "Reichweite" und Empfindlichkeit bzw.
Auslesesicherheit des Touchpads bei unterschiedlichen
AtmelversorgungsSpannungen?
also:
Misst man mit Vcc = 5V besser und sicherer als mit VCC = 3,3V?
Vielen Dank,
Alex
Hallo zusammen,
ich habe mich, mit Hilfe dieses exzellenten Threads, auch an die
Implementation der Ladungspumpentechnik mit einem externen Kondensator
gemacht. Der Ansatz funktioniert eigentlich recht gut, unpraktisch ist
nur die starke Prozessorbelastung.
Auf halben Wege bin ich über diese App-Note von Atmel zu einem noch
interessanteren Ansatz gestoßen (QtouchADC):
http://www.atmel.com/Images/doc8497.pdf
Im Gegensatz zum Ansatz aus dem Thread, wird die Ladung aus dem Touchpad
nicht in einen externen Kondensator sondern in den internen Sample&Hold
Kondensator des AD-Wandlers umgeladen. Die Spannung am S&H Kondensator
kann dann über den ADC direkt ausgewertet werden. Danach wird der S&H
Kondensator aufgeladen und über das Touchpad entladen. Die Ergebnisse
beider Messungen werden kombiniert.
Die Vorteile sind offensichtlich: Nur ein externes Bauteil, schneller,
Interruptfähig.
Da ich die Library nicht nutzen kann/will, habe ich auch diese Methode
nachgekocht. Soweit funktioniert es recht gut. Der Code unten setzt
folgende Schritte um:
1) Pad über Pin1 auf 0V Entladen
S&H Kondensator über Pin0 auf 5V Laden (AREF)
2) S&H Kondesator mit Pin1 ADC Verbinden
ADC Auslesen
3) Pad über Pin1 auf 5V Laden
S&H Kondensator über Pin0 auf 0V Entladen.
4) S&H Kondesator mit Pin1 ADC Verbinden
ADC Auslesen
5) Ergebnisse aus 2) und 4) subtrahieren.
Und hier auch die Frage: Um den S&H Kondensator gezielt zu be- und
entladen, schalte ich den ADC über den Multiplexer an einen freien Pin
(Pin0), an den ich über den Ausgangstreiber das gewünschte Potential
anlage. Erstaunlicherweise funktioniert dieese auch ohne einen
ADC-Vorgang auszulösen. Ist dieses irgendwie erklärbar? Außerdem gibt es
eine starke Beeinflussung durch externe Streukapazitäten an Pin0. Gibt
es eine bessere Möglichkeit zur Umsetzung?
1
// Init ADC
2
3
ADMUX=_BV(REFS0)|0x0f;
4
ADCSRA=_BV(ADEN)|_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0);// Enable ADC, Set prescaler to 128
5
6
7
intsenseadctwice(void){
8
/*
9
Capacitive sensing using charge sharing between
10
the S/H capacitor and an external sensing pad
11
12
ATMega 328P
13
Float/ref Analog0 = PC0
14
Sense an Analog1 = PC1
15
*/
16
17
intdat1,dat2;
18
19
// Precharge Low
20
ADMUX=_BV(REFS0)|0x00;// Charge S/H cap from Analog0
hallo zusammen.
den code, den Autor: Martin J. (bluematrix)veröffentlicht hat. kann es
sein, das da noch viele sachen zum funktionieren fehlen.? allein die
LEDs müssen ja irgentwo mal deklariert werden.
außerdem verstehe ich dieses stück noch nicht:
void read_senskey( void )
{
uint16_t i = MAX_CYCLE;
uint8_t a, b, x, y;
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
a = DDRE & ~(SK_A012 | SK_B012);
b = PORTE & ~(SK_A012 | SK_B012);
y = SK_B012; // input mask
do
{
DDRF = a; // tristate
PORTF = b | SK_B012;
DDRF = a | SK_B012; // Bx = strong high
DDRF = a; // tristate
PORTF = b;
DDRF = a | SK_A012; // Ax = strong low
kann mir jemand helfen.? ich finde das projekt auch voll genial.
danke
Hallo,
ich würde das qtouch modul vom 32-Bit Atmel µC AT32UC3L032 gerne
verwenden, um kleine Kapazitätsänderungen zu detektieren (pF-Bereich).
Nachdem ich mir dieses Thema durchgelesen habe, hätte ich noch ein paar
Fragen dazu:
Ist es prinzipiell möglich, so kleine Kapazitätsänderungen zu
detektieren?
Gehe ich richtig in der Annahme, dass ich die oben angeführten
Codebeispiele nicht auszuprogrammieren brauche, weil im verwendeten µC
das Modul integriert ist?
Die Sens-Kapazität Cs und die sich ändernde Kapazität werden extern an
die beiden entsprechenden Pins des µC gelegt?
Wie genau funktioniert der Counter? Werden hier einfach die Takte
gezählt, die benötigt werden, bis die Spannung am Cs als High erkannt
wird oder wird dazu ein eigener Counter verwendet?
Vielen Dank für die Hilfe!
Zusätzlich müsste ich die Kapazitätsänderung innerhalb von 1 ms
erkennen. Ist das prinzipiell überhaupt möglich? Dafür müsste ich Cs
vermutlich kleiner machen, was sich wieder negativ auf die Auflösung der
Count-Werte auswirkt. Könnte mir jemand einen Tip geben?
Ok, was älter - macht aber nichts :-)
Toucherkennung selbst läuft super, aber die Platine muss über I2C
angebunden werden (I2C-slave, ATMega328P, Master ist ein STM32).
Ausserdem noch ein paar andere Sachen die am ATMega hängen.
Und jetzt beisst sich die Sache, read_senskey() dauert etwa 8ms,
natürlich tödlich für die eigentlich asynchrone I2C-Kommunikation. Mit
freigegebenem Interrupt läuft die touch-Sache mehr schlecht als recht,
mit gesperrtem Interrupt ist die Kommunikation Glückssache.
Mir fällt da keine ordentliche Lösung ein. Im Moment habe ich eine zus.
Leitung gefädelt, die dem master sagt, wann er mit dem slave babbeln
darf. Funktioniert auch, aber ich habe nur eine 4polige Verbindung
zwischen den Platinen (die Gegenseite ist fertig, nicht auf meinem Mist
gewachsen). Irgendwelche Ideen, wie man das Problem lösen könnte?
Ich denke mal, ich werde einen AT42QT2120 o.ä. zus. verwenden.
H.Joachim S. schrieb:> tödlich für die eigentlich asynchrone I2C-Kommunikation.
Warum, I2C ist doch nicht zeitkritisch. Der Slave kann einfach über
Clock-Stretching den Master warten lassen.
Hier mal ein Beispiel für ADC-Touch:
Beitrag "Re: Touch-Controller für Lampe"
H.Joachim S. schrieb:> Und jetzt beisst sich die Sache, read_senskey() dauert etwa 8ms,> natürlich tödlich für die eigentlich asynchrone I2C-Kommunikation.
I2C ist nicht asynchron, sondern im Gegenteil voll synchronisiert. Es
gibt also nicht nur einen Takt (die ABWESENHEIT eines solchen macht
eine asynchrone Kommunikation aus), sondern der Slave kann ihn obendrein
nach seinen Bedürfnissen verlangsamen, theoretisch bis zum völligen
Stillstand.
Aus praktischen Gründen wird man aber einen Timeout sinnvoller Größe
setzen. In deinem Fall muss der halt dann einfach nur größer als 8ms
sein, das ist alles.
Funktioniert die Kommunikation trotzdem nicht, hast du irgendwas falsch
gemacht. Suche den Bug.
H.Joachim S. schrieb:> Im Moment habe ich eine zus.> Leitung gefädelt, die dem master sagt, wann er mit dem slave babbeln> darf.
Die Leitung existiert schon, nennt sich SCL. Natürlich darf der Master
nicht blockierend in der Mainloop warten, sondern per I2C-Interrupt im
Hintergrund. Der Interrupt setzt dann ein Flag "habe fertig" zum Main.
Mit asynchron meinte ich nicht die Übertragung selbst, sondern dass die
Kommunikation zu einem unbestimmten (und unpassenden) Moment losgehen
kann und wird.
clock-stretching klingt interessant. Habe ich ehrlich gesagt noch nie
benutzt. Das könnte die Lösung sein, muss ich mich mal schlau machen.
Schön ist es dennoch nicht, dass die Interrupts so lange blockiert sind.
Danke erstmal.
H.Joachim S. schrieb:> Schön ist es dennoch nicht, dass die Interrupts so lange blockiert sind.
Interrupts können nur durch andere Interrupts blockiert werden.
Interrupts sollte man daher immer kurz halten. Ich versuche möglichst
unter 200 Zyklen zu bleiben (25µs @8MHz).
8ms in einem Interrupt zu warten, ist definitiv zuviel.
ADC-Touch läßt sich gut im ADC-Interrupt ausführen, d.h. das Main läuft
dabei weiter.