Vývoj dotykové klávesnice pro vaše zařízení

11. ledna 2011 ve 20:33

Vývoj dotykové klávesnice pro vaše zařízení

  • DIY nebo Udělej si sám

V tomto článku popíšu proces vývoje dotykové klávesnice, kterou můžete používat ve svých zařízeních. Taková klávesnice není náročná na sestavení, protože... Nejsou zde žádné mechanické části a to, co postrádá na mechanické zpětné vazbě, vynahrazuje elegancí použití.

Při vývoji jednoho projektu jsem potřeboval pohodlnou klávesnici s 8 tlačítky. Rozhodl jsem se uchýlit se ke známému přístupu – implementovat kapacitní senzory.
Fyzikální teorii jsem již popsal ve svém článku o zařízení-suvenýru, který jsem cítil, když jsem jej vzal do ruky (http://habrahabr.ru/blogs/DIY/111627/)
Princip zůstává naprosto stejný, rozdíl je pouze v implementaci – nejsou použity dva piny mikrokontroléru, ale jeden.
Nejprve video o tom, o co se budeme snažit:

Krok 1: Návrh obvodu

Obvody senzorů se mírně změnily, a to z toho důvodu, že je nutné použít pouze jednu nohu mikrokontroléru na senzor, nikoli dvě. Pokud vám však nevadí nohy navíc, můžete vše nechat jako dříve.

Pořadí, ve kterém je senzor dotazován, se bude mírně lišit. Zpočátku se na pin PD0 přiloží protokol. 0.
Proud tedy teče z napájecího zdroje přes megaohmový odpor a teče do pinu. Pokud byl senzor nabitý, pak proud z něj poteče i do pinu PD0.

V době dotazování přepneme pin z výstupu na vstup (složené závorky jsou deaktivovány!). V tomto okamžiku přechází kolík do vysokoimpedančního stavu s odporem v řádu několika desítek (nebo dokonce stovek) MOM. Proud ve směru kolíku prakticky přestane téct a začne téci směrem k senzoru. Jakmile je snímač nabit na napětí nad úrovní log. 1, tento vstup mikrokontroléru zobrazí jedničku.
Měřením času, který uplynul od okamžiku, kdy se PD0 přenesl do vysokoimpedančního stavu, dokud se na něm neobjeví log 1, můžeme usoudit, že se změnila kapacita snímače, a proto zachytit okamžik dotyku.

Konstrukčně je senzor obdélníková kontaktní podložka 10x10 mm, ale ve skutečnosti je jeho tvar prakticky neomezený, můžete vytvářet kruhy, hady, rozdělit je na segmenty a sektory - obecně zadávat informace v jakékoli formě.

Níže je fotka hotové DPS. Deska je na zakázku, ale vyrobit si ji doma také není nic složitého. Při použití prkének na krájení na krájení může jako senzor fungovat kus fóliového skelného vlákna nalepeného na horní straně desky.

Nad každým senzorem je SMD dioda pro indikaci tlaku.
To vše řídí mikrokontrolér ATMega88, taktovaný na 20 MHz.
Výstupem z této klávesnice tedy může být cokoliv, co potřebujete a co chcete. V mém případě bylo SPI pohodlné (flashoval jsem a testoval bez odpojení od programátoru a tato sběrnice již byla v zařízení povolena), ale můžete použít UART, I2C, zabudovaný v mega spolu s SPI, nebo použít USB implementace softwaru od ObjDev. Ano, ve skutečnosti je to možné pomocí hardwaru, jako je převodník FTDI USB->UART.

Konečný diagram (snímek obrazovky z Altium) je uveden níže.

Opět nic složitého, nic nadbytečného - mega obvod, který to taktuje, dvojice konektorů vyhlazujících výkon, konektor pro programování/připojení, 8 diod a 8 senzorů.

Co je zajímavé: vzdálenost, na kterou senzor ucítí ruku, závisí na bitové kapacitě časovače, jeho frekvenci a také na odporu, přes který je senzor připojen. To se vysvětluje jednoduše – rychlejší časovač bude schopen detekovat menší časové intervaly a při absenci galvanického kontaktu se senzorem se výrazně zkrátí doba nabíjení. 20 MHz mega a jeho 16bitový časovač stačí na sebevědomou detekci dotyku přes vrstvu plastu (plexiskla) o tloušťce cca 1 mm.
Mega můžete mírně přetaktovat a mírně zvýšit odpor, ale je lepší se tím nenechat unést - stabilita přetaktovaného mega není zaručena a příliš velký odpor může vyrovnat nabíjecí proud se svodovým proudem, který učinit senzor navždy neaktivní.
Ať je to jak chce, běžný provoz úplně stačí na to, abyste senzory zakryli tenkým kusem plastu. Ideální variantou by bylo nastříkat na sklo vodivý povlak, ale moc příležitostí experimentovat jsem v tomto směru neměl.

Krok 2: Kód

V zásadě již bylo vše popsáno výše, ale pro určitou jasnost uvedu kód projektu.

#zahrnout #zahrnout unsigned char KBD_STATUS=0x00, TMP_STATUS=0x00; //Aktuální stav klávesnice a proměnná, kam budeme zapisovat nový stav unsigned short SensorTimes=(0,0,0,0,0,0,0,0); //Doby odezvy senzoru bez znaménka krátké SensorHI=(0,0,0,0,0,0,0,0), //Pro urychlení výpočtů - předem vypočítané SensorLO=(0,0,0,0,0, 0, 0,0); //horní a dolní prahové hodnoty void CheckSensors(); unsigned short SensToLED=(8,16,32,1,4,2,1,2); //Přidat. pole, protože diody visí na náhodných nohách) ISR(TIMER0_OVF_vect) ( CheckSensors(); //Zkontrolujte, zda jsou senzory (bez znaménka short i=0;i<8;i++) { if(KBD_STATUS&(1<SensorHI[k]) //Hystereze aby neškubal na mezní hodnotě kapacity TMP_STATUS|=i; jinak if(TCNT1<=SensorLO[k]) TMP_STATUS&=~i; k++; i<<=1; } KBD_STATUS=TMP_STATUS; } int main() { DDRD=0xFF; PORTD=0x00; PORTC=0xFF; DDRC=0xFF; TCCR0=0b00000101; TCNT0=0x00; TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; MCUCR=0x00; TIMSK=0x01; ACSR=0x80; SFIOR=0x00; InitSPIMode3(); for(int i=0;i<1024;i++) //Просто чтобы не калиброваться сразу как подадут питание CheckSensors(); // подрыгаем сенсорами) KBD_STATUS=0x00; TMP_STATUS=0x00; Calibrate(); //Калибруемся sei(); while(1); }