6.10.2014

Yhdestä on moneksi - analogitekniikkaa

R-2R vastusverkko-painike-juttu.
Mikrokontrollereissa on pinnejä, joihin saa kiinni kaikenlaista. Jotkut pinneistä ovat digitaalisia (0 tai 1) ja jotkut pinneistä ovat analogisia (0 ... 1). Jos projektin tavoitteena on tunnistaa painikkeen painalluksia ja mikäli digitaalisia pinnejä ei ole enää vapaana painikkeiden kytkemiseen, vastusverkolla (tai -tikapuilla) voidaan kytkeä monta painiketta analogiseen pinniin.

Tarve tällaiselle temppuilulle ilmeni, koska projektissa käyttämäni Adafruitin Trinket perustuu ATtiny85 -mikrokontrolleriin ja siinä on vain 5 kappaletta käytettävissä olevia GPIO (General Purpose Input and Output) pinnejä.

Ajatuksien tueksi tarjottua

Tutoriaalista napattu kytkentäkaavio.

Tavoitteenani oli siis lukea arduino-yhteensopivalla mikrokontrollerilla kahden (tai useamman) painikkeen tilatietoa käyttäen vain yhtä pinniä. Koska elektroniikkajutut ovat joiltakin osin aina yli ymmärrykseni meneviä juttuja, tein tämän kytkennän netistä löytyvää tutoriaalia (linkki [1]) mukaillen.

Osat ja oma suunnitelma

Muokattu kytkentäkaavio, 2 painiketta.

Tutoriaalin perusteella aloitin piirtämällä omiin tarkoituksiini sopivamman ja yksinkertaisemman kytkentäkaavion ja käymällä komponenttikaupassa. Ostoslistalle päätyi:
  • piikkirimaa (vasemman reunan liittimet)
  • 3kpl 22kOhm vastuksia
  • 2kpl pieniä painonappeja
  • 1kpl 10kOhm vastus
Kytkennän pohjaksi kotilaatikon pohjalta löytyi vielä sopiva protolevyn palanen.

Osasijoittelu, tältä sen pitäisi lopulta näyttää.
Osia, kytkentäkaaviota, Fritzingiä ja protolevyä hetken pyörittelemällä ja tuumailemalla sain aikaiseksi mielestäni myös kohtuullisen kompaktin osasijoittelu-kaavion. Harmittaa hieman, ettei Suomen kielessä ole oikeasti hyvää vastinetta sanalle contraption (=härveli, viritys, häkkyrä?), sillä seuraavaksi aloitin rakentamaan sellaista.

Kolvi kuumaksi

Kytkentään tarvittavat osat valmiina.
Huolellisesti valmisteltuna rakentaminen on helpompaa. Kokeilin osien sijoittamista piirilevylle ja merkitsin kuparointien katkaisukohdat tussilla. Kytkennässä tarvittavan hyppylangan katkaisin yhden vastuksen jalasta.

Valmis tuotos, komponenttipuoli.
Valmis tuotos, juotospuoli.
Sellainen siitä sitten tuli. Testasin kytkennät yleismittarilla oikosulkujen varalta (ei ollut) ja että vastusarvot vaihtuivat odotetusti erilaisilla painike-yhdistelmillä.

Miten se toimii?

Testisetup.
Toimiihan se. Testasin tuotostani kytkemällä painikepiirin Arduino nano-klooniin (musta-GND, punainen-5V, valkoinen-A6). Tämän lisäksi kirjoitin lyhyen testisketchin[2] (=arduino-ohjelma), jossa analogReadilla painikkeilta luettu arvo ja näytteen aikaleima tulostetaan sarjaporttiin. Lyhyen testailun jälkeen jatkojalostin sketchiä tulostamaan myös raja-arvojen ylitykset, eli tiedon siitä, mikä painike on painettuna.

Testiohjelmien perusteella tekemiäni havaintoja:
  1. Kytkentä toimii, eli painikkeet ovat tunnistettavissa sekä erikseen että yhdessä painettuina
  2. Kytkennän palauttamat arvot vaeltavat käytettäessä hieman ylöspäin, ilmeisesti lämmön vaikutuksesta vastuksiin.
  3. Ns. "laakista" onnistuminen saa aikaan välittömän Guru-fiiliksen!
  4. Kytkentä tuntuu ehkä sittenkin hieman hitaalta
    • nopeat painikkeen painallukset eivät ylitä raja-arvoja
    • painikkeen vapautus aiheuttaa väärän painikkeen tunnistuksen ennen oikeaa tunnistusta
Testiohjelmassa Arduino oli asetettu lukemaan arvoja 20ms välein, siksi yllätyin hieman kytkennän "hitaudesta". Ajatustyötä helpottaakseni kopioin sarjaportin konsoliin tulostetut arvot taulukkolaskentaohjelmaan ja piirsin tuloksista graafin.

Debuggausta

Vaaka-akseli: millisekunnit; pysty-akseli: analogRead arvo
Jos ei muuta, niin graafinen esitys paljastaa piirin analogisen luonteen. Piiri reagoi painikkeen painamiseen ja Arduino tunnistaa sen, mutta haluttu raja-arvo ylittyy vasta kun painike on ollut hetken kytkettynä. Aikajanalla tarkasteltuna raja-arvon ylittyminen kestää noin 1000ms eli noin sekunnin verran. Painonapin tunnistamiseen sekunti on kuitenkin mielestäni kohtuuttoman paljon aikaa.

Lähdin etsimään ajatuksia, miksi piiri toimii tällä tavalla ja miksi analogipinnin näkemän jännitteen nouseminen tavoitetasoon kestää. Parhaiten tätä asiaa oli mielestäni selitetty powerpoint-esityksessä "Digital to Analog converter" (linkki [3]):

DAC-piirille syötetyn analogisignaalin asettumista kuvaava graafi.
Vaikka ilmiö selveni hieman ja ongelma jäljittyi analogisignaalin digitaaliseksi muuntamiseen, muunnoksen kestolle löytyi järkevä selitys vasta Atmelin dokumentaatiosta. Käyttämäni arduino-kloonin ytimenä on ATmega328, jonka datalehteä (linkki [4]) selatessa tuli vastaan selitys A-D -muuntimen tarkemmasta toiminnasta.

Lainaus Atmel ATmega datalehdeltä, kappaleesta 24.6.1
Tekstiosuus selventää, että muunnin (ADC) on optimoitu analogisignaaleille, joiden impedanssi[5] on noin 10 kOhm tai pienempi. Tällaista lähdettä käytettäessä näytteistysaika jää merkityksettömäksi, mutta jos lähteen impedanssi on korkeampi, näytteistysaika riippuu paljolti siitä, kuinka kauan lähteeltä kestää varata kuvassa näkyvä C(s/h) = 14pF -merkitty kondensaattori.

Tarkistuslaskelmat

Kauanko 14 pikofaradin kondensaattorin varaaminen viidellä voltilla ja 31,9 kOhm tai 22 kOhm vastuksella sitten kestää? Jännitteen putoaminen on laskettavissa kaavalla tai vastuslaskureilla[6], joten nyt täytyisi selvittää, kauanko 14pF varaaminen 2,5 tai 2,037 voltilla kestää. Tähän tarkoitukseen on toki olemassa kondensaattorin varaus- ja purkulaskuri[7], jonka mukaan huonoimmassa tapauksessa aikaa kuluisi noin 213 nanosekuntia.

14pF kondensaattorin 0-2,5V varaamiseen kuluva aika, 5V jännitteellä (mustcalculate.com)
Jotakin mätää, sano. Oman mittausdatani mukaan aikaa tavoitejännitteeseen kuluu noin sekunti, kun taas laskurin mukaan aikaa pitäisi kulua vain 0,0000021 sekuntia. Täytynee jatkaa harjoituksia ja tutkia vielä sarjaporttiin tulostamisen vaikutus viiveeseen. Tai sitten kokeilla niitä pienempiä tai tarkempia vastuksia.

Linkit

[1] http://tronixstuff.com/2012/02/29/tutorial-analog-input-for-multiple-buttons-part-two/
[2] http://arduino.cc/en/Tutorial/AnalogInOutSerial
[3] http://ume.gatech.edu/mechatronics_course/DAC_F05.ppt
[4] http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf
[5] http://fi.wikipedia.org/wiki/Impedanssi
[6] http://www.raltron.com/cust/tools/voltage_divider.asp
[7] http://mustcalculate.com/electronics/capacitorchargeanddischarge.php?vfrom=0&vto=2.5&vs=5&c=14p&r=22k

Ei kommentteja :

Lähetä kommentti