Kapacitív érintésérzékelés
A fejezet tartalma:- A kapacitív érintésérzékelés elve
- A TSI érintésérzékelő modul
- Programkönyvtárak a TSI modul kezeléséhez
- A TSI programkönyvtár
- Mintapélda: LED fényerejének
szabályozása
(04_TSISensor)
- A tsi_sensor programkönyvtár
- Mintapélda: a tsi_sensor könyvtár használata (04_tsi_slider)
- A csúszka használata nyomógombként
- Mintapélda: nyomógombok emulálása (04_tsi_buttons)
A kapacitív érzékelők akár a nyomtatott áramkörön közvetlenül is megvalósíthatók. Ennek előnyei:
- Rugalmasan megválasztható alak és méret
- A költséget csak a PCB és a járulékos elemek adják
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.
ahol:
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:
- Töltésmegosztás: a
mikrovezérlő egyik analóg bemenetét adott feszültségre feltöltjük, majd
összekapcsoljuk az érintésérzékelő szenzorral. A töltéskiegyenlítődés
után mérhető feszültség értéke más lesz, ha a szenzort megérintjükvagy
sem.
- Relaxációs oszcillátor: a
kapacitív szenzort egy relaxációs oszcillátor visszacsatoló körébe
helyezzük. A kondenzátor feltöltődési ideje és így a rezgés
periódusideje függ attól, hogy megérintettük-e az érzékelőt.
- Kisülési/feltöltési időmérése:
a kapacitív szenzor, mint kondenzátor feltöltési vagy kisütési ideje
függ attól, hogy mekkora a kapcitása, azaz megérintettük-e.
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).
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:
- Akár 16 db. érintésérzékelő elektróda kezelése
- Kapacitásváltozás detektálása beállítható alsó és felső küszöbérték figyelésével
- A bemenetek hardveres vagy szoftveres pásztázása
- Alacsonyfogyasztású mód <1uA áramfelvétel
- Lehetőség a mikrovezérlő felébresztésére
- DMA adatátvitel támogatása
- Nem kell külön alkatrész, a TSI bemenetek közvetlenül csatlakozhatnak a szenzor elektródákra (legfeljebb ESD védelemre lehet szükség)
- Egy kivezetés - egy elektróda típusú elrendezés
- A külső és a referencia oszcillátor egyformán reagál a
hőmérséklet és a tápfeszültség megváltozására

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 a FRDM-KL25Z kártya kapacitív csúszkájának kezeléséhez, ezért alkalmazásainkhoz kiegészítő 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ó mbed-official TSI programkönyvtár (ebben a szakaszban ennek használatával ismerkedünk meg).
A másik lehetőség a Martin Kojtal által közzétett tsi_sensor programkönyvtár, amellyel a következő szakaszban foglalkozunk majd.
A gcc4mbed offline fordítókörnyezetben a kiegészítő könyvtárak az external/mbed-libs mappában kapnak helyet, ezért a TSI könyvtárat az external/mbed-libs/TSI almappába, a tsi_sensor könyvtárat pedig az external/mbed-libs/tsi_sensor almappába kell bemásolni.
A könyvtárak használatához a program elején be kell csatolni a megfelelő fejlécállományt. A TSISensor könyvtár esetén ez a TSISensor.h, a tsi_sensor könyvtár esetén pedig a tsi_sensor.h. A fejléc becsatolása után a könyvtárak osztályai és függvényei ugyanúgy használhatók, mint bármely más Mbed 2 kompatibilis komponens.
Végül a projekthez tartozó Makefile‑ban meg kell adni, hogy a projekt milyen kiegészítő könyvtárakat használ. A TSISensor használatához a Makefile-t a USER_LIBS := ../../external/mbed-libs/TSI sorral kell kiegészíteni, a tsi_sensor könyvtár használata esetén pedig a USER_LIBS := ../../external/mbed-libs/tsi_sensor sorra lesz szükség. Ezáltal a gcc4mbed tudni fogja, hogy a projekt a megadott könyvtárakat is használja, és automatikusan be fogja fordítani őket.
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.Hardver követelmények:
- FRDM-KL25Z kártya
#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 projekthez tartozó Makefile‑ban meg kell adni, hogy a projekt milyen kiegészítő könyvtárakat használ. A TSISensor használatához a Makefile-t a USER_LIBS := ../../external/mbed-libs/TSI sorral kell kiegészíteni.
A 04_TSISensor projekt Makefile állománya:
PROJECT := 04_TSISensor
DEVICES := KL25Z
GCC4MBED_DIR := ../..
GCC4MBED_TYPE := Release
USER_LIBS := ../../external/mbed-libs/TSI
MBED_OS_ENABLE := 0
NEWLIB_NANO := 1
NO_FLOAT_SCANF := 1
NO_FLOAT_PRINTF := 1
include $(GCC4MBED_DIR)/build/gcc4mbed.mk
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 kétféle objektumosztályt definiá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:
- A TSIAnalogSensor objektum konfiguráláshoz a mikrovezérlő kivezetések neve (esetünkben PTB16, PTB17) helyett a TSI modul csatornaszámait is használhatjuk (esetünkben 9 és 10).
- 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: 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:
- FRDM-KL25Z kártya
#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 projekthez tartozó Makefile‑t most a USER_LIBS := ../../external/mbed-libs/tsi_sensor sorral kell kiegészíteni.
A 04_tsi_slider projekt Makefile állománya:
PROJECT := 04_tsi_slider
DEVICES := KL25Z
GCC4MBED_DIR := ../..
GCC4MBED_TYPE := Release
USER_LIBS := ../../external/mbed-libs/tsi_sensor
MBED_OS_ENABLE := 0
NEWLIB_NANO := 1
NO_FLOAT_SCANF := 1
NO_FLOAT_PRINTF := 1
include $(GCC4MBED_DIR)/build/gcc4mbed.mk
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:
- FRDM-KL25Z kártya
- USB kábel a PC és a kártya OpenSDA csatlakozó összekötéséhez
#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 < sizeof(BTNMAX)/sizeof(BTNMAX[0]); i++)
if (v < BTNMAX[i]) return i;
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 < newbtn)
realbtn = SWIPE_R;
else
realbtn = SWIPE_L;
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.
A projekthez tartozó Makefile‑t itt is a USER_LIBS := ../../external/mbed-libs/tsi_sensor sorral kell kiegészíteni.
A 04_tsi_buttons projekt Makefile állománya:
PROJECT := 04_tsi_buttons
DEVICES := KL25Z
GCC4MBED_DIR := ../..
GCC4MBED_TYPE := Release
USER_LIBS := ../../external/mbed-libs/tsi_sensor
MBED_OS_ENABLE := 0
NEWLIB_NANO := 1
NO_FLOAT_SCANF := 1
NO_FLOAT_PRINTF := 1