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 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:
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 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:
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 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:
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 < 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