Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

15. diel - Arduino a I2C zbernice

I²C je sériová zbernica, pôvodne od firmy Philips, používaná napr. Na základných doskách na pripojenie periférií, ktoré nevyžadujú vysokú rýchlosť prenosu dát. Občas sa môžete stretnúť aj s označením TWI, čo je prakticky to isté, len TWI používa Atmel (výrobca napr. Mikroprocesorov ATmega, pořivaných v Arduino) a ďalšie spoločnosti, pretože I²C je chránená značka.

A v čom je čaro tejto zbernice? Určite ste na doske zahliadli piny označené SCL a SDA. Ich skratky znamenajú Synchrous Clock a Synchronous Data. Takto môžeme pomocou dvoch (štyroch (+ napájanie)) vodičov pripojiť až 128 zariadení. Naša Arduino bude pracovať ako tzv. Master - zariadenie, ktoré je na zbernici iba jedno, ovláda komunikáciu a generuje hodinový signál na pinu SCL. Zvyšných 127 zariadenia sú tzv. Slave - tí sú riadení masterom a bez jeho pokynu nič neurobia.

Čo teda môžeme na zbernicu pripojiť? Skoro všetko! Napríklad LCD display, RTC modul (ten na čas), IO expander (pridá ďalšie digitálne piny), ďalšie Arduino a veľa ďalšieho.

Len pozor - piny SCA s SDL sú u Arduien UNO a NANO pripojené na analógové piny A5 a A4, teda je nemôžete používať súčasne so zbernicou.

Teória tiež tvrdí, že na SDA a SCL by ste mali odporom pripojiť VCC. Z vlastnej skúsenosti vám ale poviem, že na krátke vzdialenosti (zapájaní pár zariadení v breadbordu atď.) Tam vôbec nie sú potrebné, a keď vám na dlhších vzdialenostiach niečo nefunguje, tak až teraz je odpor potreba. Zbernica je určená pre krátke vzdialenosti, ale s odpormi nemám najmenší problém natiahnuť zbernicu cez 10m UTP káblu (a možno pôjde i viac) a na druhom konci vpohode funguje LCD is expandery.

I²C adresa

Každé zariadenie má svoju adresu. Dosť často na module nájdete 3 piny, označované ako A0, A1, A2. Privedením napätia na jednotlivé piny potom možno meniť adresu zariadenia. Napríklad tabuľka adries pre IO expandery PCF8574 použité v tomto tutoriálu bude vyzerať takto:

A0 A1 A2 Dec hex
L L L 32 20
H L L 33 21
L H L 34 22
H H L 35 23
L L H 36 24
H L H 37 25
L H H 38 26
H H H 39 27
L - Low, pin bez napätia; H - High, 5V na pinu

Adresu možno zapísať decimálne (32) alebo hexadecimálne (0x20). Rozdiel v tom podstate nie je žiadny, len občas sa niekde dočítate jeden zápis, druhýkrát iný. A ako zistiť adresu? Pri kúpe súčiastok z eBay sa mi dosť často stáva, že zariadenie má inú adresu, než uvádza predajca. Možno použiť I²C scanner zo stránok Arduino. Sketch nahrajte do dosky, otvorí Serial Monitor a Arduino vypíše všetky zariadenia na zbernici.

LCD display

Ak si kúpite LCD display, bude k vému pripájané doštička so 4 vývody - VCC, GND, SDA, SCL. Zapojenie všetkých týchto zariadení je jednoduché - VCC na 5V, GND na zem, SDA na SDA, SCL na SCL. Ešte budeme potrebovať knižnicu. Arduino IDE už v sebe má manažéra knižníc, teda rozkliknite Sketch -> Include Library -> Manage Libraries, vyhľadáme knižnicu LiquidCrystal_I2C a nainštalujeme ju.

z 6. dielu vieme, ako LCD funguje, a LCD cez I²C sa ovládaním nijak moc nelíši.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);

void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,1);
  lcd.print("ITnetwork.cz!");

}


void loop()
{
}

Zaujímavý je riadok LiquidCrystal_I2C lcd (0x27,20,4);. Tu vytvoríme objekt LCD, lenže ako parametre nie je použitý zoznam RS, E, Dx pinov, ale iba I²C adresa a počet znakov na riadok a riadkov. Teda display je pripojený na adrese 0x27, má 4 riadky a 20 znakov. Potom lcd inicializujeme (lcd.init ()) a keďže aj piny pre podsvietenie sú pripojené na I2C čip, musíme pomocou lcd.backligh () zapnúť podsvietenie. Funkcia print () a setCursor () už poznáme.

I²C IO expander

Došli vám piny a potrebujete ešte niečo pripojiť? Nevadí, stačí si kúpiť IO expander PCF8574. Na zbernicu ich môžeme pripojiť až 8, čo je 8 * 8 = 64 pinov (keďže skoro všetky sú vyrábané s rovnakou adresou, ak budete mať šťastie, môže sa vám podariť zohnať aj iné rozsahy). Na expander.Výhodou máme 8 digitálnych pinov, lenže práca s ním je trochu ťažšie na pochopenie, ale potom už to je jednoduché. Pre nasledujúce vysvetlenie predpokladám, že chápete princíp dvojkovej sústavy.

Ak expander chceme použiť ako výstupné piny, zapíšeme na neho hodnotu v rozmedzí 0-255. Ak ako výstupné, budeme hodnotu čítať. Teraz ovšem ako požadované signály na pinoch previesť na hodnoty a zase späť?

8 pinov na expander.Výhodou si označíme číslami 0-7, ako sou popísané na čipe. Tieto čísla pre nás budú mocniny dvojky (už chápete kam tým mierim?). Teda prvý pin (0) dostane číslo 1, druhý (1) dostane 2, tretí (2) dostane 4 a tak ďalej. Preto budeme mať niečo takéto:

pin 1 2 3 4 5 6 7 8
číslo pinu 0 1 2 3 4 5 6 7
mocnina dvojky 1 2 4 8 16 32 64 128
A dajme tomu, že budeme chcieť mať na pinoch číslo 0 a 5 napätia (logická 1) a na všetkých ostatných nie (logická 0). Teda toto:
pin 1 2 3 4 5 6 7 8
číslo pinu 0 1 2 3 4 5 6 7
mocnina dvojky 1 2 4 8 16 32 64 128
výstup 1 0 0 0 0 1 0 0
Tým nám vznikne číslo v dvojkovej sústave - 10000100. To už len prevedieme do desiatkovej sústavy a máte číslo, ktoré môžeme odoslať na expander - teda 132. Pre zápis na expander musíme mať naimportovaný knižnicu Wire.h a v setupu zavoláme Wire.begin () ;. Potom môžeme na expander posielať dáta:
Wire.beginTransmission(33);
Wire.write(132);
Wire.endTransmission();

V prvom riadku otvoríme spojenie k príslušnému expander.Výhodou na adrese 33 (tiež možno zapísať 0x21). V druhom riadku zapíšeme našu hodnotu 132. A v treťom sa vykoná samotné odoslanie na expander. Funkcia endTransmission () tiež vracia číslo podľa úspešnosti, ak sa dáta zapísať podarilo, vráti 0, ak zariadenie neexistuje, vráti 4. Len nečakajte, že na čipe bude výstup čistých 5V, napätie môže byť nižšia.

A teraz ak budeme potrebovať použitý piny ako vstupný. Princíp fungovania je úplne rovnaký. Zase jednotky a nuly na pinoch, zase číslo v desiatkovej sústave, lenže tentoraz číslo prečítame, a ako ho previesť späť na jednotky a nuly pre jednotlivé piny? Najprv si pomocou funkcie Wire.requestFrom () vyžiadame zariadenie na zbernici, ak je dostupné, prečítame z neho hodnotu pomocou Wire.read () a uložíme ju do premennej. Arduino má funkciu bitRead (), ktoré vstupné číslo v desiatkovej sústave prevedie na dvojkový zápis a ako druhý parameter vezme pozíciu čísla (tj. Mocninu dvojky) a vráti, či je tu 1 alebo 0. Ak túto funkciu zavoláme postupne so všetkými číslami od 0 do 7, vrátenú hodnotu prevedieme na string a pridáme do premennej, môžeme získať pôvodný reťazec, s ktorým sme pracovali na začiatku pri zapisovaní.

Wire.requestFrom(33, 1);
 if(Wire.available()) {
   byte readExpander =255- Wire.read();
   String readed;
   for(byte i = 0; i < 8; i++) {
     readed+= String(bitRead(readExpander,i));
   }

   if(String(readed[0])=="1") { pin1(); }
   else if(String(readed[1])=="1") { pin2(); }
   else if(String(readed[2])=="1") { pin3(); }
   else if(String(readed[3])=="1") { pin4(); }
   else if(String(readed[4])=="1") { pin5(); }
   else if(String(readed[5])=="1") { pin6(); }
   else if(String(readed[6])=="1") { pin7(); }
   else if(String(readed[7])=="1") { pin8(); }


 }

Samozrejme môžeme vynechať ukladanie do premennej readed aj slučku a v ifech používať priamo if (bitRead (readExpander, 0) == 1) {PIN1 (); }

V budúcom dieli sa pozrieme na komunikáciu medzi jednotlivými doskami Arduino.

V budúcej lekcii, Arduino a analógový pin , si povieme niečo o analógovom pinu a ako ho možno využiť na meranie elektrického odporu a napätia.


 

Predchádzajúci článok
Arduino - Komunikácia cez Bluetooth
Všetky články v sekcii
Arduino
Preskočiť článok
(neodporúčame)
Arduino a analógový pin
Článok pre vás napísal Adam Ježek
Avatar
Užívateľské hodnotenie:
2 hlasov
Autor se převážně věnuje Arduinu a psaní tutoriálů z této oblasti, občas napíše příležitostně nějakou tu zprávičku. Většinu svého volného času momentálně věnuje Linuxu a/nebo Raspberry Pi. Také umí C#, HTML, CSS, PHP a Python.
Aktivity