Kapacitív érintésérzékelés

A fejezet tartalma:
Az elektronikai iparban egyre több helyen váltják ki a hagyományos nyomógombokat és kezelőszerveket különféle érintésérzékelő eszközzel. Ennek előnyei az alacsony előállítási költség és a hosszabb élettartam. Az érintésérzékelés különféle megvalósítási lehetőségei közül (optikai, rezisztív, illetve kapacitív) most a kapacitív érintésérzékeléssel foglalkozunk.

A kapacitív érzékelők akár a nyomtatott áramkörön közvetlenül is megvalósíthatók. Ennek előnyei:

A kapacitív érintésérzékelés elve

Nyugalmi helyzetben az érzékelő elektróda és a föld közötti csak a CX = CP szórt kapacitás mérhető (többnyire 10 pF nagyságrendű).

Az ujjunkkal, mint földelt vezetővel megérintett érzékelő esetén megnövekedett CX = CP + CF kapacitást érzékelünk.

CF = ε0·εr·A/d

ahol:
A – az érintési felület nagysága
d – a fedőréteg vastagsága



Többféle módszer ismeretes a szenzor kapacitások megváltozásának detektálására, mint például:

A TSI - érintésérzékelő modul

A Freescale Kinetis MKL25Z128VLK4 mikrovezérlő TSI (Touch Sensing Input) moduljának érintésérzékelő megoldása a relaxációs oszcillátor elvéhez hasonlít, de a szokásos RC kör helyett a szenzor kapacitását két állandó áramú forrás kapcsolgatásával töltjük fel, illetve sütjük ki. Az így előálló háromszögjel frekvenciája a szenzor kapacitásától függ,  tehát megváltozik, ha megérintjük a szenzort. Az oszcillátor működését az alábbi ábra szemlélteti. A szenzor megérintésekor a jel frekvenciája megváltozik (lecsökken).

2. ábra: Az érintésérzékelő bemenetre kötött oszcillátor felépítése és jelalakja

A mikrovezérlő az érintésérzékelő bemenetre csatlakozó oszcillátor mellett egy referencia oszcillátort is tartalmaz, ami egy fix belső kapacitást használ. Így a két oszcillátor frekvenciájának összehasonlításával a hőmérséklettől és a tápfeszültségtől való függés kiküszöbölhető.

A Freescale Kinetis MKL25Z128VLK4 mikrovezérlő TSI (Touch Sensing Input) moduljának jellemzői:
A Freescale Kinetis MKL25Z128VLK4 mikrovezérlő TSI (Touch Sensing Input) moduljának blokkvázlatát az alábbi ábrán mutatjuk be. Látható, hogy a TSI0..TSI15 bemenetek egy analóg multiplexeren keresztül ugyanarra az oszcillátorra csatlakoznak, így lekérdezésük csak sorban, egymás után lehetséges. Erre az egymás utáni lekérdezésre utal a jellemzők felsorolása között a "pásztázás" (scan).



3. ábra: A Freescale Kinetis MKL25Z128VLK4 mikrovezérlő TSI moduljának blokkvázlata

A FRDM-KL25Z kártyán a 16 TSI bemenet közül kettő van bekötve egy, a nyomtatott áramköri lapon kialakított csúszka két végére: TSI09 (PTB16) és TSI10 (PTB17). A csúszka működése azon alapul, hogy a két szembefordított háromszög alakú elektróda megérintésekor az érintés helyétől függően a kapacitásváltozás különböző lesz. Így a két bemenet kapacitásváltozásának arányából az érintés helye meghatározható.

4. ábra: A FRDM-KL25Z kártya kapacitív csúszkájának bekötése

 

Programkönyvtárak a TSI modul kezeléséhez

Az alapértelmezett mbed API nem tartalmaz beépített függvényeket FRDM-KL25Z kártya kapacitív csúszkájának kezeléséhez, ezért alkalmazásainkhoz megfelelő programkönyvtárat kell importálni, amelyre több lehetőség, illetve programkönyvtár változat is rendelkezésünkre áll:

Az egyik lehetőség a Components/Sensors gyűjteményben található KL25Z TSI programkönyvtár (ebben a szakaszban ennek használatával ismerkedünk meg), amely kifejezetten a FRDM-KL25Z kártya kapacitív csúszkájának kezeléséhez készült. Ennek becsatolásához a fenti linkre történő kattintás után az Import Library feliratú gombra kell kattintanunk.

A másik lehetőség az mbed Compiler ablakból is importálható, Martin Kojtal által közzétett tsi_sensor programkönyvtár, amellyel a következő szakaszban foglalkozunk majd.

A TSI programkönyvtár

A Components/Sensors gyűjteményben található KL25Z TSI programkönyvtár a TSISensor objektumosztályt definiálja FRDM-KL25Z kártya kapacitív csúszkájának kezeléséhez. A tagfüggvények felsorolása az alábbi táblázatban található. Mivel a programkönyvtár kimondottan ehhez a kártyához készült, a csúszka mérete és a hozzá rendelt két kivezetés (PTB16, PTB17) ismert, ezért a konstruktor függvény nem igényel paramétereket.

Függvény
Felhasználás
TSISensor()
A konstruktor, amely létrehoz egy "név" nevű TSISensor  objektumot és a FRDM-KL25Z kártya kapacitív csúszkájának kezeléséhez konfigurálja  az érintésérzeklő TSI modult
readPercentage()
Az érintés helyének megadása 0.0 - 1.0  közötti érték formájában (float)
readDistance()
Az érintés megadása (0 - 40 közötti érték formájában (uint8_t)

Megjegyzés: Ha nincs megérintve a csúszka, akkor minden kiolvasás 0 értékkel tér vissza. Ez a gyakorlatban azt jelenti, hogy a csúszka bal szélső véghelyzete és a nem érintett állapot elvileg nem különböztethető meg.

Mintapélda: LED fényerejének szabályozása

Az alábbi mintaprogramban a kék LED teljesítményét szabályozzuk kapacitív csúszka segítségével. A projekt létrehozása után ne felejtsük el importálni a TSI programkönyvtárat (a FRDM KL25Z on-board Capacitive Touch Sensing oldalon kattintsunk az Import Library gombra).


Hardver követelmények:
1. lista: A 04_TSISensor/main.cpp program listája
#include "mbed.h"
#include "TSISensor.h"

int main(void) {
PwmOut led(LED_BLUE); //Configure a PWM output for the blue LED
TSISensor tsi; //Configure the touch sensing module
led = 1.0; //LED off at the beginning
while (true) {
float s = tsi.readPercentage(); //Read slider status
if (s > 0.01) led = 1.0 - s; //Control LED power if touch occurred
wait(0.1); //wait a little...
}
}
A TSI könyvtár használatba vételéhez a program elején be kell csatolni a TSISensor.h fejléc állományt is. A főprogram elején egy PWM kimenetet konfigurálunk a FRDM-KL25Zkártya kék LED-jéhez, majd konfiguráljuk a TSI modult a kártyára épített csúszkához. A közös anódú RGB LED fordított logikája miatt 100 %-ra kell állítanunk a PWM jel kitöltését ahhoz, hogy induláskor ne világítson a LED.

A végtelen ciklusban periodikusan kiolvassuk a kapacitív csúszka állapotát, s ha érintés történt (a kiolvasott állapot nem nulla), akkor az érintés helyének függvényében szabályozzuk a LED teljesítményét.

A tsi_sensor programkönyvtár

Martin Kojtal tsi_sensor programkönyvtára összetetteb és általánosabb, ennek következtében némileg bonyolultabb is, mint a fentiekben tárgyalt TSI könyvtár. Egyrészt többféle Freescale Kinetis mikrovezérlő kártyához is használható, másrészt hozzáférést  nyújt az alapvonal és az érzékelési  küszöb beállításához is (ezekkel azonban itt nem foglalkozunk).

A tsi_sensor programkönyvtár projektjeinkbe a fenti link megnyitása után az Import Library gombra történő kattintással is becsatolható, de az mbed Compiler oldalon az Import varázsló segítségével is rákereshetünk és közvetlenül becsatolhatjuk.

A tsi_sensor programkönyvtár kétféle objektumosztályt definiál:
TSIElectrode - a felhasznált TSI modul bemeneteinek konfigurálására szolgál
TSIAnalogSlider - egy analóg csúszkát konfigurál


A TSIAnalodSlider kapacitív csúszkát definiál (az előző szakaszban tárgyalt TSI könyvtár TSISensor objektumához hasonlóan), tagfüggvényeinek felsorolása az alábbi táblázatban található. Mivel a programkönyvtár többféle kártyához is használható, a csúszka méretét és a hozzá rendelt két kivezetést (PTB16, PTB17) paraméterként meg kell adni a konstruktor hívásakor.

Függvény
Felhasználás
TSIAnalogSlider név(pin1, pin2,width)
A konstruktor, amely létrehoz egy "név" nevű TSIAnalogSlider  objektumot és a TSI modul megadott kivezetésekhez rendeli hozzá, s a width paraméterrel megadott csúszkaméretet is eltárolja
readPercentage()
Az érintés helyének megadása 0.0 - 1.0  közötti érték formájában (float)
readDistance()
Az érintés megadása (0 - 40 közötti érték formájában (uint8_t)

Megjegyzések:

Mintapélda: a tsi_sensor könyvtár használata

Az alábbi mintaprogramban a zöld LED teljesítményét szabályozzuk kapacitív csúszka segítségével. A projekt létrehozása után ne felejtsük el importálni a tsi_sensor programkönyvtárat az mbed Compiler oldalon az Import varázsló segítségével!


Hardver követelmények:
2. lista: A 04_tsi_slider/main.cpp program listája
#include "mbed.h"
#include "tsi_sensor.h"

int main(void) {
PwmOut led(LED_GREEN); //Configure PWM output for the green LED
TSIAnalogSlider tsi(PTB16,PTB17,40);//Configure for the FRDM-KL25Z slider
while (true) {
float s = tsi.readPercentage(); //Read slider status
led = 1.0 - s; //Control LED power
wait(0.1); //wait a little...
}
}
A tsi_sensor programkönyvtár használatba vételéhez a program elején be kell csatolni a tsi_sensor.h fejléc állományt is. A főprogram elején egy PWM kimenetet konfigurálunk a FRDM-KL25Z kártya zöld LED-jéhez, majd konfiguráljuk a TSI modult a kártyára épített csúszkához. A közös anódú RGB LED fordított logikája miatt a PWM jel kitöltése = 1.0 - csúszkaállás lesz.

A végtelen ciklusban periodikusan kiolvassuk a kapacitív csúszka állapotát, s az érintés helyének függvényében szabályozzuk a LED teljesítményét. Ebben a programban nem foglalkoztunk a csúszka elengedésének viszgálatával, ezért ha elvesszük a kezünket a csúszkáról, a LED kialszik. A LED állapotának megőrzését az előző programban használt feltételvizsgálattal oldhatnánk meg.

A csúszka használata nyomógombként

Előfordul, hogy el alkalmazáshoz a kapacitív csúszka helyett nyomógombokra lenne szükségünk. Ilyenkor a csúszkát feloszthatjuk 2, 3, vagy 4 részre, és az érintés helyétől függően az érintett szakaszhoz tartozó "virtuális" gombot tekintjük megnyomottnak.

AI Williams
a Dr.Dobbs honlap bloggere közzétett egy mintaprogramot, amely a FRDM-KL25Z kártya csúszkájának segítségével legfeljebb 4 db nyomógomb emulálására alkalmas, illetve emellett a jobbra/balra húzást is képes detektálni. Az alábbiakban ezt a programot ismertetjük röviden, AI Williams: The Touch of a Button című írása nyomán .

Megjegyzés:  Az emuláció egy adott működési környezetet más körülmények között utánzó technológia. Esetünkben az emuláció azt jelenti, hogy olyan alkalmazást is írhatunk/futtathatunk, ami  max. 4 db nyomógombot használ,  amelyeket mi a  kapacitív csúszka egy-egy szakaszával helyettesítünk.

Mintapélda: nyomógombok emulálása

Az alábbi program 4 db nyomógombot emulál, emellett a jobbra-balra húzást is képes detektálni. A program legnagyobb része a nyomógom emulációval kapcsolatos függvényekből áll. A végtelenül leegyszerűsített főprogram itt csak annyit csinál, hogy periodikusan lekérdezi a nyomógombok állapotát, s lenyomás észlelésekor kiírja az állapotot a képernyőre.

A kiíratáshoz az OpenSDA hibavadász és USB-UART protokol konver áramkörön keresztül kommunikálunk a számítógéppel. Ez a kommunikációs csatorna a mikrovezérlő felől soros portnak látszik, ezért a Serial objektumosztályt használjuk fel hozzá, s ennek példányosításakor az USBTX, USBRX (PTA2, PTA1) kivezetéseket rendeljük hozzá.  A számítógép felől ez a kommunikációs csatorna virtuális soros portnak látszik (a Windows eszközkezelőjében mbed Serial Port (COMxx) néven találjuk meg a COM és LPT portok között. Az alapértelmezett beállítás: 9600 baud, 8 bit, 1 stop bit, paritás és adatfolyam-vezérlés nélkül. Bármilyen terminálemulációs program (Hyperterminal, PuTTY, stb.) megfelel a kiírások nyomonkövetéséhez.

Hardver követelmények:
3. lista: A 04_tsi_buttons/main.cpp program listája
#include "mbed.h"
#include "tsi_sensor.h"

// Simple button/swipe library for FRDM-KL25Z
// AI Williams -- The Touch of a Button
// Dr.Dobb's Journal
// http://www.drdobbs.com/embedded-systems/the-touch-of-a-button/240169431


//-- Define the "zones" considered to be buttons
float BTNMAX[]= {0.25, 0.50, 0.75, 1.00 };
#define SWIPETIME .350 // seconds to wait before sensing a button push or swipe
#define SWIPE_R 256 // virtual button code for right swipe
#define SWIPE_L 512 // virtual button code for left swipe

Serial pc(USBTX, USBRX); // tx, rx for serial connection
TSIAnalogSlider tsi(PTB16,PTB17,40); // configure the Analog slider
Timeout scan;

int candidate=-1; // possible button push (-1 is none)
volatile int realbtn=-1; // actual button push (-1 is none)
volatile int hold=0; // waiting for button release when 1

//-- internal function to get raw button state
int getrawbtn()
{
float v=tsi.readPercentage(); // read slider
if (v==0.0) return -1; // no button at all
for (int i=0;i
if (v
return -1; // what?
}

// This is called by the timeout to either see there is no swipe
// see that there is a swipe or see that there is a button release
void checkbtn(void)
{
int newbtn=getrawbtn();
if (hold!=0 && newbtn==-1) // wait for key release
{
hold=0; // released so
return; // don't reschedule me
}
// reschedule us for next swipetime
scan.attach(checkbtn,SWIPETIME);
if (hold) return; // still waiting for release
hold=1; // we will be waiting for release from now on
if (newbtn==-1||newbtn==candidate) // if no touch or button is the same...
{
realbtn=candidate; //... the candidate is the button
return;
}
// Otherwise we are swiping either left or right
if (candidate return;
}

// This is the main API
// Call it to get a button code (0-3 or 256 or 512)
// You can block or not (default is to block)
int getbtn(bool kwait=true)
{
while (hold) // if holding, either wait or return
{
if (!kwait) return -1;
}
realbtn=-1; // mark that we don't know
do
{
candidate=getrawbtn(); // get a candidate (or return if not waiting)
} while (candidate==-1 || !kwait);
if (candidate==-1) return -1;
scan.attach(checkbtn,SWIPETIME); // schedule the checkbtn routine
while (realbtn==-1); // wait for realbtn to get set
return realbtn; // return it
}

// Simple test program
int main(void) {

while (true) {
pc.printf("Button %d\r\n",getbtn());
}
}
A kapacitív csúszkát négy egyenlő részre oszjuk, így 25 % alatti pozícióban történő érintés a 0. gomb lenyomását, 25 - 50 % között az 1. gomb megnyomását, 50 - 75 % között a 2. gomb megnyomását, az efölötti pozíciók pedig a 3. nyomógomb megnyomását jelentik.

Mivel az analóg csúszka kezeléséhez itt is a tsi_sensor programkönyvtárat használjuk, ezért a program elején be kell csatolni a tsi_sensor.h fejléc állományt. Ezután példányosíthatjuk a TSIAnalogSlider objektumot, melyet a FRDM-KL25Z kártyához konfigurálunk (40 mm-es csúszkahossz, PTB16, PTB17 kivezetések).

A Serial objektum a soros kommunikációhoz kell (ezen keresztül íratjuk ki az észlelt lenyomásokat).

A Timeout objektum az ébresztőórához hasonlóan használható: beáálíthatjuk, hogy mennyi idő elteltével melyik függvény kerüljön meghívásra. Itt most a nyomógomb lenyomásokat figyelő checkbtn() függvény 0.35 másodpercenkénti meghívására használjuk.

A főprogram végtelen ciklusban (virtuális) gomblenyomásra vár, majd kiírja a lenyomott gomb kódját.