14.7.12

OpenWRT a i2c

Chcel som spravit ovladanie zahradnych polievatok. Kupil som kvoli tomu zariadenie od SparkFun (USB bit whacker). Problem je, ze to zariadenie je nestabilne. Vacsinu casu ide, ale prave ked sa nan clovek spolahne, tak zvazi, ze sa odpoji od USB. A co je dalsi probem - zariadenie nema obojsmerny buffer pre vsetky I/O porty. Konkretne clovek posle na vystup hodnotu a chce si ju precitat a ma smolu - precita prve 3 alebo 4 bity a hotovo. Tak som hladal ine zariadenie - nieco, co by bolo potencionalne lacnejsie, ako UBW. A nasiel som. Zistil som, ze existuje zbernica s nazvom I2C. Na nu su za doslova par halierov pripojitelne vstupno-vystupne expandery, teplotne cidla a podobne srandy. Dalej som zistil, ze v linuxe je modul, ktory dokaze zbernicu I2C simulovat - v podstate ju simuluje z obycajnych I/O vystupov, ktore routery uz davno maju. Problem je, ze som sa nechcel hned hrabat v HW - v podstate by som nemal sancu zistit, ci to realne funguje. Kedze nemam k dispozicii ziadne ine i2c zariadenie, o ktorom by som vedel, ze funguje, mohol by to byt zdlhavy postup. A tak som pozeral po nejakom i2c adaptery. Po niecom, co by nestalo 60 EUR teda ;) A nasiel som, projekt, kde 2 adaptery (HW na nich) stali 10 EUR spolu. Kupil som si aj jedno Arduino (to bolo trosku nad rozpocet popravde), aby som do toho maleho cipu (ATtiny45) mohol nahrat firmware. Podla navodu som to vyskusal a fungovalo to.
Nahral som tam teda firmware zo stranky i2c-tiny-usb. To chvilu trvalo, musel som trosku zmenit subor Makefile a upravil som tam riadok
FLASH_CMD = avrdude -P$(TTY) -c stk500hvsp -p attiny45 -U lfuse:w:0xdf:m -U hfuse:w:0x5f:m -U flash:w:main.hex
a upravil vzhladom na to, ze pouzivam na nahravanie firmware Arduino, takze je tam teraz takyto:
FLASH_CMD = avrdude -v -v -P$(TTY) -c arduino -b 19200 -p attiny45 -U lfuse:w:0xdf:m -U hfuse:w:0x5f:m -U flash:w:main.hex
Ma to jednu malinku nevyhodu - musi sa to nahrat na prvy pokus, pretoze to pouziva aj vystup na RESET a tym padom po napaleni uz bez dalsich hraciek (12V prepisovanie poistky) nejde prehrat firmware. Nastastie sa to podarilo a tak som sa dal do stavby samotneho adapteru. To slo lahsie, ako by sa zdalo. Znicil som kvoli tomu USB kabel, nech nemusim letovat a bol to dobry napad - na prve zapojenie ho detekovalo Ubuntu! To bola super sprava - to znamena, ze som rovno mohol zacat skusat pripajat zariadenia.
Doma som nemal nic, len 23008 (8bit I/O) a vsetko ostatne len na 3.3V. Aby som hned nieco neznicil, tak som neriskoval a zobral tu 23008. Na moje testovacie pole sa to ledva zmestilo (testovacie diody uz nemam kam pripojit, tak sa s odpormi spajaju len tak - vo vzduchu). Kazdopadne som to pripojil a... No a teraz to bolo treba otestovat. Ubuntu sice zariadenie detekovalo, ale nevznikol ziadny zaznam v
/dev/i2c-*
, co znamena, ze pri pouziti i2cdetect z balika
i2c-tools
vypisal program len ze nenasiel zbernicu. Nakoniec to poriesila blbost:
modprobe i2c-dev
, cim vznikol zaznam v /dev strome a zrazu vsetko ficalo. Po spusteni
# i2cdetect -l
sa uz objavil adapter. Tak som skusil
i2cdetect -y 0
a ten nasiel zariadenie na adrese 0x20. Tu som nastavil ja - 23008 ma 3 adresne bity a dovoli nastavit adresy od 0x20 po 0x27, podla toho, aka binarna hodnota je na ich pinoch. To okrem ineho znamena, ze mozem pripojit az 8 takychto zariadeni, co mi dava 64 I/O vystupov (!!!). No a kedze som uz vedel zariadenie a videl ho na zbernici, zacal som robit pokusy. V prvom rade je potrebne nastavit I/O porty na vystup, pricom 0 pre dany bit znamena vystup a 1 znamena vstup. A nastavuju sa registrom na adrese 0x00. Takze prikaz znie
i2cset -y 0 0x20 0x00 0x00
, tym som nastavil vsetky bity na vystup.
A kedze na poslednom bite (7. bit, hexa-prepis 0x80) bola dioda a chcel som ju rozsvietit, pouzil som zapis na vystup (register 0x09). Prikaz teda vyzera takto:
i2cset -y 0 0x20 0x09 0x80
Prva 0 reprezentuje /dev/i2c-0, nasledne adresa 0x20 je zariadenie, ktore nasiel i2cdetect, 0x09 je vystupny register a 0x80 je samotna hodnota, ktora na 7. I/O vystup posle logicku 1. Analogicky prikaz
i2cset -y 0 0x20 0x09 0x00
diodu vypne. Tak som sa este pohral a nasiel som vsetky diody, co som mal po ruke (6 kusov). Vsetky som pripojil cez 100ohm rezistory na vystupy, konkretne su pouzite (0x80, 0x40, 0x20, 0x10, 0x02, 0x01). A spravil som si script, ktory ich rozsvecuje a zhasina - beziaci "svetelny" had. Tak a to znamena, ze teraz uz mam fungujuce i2c zariadenie a mozem skusit rozobrat router a vytiahnut z neho softwarovu i2c zbernicu :) Ale az zajtra, dnes sa mi uz nechce. A mam k dispozicii 8 vystupov pre spinanie cerpadlovych vystupov (cez rele) a samotne cerpadlo (relatko, ktore mu zopne 220V). Relatka uz mam davno hotove, su zapojene cez ten USB bit whacker zo Sparkfun-u. Ale prehodim ich - a odvtedy bude cela zahrada riadena routerom a nie Alixom, ktory je podstatne drahsi, samozrejme. Mam dobry pocit zo zivota :)