PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kapazitiven Sensor -> 1 Port



Sp666dy
11.04.2012, 19:24
Guten Abend,

also vor längerer Zeit habe ich ein Tutorial gemacht, mit ein kapazitiven sensor. (http://www.modding-faq.de/Forum/index.php?topic=20032.0)

Da ich jetzt mit einem Controller mein Projekt erweitern will, würde ich gerne die Hardware Lösung
software mäßig lösen.

Ich habe gelesen und auch schon Bestellt, das wenn ich zwischen zwei Ports ein Kondensator und parallel dazu eine Sensorfläche (Kupferplatte) anschließe ich den Kondensator aufladen kann und mit den pull up entladen kann, und die zeit messe, wobei die Veränderung ich abfangen kann sobald der Finger im Spiel kommt.

Heute morgen sah ich aber dieses Projekt (http://elm-chan.org/works/capsens/report_e.html), nur versteh ich nicht den code dabei weil das sehr umfangreich ist,
nur um den Taster abzufragen (finde ich)

Also so würde ich sehr viel Ports speichern, denn ich brauche 24 Taster... nur versteht jemand wie das damit funktioniert? Benutzt er das so als ob es ein halber Kondensator ist?

Wäre echt nett wenn ihr mir dabei helfen könntet, denn der Schaltplan ist mehr als einfach.... und das interessiert mich...

Danke
Gruß David

robin
11.04.2012, 20:39
Schau mal bei Microchip unter: Mtouch

Bei Atmel unter: Qtouch

Da gibts für beide Application Notes in denen auch Beispielprogramme drin sind. Einfach mal auf den homepages suchen.

Edit:

Theoretisch gibt es 4 verschiedene Möglichkeiten, das ganze zu realisieren (sicherlich noch mehr).

1. Du lädst mit einer festen Frequenz/Zeit den Kondensator und verwendest die internen Schaltpegel der I/O Ports des Controllers. Die Empfindlichkeit wird dann über den Ladewiderstand der Sensorfläche bestimmt. (wie bei deinem Tutorial). Die Software intern ist dafür recht Einfach, aber der Controller kann nicht auf Umwelteinflüsse Reagieren und Nachregeln (alterung, Temperatur, ....).

2. Im Prinzip das Selbe, nur wird der Ladezustand über den ADC ausgewertet. Hat den Vorteil, man sieht in der Software auch Umweltbedingungen und kann drauf reagieren. Ist aber für deinen Fall eher weniger Geeignet, da du 24 Schalter brauchst und dafür fehlen dir halt die ADCs.

3. Man läd den Kondensator so lange, bis der Eingangspin "1" ist und misst die Zeit die Zwischen einschalten und "1". Müsste das verfahren von mikrochip sein, bin mir aber nich 100% sicher.
Unter Umständen musst du zum Messen das laden kurz unterbrechen, da du sonst den Highpegel vom Laden misst und nicht die Ladung der Sensorfläche.

4. Die Ladung von deiner Sensorfläche auf einen größeren Kondensator "umladen", gemessen wird die Anzahl der Umladungen bis eine bestimmte Spannung am Kondensator erreicht ist (High-Pegel oder ADC). Ist Softwaretechnisch komplizierter, da man die I/Os recht schnell in bestimmte zustände Schalten muss (Eingang, Ausgang, Hochohmig). Das verfahren ist das was Atmel mit Qtouch verwendet, gibts auch ne C-Lib dazu.
Der Vorteil von Methode 4 ist, du kannst beliebig viele Sensoren auf einen Kondensator umladen und somit eine Matrix aufbauen.

Sp666dy
11.04.2012, 22:33
Ja Punt 3 war ja mein Vorhaben:

Ich würde dann ein Port als Eingang setzen, und den Kondensator aufladen und warten bis der Port High wird.
dann den Pull up widerstand setzen so der sich wieder entläd.
Das habe ich alles in einer "for" schleife gesetzt und zähl die Durchgänge bis der Port high wird.
Die laufvariabel wird dann abgefragt. sollte die sich ändern, braucht der Kondensator wegen den Finger länger, und
müsste das so abfangen.
Hab da mal zwei Zeilen geschrieben, werde es aber erst morgen Testen und optimieren sobald
meine Sachen ankommen.

[QUOTE]

#include <avr/io.h>


int main(void)
{
int var = 0;
int i = 0;
int grenzwert = 0; //grenzwert eintragen
int durchschnitt = 0;
DDRA = (0<<PA0);
PORTA = (0<<PA0);
DDRB = (1<<PB0);
PORTB = (0<<PB0);
while(1)
{
for (i=0;(1<<PA0);++i)
{

var= var+1;
}

PORTA=(1<<PA0);//Pullup aktivieren

for (i=0;(0<<PA0);++i)
{

var= var+1;
}
durchschnitt = var/2;

if(durchschnitt>=grenzwert)
{
PORTB = (1<<PB0);
}
else
{
PORTB = (0<<PB0);
}

}
}
[QUOTE]

Was ich mich jetzt nur gefragt habe, wie der hier (http://elm-chan.org/works/capsens/report_e.html) das macht, mit zwei Kondensatoren?
Ich glaube die sensor flache ist ein halber Kondensator und mittels den Finger vervollständigt man den Kondensator und
man fängt das ab.
Das was ich so Vorteilhaft finde ist die Schaltung (http://elm-chan.org/works/capsens/capsens.png) bei Ihm.
Und nach dem Video funktioniert sie sehr genau und parallel...

robin
12.04.2012, 10:06
Hi,

Die Kondensatoren bei ihm in der Schaltung sind Optional (Falls die Fläche zu klein ist), bzw Abblockkondensatoren.

Habe mal deinen Code überflogen und meine 2 Fehler gefunden zu haben.

1. Die Bedingung in deiner For-Schleife Da fehlt noch der Pin

2. Die Entladezeit musst du nicht messen, da die Relativ egal ist. Denn du entlädst den Sensor direkt an GND und das sollte innerhalb von ein Paar Takten erledigt sein (mit und ohne Finger). Wichtig ist die Ladezeit.

In deinem Späteren Code sollte der Pull Up am Pin dauerhaft deaktiviert sein, nur zum Messen wird er Aktiviert und dann hochgezählt, bis der Eingang high ist.



while(1)
{
PORTA=(0<<PA0);//Pullup deaktivieren um Sensor zu entladen

sleep(1); // Bestimmte Zeit warten, damit der Sensor entladen ist.

PORTA=(1<<PA0);//Pullup aktivieren um Sensor zu laden

for(i=0;PINA & (1<<PA0);i++) // Abfrage ob sensor schon geladen ist.
{
var=var+1; // Wird evtl nicht benötigt, da i schon hochgezählt wird (?)
}

// Ausgabe
if(var>=grenzwert)
{
PORTB=(1<<PB0);
}
else
{
PORTB=(0<<PB0);
}

}
}


So würde ich das Machen, bin aber in C nicht so fit, kann also noch ein Paar Fehler haben.

Sp666dy
12.04.2012, 10:22
Danke erstmal, hoffe ich Krieg heute meine Sachen und kann das mal so aufbauen!

Hat den schon jemand den Code von der Website durchgeguckt, wie er das macht, hab
sein ekläungs Text mal über google übersetzen lassen, da kam aber nichts vernümpftigen raus!

Sp666dy
12.04.2012, 22:39
:-( Es klappt nicht

Habe den Kondensator zwischen PA7 und masse gesteckt und die LED liegt an PA2


#include <avr/io.h>#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>






int main(void)
{

int i = 0;
int grenzwert = 20; //grenzwert eintragen

DDRA = (0<<PA7);
PORTA = (0<<PA7);
DDRA = (1<<PA2);
PORTA = (0<<PA2);

while(1)
{
PORTA=(0<<PA7);

_delay_ms(1);
PORTA=(1<<PA7);

for (i=0;PINA & (1<<PA7);++i)
{


}

if(i>=grenzwert)
{
PORTA = (1<<PA2);
}
else
{
PORTA = (0<<PA2);
}

}
}






Habe ein 2,2 pF Kerko dran...

Was ist falsch?

Besserwessi
13.04.2012, 00:03
Für die Messung muss wohl schon das Datenrichtungsregister umgeschaltet werden zum entladen des Kondensators.

Es ist auch zu beachten, das man sehr leicht Störungen von der Netzfrequenz einfängt. Es reicht also nicht eine Messung, sondern man wird viele Messungen über 20 ms Verteilt machen müssen. So ist das auch im längeren Code drin (nur für 1/60 s).

Sp666dy
13.04.2012, 15:23
aber um den Pull up wiederstand zu aktivieren reicht doch

PORTA=(1<<PA7);
oder nicht?

Besserwessi
13.04.2012, 18:21
Für die Messung muss man umschalten zwischen Ausgang-low und PullUp akitv. Dazu muss man sowohl das Daterichtungsregister (DRRA) ändern als auch das Ausgaberegister (PORTA).
Also etwa in der Reihenfolge:
DRRA=(1<<PA7);
PORTA=(0<<PA7);
etwas Warten
DRRA=(0<<PA7);
PORTA=(1<<PA7); // ab hier zählt die Zeit

In der Regel wird man das ganz auch noch mehrmals über 20 ms machen müssen und dann sehen wie oft man über die Schwelle kommt, bzw. was als Mittelwert rauskommt.

Sp666dy
13.04.2012, 19:25
Hab nach ein bisschen rum testen gemerkt das er immer in der schleife bleibt, also er nimmt nie den high Pegel an???




#include <avr/io.h>
#define F_CPU 1000000UL // 1 MHz
#include <util/delay.h>






int main(void)
{

int i = 0;
int grenzwert = 5; //grenzwert eintragen

DDRA = (1<<PA7);
PORTA = (0<<PA7);
DDRA = (1<<PA2);
PORTA = (0<<PA2);
_delay_ms(1);
while(1)
{
PORTA=(0<<PA7);

_delay_ms(1);
DDRA=(0<<PA7);// ab hier zählt die Zeit

for (i=0;PINA & (1<<PA7);++i)
{



}

if(i<=grenzwert)
{
PORTA = (1<<PA2);
}
else
{
PORTA = (0<<PA2);
}

}
}