Page
V tomto článku sa pozrieme na odosielanie binárnych dát pomocou zbernice I2C medzi dvomi Arduinami. Tento príklad vám pomôže pochopiť, ako si organizovať údaje pomocou štruktúry a ako ich jedným príkazom prenášať. Takáto organizácia dát nie je náchylná na chyby v prípade, že sa binárne dáta nejako menia. Spôsob odosielania je vždy rovnaký.
Základom je zapojiť Arduina podľa nasledovného obrázku. Treba prepojiť na oboch Arduinach SDA na pine A4 a SLC na pine A5. Obe linky treba pomocou pull-up rezistora prepojiť na +5 V. Okrem toho sa prepojí napájanie a GND.
Keďže ale budeme predpokladať, že sa s tým budete hrať na počítači a oba Arduina máte napojené cez USB, nie je potrebné napájanie a GND spájať, pretože sú už takto prepojené krížom cez PC. Okrem toho ich v takomto prípade asi prepojíte cez USB šnúru, ktorú si kupujeme k Arduinu a teda oba Arduina budú blízko pri sebe.
Počas experimentov môžete vynechať aj oba pull-up rezistory, pretože knižnica, ktorú používame v Arduine používa interné pull-up rezistory v Arduine, ktoré na túto komunikáciu stačia. To ale používajte iba počas experimentov. V reálnom nasadení použite vždy externé pull-up rezistory s hodnotami 10k alebo 4k7.
Príklad prenášaných údajov. Na ukážku som zadefinoval aj prenositeľné typy, aj typy, ktoré môžu mať na rôznych platformách rôznu dĺžku v pamäti. V prípade dvoch Arduin nás to až tak nemusí trápiť, ale nikdy neviete, kedy je na druhej strane nejaké iné zariadenie, ktoré môže údaje interpretovať inak. Preto je bezpodmienečné nutné aby ste vedeli, ako v pamäti definujú daný typ obe strany prenosu.
struct transfer_data
{
int16_t x; // same on all platforms - 2b
int y; // platform dependent - Arduino 2b
float value; // 4b
};
Výňatok podstatných riadkov na pochopenie celého prenosu. Do pointra p, si uložíme počiatočnú adresu dát a celý prenos nám zabezpečí v jednom kroku funkcia Wire.write(p,sizeof(td));.
transfer_data td={10,20,1.2345};
uint8_t *p=(uint8_t*)&td;
Wire.write(p,sizeof(td)); // max 32b
Slave musí zadefinovať štruktúru na prenos údajov presne rovnako ako master. Vo funkcii receiveEvent dostaneme ako parameter počet znakov, ktoré sa ku nám prenášajú. My tie znaky musí len postupne prečítať a uložiť do pointra. Po prenose budeme mať v premennej td zrekonštruované dáta v pôvodnej podobe.
int how;
transfer_data td={0,0,0.};
// called by interrupt service routine when incoming data arrives
void receiveEvent (int howMany)
{
how=howMany;
uint8_t *p=(uint8_t*)&td;
for (int i = 0; i < howMany; i++)
{
b = Wire.read ();
*p=b;
p++;
} // end of for loop
signal=true;
} // end of receiveEvent
Maximálna dĺžka odosielaných dát je 32 bajtov. To preto, lebo interný buffer knižnice je tak nastavený.
01.09.2015