I2C Arduino - Master odosiela binárne dáta na slave

Page

Stránky / Zbernice / I2C /

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ý.

Schéma

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.

Ako ukladať údaje

V priloženom súbore sa nachádza vzorový príklad komunikácie, pri ktorej sa prenášajú binárne dáta. Samotné nastavovanie sa v ničom nelíši od predchádzajúceho príkladu. Podstatná zmena je len v tom, že prenášame viac údajov a že sa pri tom používajú štruktúry a pointre.
  • Štruktúra - Uložiť údaje do štruktúry namiesto niekoľkých premenných má pre nás nezanedbateľné výhody. Kód je totiž programovaný univerzálne tak, že nám stačí meniť iba definíciu samotnej štruktúry (pridaním alebo ubraním položiek) a zvyšok programu sa nijako nemení. V tom nám pomáhajú operátor sizeof a konverzia dát na pointer znakového typu.
  • Operátor sizeof - Pomocou neho sa vypočíta dĺžka ľubovoľného typu alebo premennej v pamäti. Výpočet sa uskutoční ešte počas kompilácie.
  • Pointer - V c++ užitočná vec, v iných jazykoch zatracovaná. Keď ale rozumiete tomu, ako pointre fungujú, niet sa čoho báť. Celý trik je len v tom, že aj premenná je uložená niekde v RAM. To miesto v RAM vieme nájsť a povedať, že pointer má smerovať na to isté miesto, ale už sa naň nemá pozerať vo formáte pôvodných údajov, ale v type daného pointra. Keďže vieme, že I2C bude prenášať údaje po znakoch, použijeme tiež pointer znakového typu a jednoducho pošleme znaky od miesta kam ukazuje pointer a pošleme ich toľko, koľko nám povedal operátor sizeof.

Master

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

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

Maximálna dĺžka odosielaných dát je 32 bajtov. To preto, lebo interný buffer knižnice je tak nastavený.



Download

01.09.2015


Menu