Cvičenie je zamerané na prácu s vývojovou doskou Arduino. Cvičenie je orientované na základné programovanie mikroprocesora. V rámci cvičenia budú demonštrované základné spôsoby obsluhy I2C zbernice a LCD displeja pripojeného na túto zbernicu. Tiež bude vysvetlená filozofia pulzne šírkovej modulácie PWM, jej využitia a implementácie na doske Arduino. Po osvojení si učiva, študent dokáže realizovať jednoduchú komunikáciu pro zbernici I2C, obslúžiť LCD displej a implementovať PWM moduláciu. Študent rozumie problematike generovania jednosmerného napätia za pomoci PWM a filtračného RC obvodu.
|
Odporúčaná literatúra a dôležité odkazy[1] KPI-FEI-TUKE: Arduino UNO [2] itnetwork.sk: 15. diel - Arduino a I2C zbernice https://www.itnetwork.sk/hardver-pc/arduino/arduino-a-i2c-zbernice [3] Arduino.cc: Wire Library [4] arduino.cc: LiquidCrystal Library [5] Bakker, B.: How to control a character I2C LCD with Arduino [6] LastminuteEngineers: Interface an I2C LCD with Arduino |
I2C alebo tiež IIC zbernica je dvojlinková, teda obsahuje dva vodiče, obojsmerná zbernica vyvinutá firmou Philips začiatkom 90tych rokov. Jedná sa o pomerne pomalú zbernicu, ale jej rýchlosť je postačujúca práve pre IoT riešenia [2]. Veľmi výhodné je to, že zbernica umožňuje pripojiť až 127 zariadení na iba tieto dva vodiče. Tento typ komunikácie pracuje v režime jeden Master a mnoho poddaných (Slave). Každé zariadenie pripojené na túto zbernicu má vlastnú adresu. Táto adresa je 8 bitová. Ako už bolo uvedené, zbernica používa dva vodiče – Serial Data (SDA) a Serial Clock (SCL). SCL - určuje hodinový takt, t.j. rýchlosť prenosu dát a SDA slúži pre prenos samotných dát a celkovú komunikáciu. Master je zariadenie, ktoré inicializuje a ukončuje prenos dát na zbernici, generuje hodinový takt (SCL). Slave je zariadenie adresované Masterom. Pokiaľ na zbernici neprebieha žiadna komunikácia na oboch linkách je logická 1, teda +5V. Toto je zabezpečené pomocou interných pullup rezistorov mikroprocesora. Na tejto zbernici je prenos simplexný, teda v daný moment môže komunikovať len jedno zariadenie. Správu na linke môžu prečítať v princípe všetky zariadenia ale táto správa je adresovaná len jednému konkrétnemu zariadeniu. Detaily o tejto zbernici sa budete učiť vo vyššom ročníku. Na predmete Programovanie by sme ale mali mať aspoň trochu poňatia s čím pracujeme.
Pre komunikáciu cezI2C zbernicu je potrebné použiť knižničný súbor Wire.h [3]. Je potrebné si uvedomiť, že so zbernicou sa pracuje v režime prerušení, ktoré budeme preberať na nasledujúcej hodine. So zbernicou v drvivej väčšine prípadov budete pracovať tak, že Arduino bude Master a k nemu budete pripájať rôzne senzory a displeje.
Príklad: Na nasledujúcom príklade si ukážeme jednoduchú komunikáciu medzi dvoma Arduinami. Jedno bude Master, ktorý bude posielať príkazy druhému pracujúcemu v režime Slave. Príklad je jednoduchý, Slave bude rozsvecovať LED diódy na svojich 5 digitálnych portoch podľa toho, akú LED mu Master prikáže rozsvietiť. Ak bude komunikácia úspešná pošle sa Mastrovi správa o úspechu.
Master posiela údaj o porte a hodnote - pritom rozsvieti oranžovú diódu, ak Slave potvrdí prijatie a vykonanie príkazu, Master zopne aj zelenú LED. Poruchu na linke, resp. nepotvrdenie úspešného príjmu simuluje prepínač medzi portami A4. Zapojenie si vyhotovte buď v Tinkerkade alebo ak máte 2 Arduina ,tak môžete aj na nich. Nižšie je kód pre obidve zariadenia. Môžete experimentovať s ďalšími stavmi či zariadeniami.
// MASTER #include <Wire.h> #define ORANGE 9 #define GREEN 8 int stav = 1; int msg = 0; void setup() { pinMode(GREEN,OUTPUT); pinMode(ORANGE,OUTPUT); Wire.begin(); // Inicializácia I2C - Master nemusí mať adresu } void loop() { for(int pin = 3; pin<8; pin++) { Wire.beginTransmission(55); // Začiatok komunikácie Slave je na adrese 55 digitalWrite(ORANGE,HIGH); Wire.write(pin); // Zaslanie čísla pinu Wire.write(stav); // Zaslanie stavu pinu Wire.endTransmission(); // Koniec komunikácie Wire.requestFrom(55, 4); // Požiadavka na odpoveď msg = Wire.read(); // Prečítanie odpovede if(msg == 1) digitalWrite(GREEN,HIGH); else digitalWrite(GREEN,LOW); delay(1000); //Delay používame preto aby sme to stihli zbadať digitalWrite(GREEN LOW); digitalWrite(ORANGE,LOW); delay(1000); } stav = !stav; // Do ďalšej iterácie bude stav negovaný } |
// SLAVE #include <Wire.h> int Stav; int Port; bool OK=0; void setup() { for(int i = 3; i<8; i++) pinMode(i, OUTPUT); Wire.begin(55); // Inicializácia I2C - nech adresa zariadenia je 55 Wire.onRequest(requestEvent); // requestEvent-Funkcia, ktorá sa vykoná ako prerušenie keď // je Mastrom požadovaná odpoveď Wire.onReceive(receiveEvent); // receiveEvent-Funkcia, ktorá sa vykoná ako prerušenie // keď po zbernici niečo príde pre toto zariadenie } void loop() { if(Port>2 && Port<8 && (Stav == 1 || Stav == 0) ) { digitalWrite(Port, Stav); // V loope len zapisujeme stav na piny OK = 1; }else OK = 0; } void receiveEvent(int bytes) // Ak prišla správa adresovaná tomuto zariadeniu { Port = Wire.read(); // Prečíta sa jeden bajt Stav = Wire.read(); // Prečíta sa jeden bajt } void requestEvent() // Ak prišla požiadavka od Mastera { Wire.write(OK); // Zašle sa hodnota v OK 0 alebo 1 } |
Niekedy sa môže stať, že I2C modul LCD displeja má inú adresu ako 0x27. V takom prípade je možné túto adresu získať skenovaním pripojených zariadení na I2C zbernicu. Kód pre skenovanie a následné zobrazenie adresy I2C zariadenia je uvedený nižšie. Viac informácii získate na [6].
#include <Wire.h> void setup() { Serial.begin (9600); Serial.println (); Serial.println ("I2C scanner. Scanning ..."); byte count = 0; Wire.begin(); for (byte i = 8; i < 120; i++) { Wire.beginTransmission (i); if (Wire.endTransmission () == 0) { Serial.print ("Found address: "); Serial.print (i, DEC); Serial.print (" (0x"); Serial.print (i, HEX); Serial.println (")"); count++; delay (1); // maybe unneeded? } // end of good response } Serial.println ("Done."); Serial.print ("Found "); Serial.print (count, DEC); Serial.println (" device(s)."); } void loop() {} |