VIDI Project X #92:
Serijska komunikacija

Vidi X posjeduje tri najzastupljenije sabirnice (UART, SPI i I2C) kojima može direktno komunicirati sa senzorima, aktuatorima, računalom, ali i drugim mikro kontrolerima. U ovom tekstu bavit ćemo se komunikacijom s Arduinom, Micro:bitom te komunicirati s drugim Vidi X-om ili ESP32 mikro kontrolerom no, moguće je komunicirati i sa širokom paletom ostalih mikro kontrolera koju možete pronaći na tržištu.

Komunikacija s drugim mikrokontrolerima

Vidi X ima 3 hardverske UART (Universal asynchronous receiver-transmitter) serijske sabirnice. To su UART0UART1 i UART2 koji pružaju asinhronu komunikaciju (RS232 i RS485) te podršku za IrDA protokol. Komuniciraju brzinom do 5 Mbps.

UART je osnova svake serijske komunikacije bilo na razini računala, bilo na razini kontrolera. UART nam služi za pretvorbu paralelnih podatka (najčešće 8-bitnih) u serijski oblik sa svrhom smanjivanja potrebnog broja žica za komunikaciju. Serijski oblik spajanja podataka znači kako se podatak šalje jedan po jedan u nizu.

Za komunikaciju se koriste dva pina: Tx (predajni) i Rx (prijemni) pin. Na razini UART-a komunikacija je dvosmjerna (full duplex) što znači da su mogući istovremeni prijem i predaja podataka. Prijenos funkcionira tako da su RX i TX pin postavljeni u digitalni „Hi“ ili 1, tj. ima struje kada veza nije aktivna i kada se njome ne šalju nikakvi podaci.

 

 

Slanje podatka uvijek započinje START bitom koji je „Low“, tj. digitalna nula “0”. Nakon njega se odašilju bitovi podatka, najčešće njih 8 u 8-bitnoj komunikaciji. Ponekad se nakon bitova podatka šalje i paritetni bit pomoću kojeg se utvrđuje ispravnost prijema podatka, a slanje završava STOP bitom koji je uvijek “1”.

Tako veza zna da ju vraćamo u neaktivno stanje. Trajanje svakog bita definirano je brzinom komunikacije u broju bitova u sekundi i mora biti jednako podešeno na obje komunikacijske strane.

U prošlosti su se morala koristi dodatna dva pina koji su, u nedostatku jačih procesora i buffera, bili potrebni kako ne bi dolazilo do pucanja veze. Služili su za provjeru je li veza slobodna, tj. je li primatelj slobodan za prijem podataka.

Zovu se RTS (RequestToSend) i CTS (ClearToSend), a danas ih ne koristimo jer pojavom jačih procesora, serijska veza ima ugrađeni buffer za pohranu dolazećih podataka ako je procesor zauzet drugim zadacima.

 

U ranijim verzijama Arduino IDE trebalo je prvo definirati serijsko sučelje naredbom

HardwareSerial Serial1(2);

 

ali danas to više nije potrebno. Naiđete li na neke ranije pisane programe koji pokušavaju definirati drugu ili treću serijsku vezu, dobit ćete poruku o grešci. Stoga slobodno postavite komentar „//“ ispred takve naredbe.

 

// HardwareSerial Serial1(2);

 

Dovoljno je samo odrediti brzinu serijske komunikacije, a dodjeljujemo ih naredbom:

Serial.begin(115200);
Serial1.begin(115200);
Serial2.begin(115200);

 

Modifikacija pinova

Pri tome se Serial.begin(115200); veza nalazi na pinovima 1 za Tx i 3 za Rx te ju koristimo za upload softvera na Vidi X putem USB kabela. Dakle, želimo li komunicirati sa još jednim uređajem, bilo da je to drugi Vidi X ili Micro:BIT, morat ćemo koristi Serial1.begin(115200); vezu koja je predefinirana na pinove 9 i 10.

 

 

Ovaj uokvireni dio teksta ne vrijedi za Arduino IDE 1.8.13 i novije verzije jer je Arduino IDE promijenio lokaciju \hardware\ mape i načina na koji je ponaša prema ESP32 mikro kontrolerima.

 

No pokušate li tako definiranu vezu kompajlirati i uploadati na Vidi X, stvar će rezultirati beskonačnim resetom Vidi X-a. Kako se to ne bi dogodilo, potrebno je pronaći datoteku imena

HardwareSerial.cpp

koja se nalazi unutrar mape

C:\Users\Podrska\Documents\Arduino\hardware\espressif\esp32\cores\esp32

kod vas se ta putanja može razlikovati, a potrebno je zamijeniti definiciju pinova iz predefiniranog u novo stanje

#ifndef RX1 #ifndef RX1
#define RX1 10 #define RX1 4
#endif #endif
#ifndef TX1 #ifndef TX1
#define TX1 9 #define TX1 2
#endif #endif

 

Sada veza Serial1.begin(115200); koristi pin 4 za Rx i 2 za Tx te te je moguće putem pinova 2 i 4 komunicirati s drugim uređajima, a da stvar ne rezultira resetiranjem Vidi X-a. Isto tako ste mogli ovdje za serijsku komunikaciju definirati pinove poput 14, 15 ili 21, 22 odnosno druge koji se ne koriste za važnije stvari, tj. slobodni su jer ESP32 može gotovo sve pinove koristiti za serijsku komunikaciju. Samo je bitno definirati ih u ranije spomenutoj HardwareSerial.cpp datoteci.

Morate voditi računa da prilikom updatea ESP32 librarija ili drugih fajlova, unešene promjene mogu biti pregažene. Time se može dogoditi resetiranje vašeg Vidi X-a ponovno kada poželite koristiti Serial1 vezu.

Taj reset se događa jer se pinovi 9 i 10, koji su inicijalno postavljeni za drugu serijsku vezu, kod Vidi X-a koriste za interni SPI FLASH.

 

Korištenjem novije verzije Arduino IDE razvojnog okruženja korištenje serijske komunikacije definiramo ovako:

#define RXD2 4 // Postavljamo PIN na koji primamo serijsku komunikaciju
#define TXD2 2 // Postavljamo PIN na koji šaljemo serijsku komunikaciju

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, RXD2, TXD2);
}

void loop() {
  if (Serial.available()) {      // If anything comes in Serial (USB),
    Serial1.write(Serial.read());   // read it and send it out Serial1
  }

  if (Serial1.available()) {     // If anything comes in Serial1
    Serial.write(Serial1.read());   // read it and send it out Serial (USB)
  }
}

 

Sada veza Serial1.begin(115200); koristi pin 4 za Rx i 2 za Tx te te je moguće putem pinova 2 i 4 komunicirati s drugim uređajima, a da stvar ne rezultira resetiranjem Vidi X-a. Isto tako ste mogli ovdje za serijsku komunikaciju definirati pinove poput 14, 15 ili 21, 22 odnosno druge koji se ne koriste za važnije stvari, tj. slobodni su jer ESP32 može gotovo sve pinove koristiti za serijsku komunikaciju.

 

Spajanje dva VIDI X mikroračunala

Kako bi dva uređaja komunicirala, važno je znati da se Rx pin prvog uređaja spaja sa Tx pinom drugog uređaja, te se Tx pin prvog uređaja spaja sa Rx pinom drugog uređaja. Rekli bismo unakrsno.

Kako biste spojili pin 2 za Tx i pin 4 za Rx, treba pogledati raspored tih pinova na expander slotu. Interna numeracija tog expander slota označena je na pločici, pa možemo primijetiti označene krajnje pinove 1 i 2 te na drugom kraju 27 i 28 na samoj pločici.

Time vidimo da se na mjestu 8 i 10 nalaze naši pinovi 2 (GPIO2) te 4 (GPIO4) na koje moramo spojiti serijsku UART komunikaciju drugog uređaja.

 

(Paspored pinova otvorite u .pdf formatu na stranici Vidi X poster.)

 

Pri spajanju dva Vidi X-a trebate spojiti GPIO2 prvog sa GPIO4 drugog Vidi X-a te GPIO4 prvog sa GPIO2 drugog Vidi X-a. Uzemljenje ili GND pin jednog treba spojiti sa GND pinom drugog Vidi X-a.

Mikro prekidače iznad VIDI X expander slota treba postaviti u pravi položaj želite li koristiti GPIO2 i GPIO4 pinove. U ovom slučaju na S3 mikro prekidaču pod brojevima 3 i 5 moraju biti postavljeni prema dolje.

 

 

 

Micro:BIT komunikacija s Vidi X-om

Micro:BIT mikrokontroler također ima mogućnost UART serijske komunikacije. Minimalni primjer serijske komunikacije putem pina 0 i 1 izgleda ovako u JavaSciptu:

serial.redirect(
SerialPin.P0,
SerialPin.P1,
BaudRate.BaudRate115200
)
basic.forever(function () {
basic.showString(serial.readString())
})

 

Ili ovako u blokovskom prikazu.

 

Pri tome treba paziti na nekoliko ključnih stvari kako komunikacija ne bi krenula naopako.

Ranije smo napisali kako Rx i Tx pin u stanju kada se ne koriste imaju vrijednost „Hi“, tj. digitalni 1. Drugim riječima, kroz taj pin ide struja one voltaže na kojoj radi mikrokontroler. Kod Micro:BIT-a su to 3,3 V. Isto kao i kod Vidi X-astoga je moguće direktno komunicirati bez uništavanja nekog od tih uređaja.

 

 

Komunikacija s Arduinom

Kod Arduino mikrokontrolera nešto je dugačija situacija. Arduino većinom koristi 5 V na izlazima te će direktna komunikacija biti nemoguća jer bi 5 V izlaz sa Arduina mogao uništiti VIDI X. Zato nam je između njih potreban Logic Level Converter (LLC) koji pretvara 5 V u 3,3 V i obratno.

Logic Level Converter s jedne strane ima oznake HV1HV2 i tako redom što označava High voltage, tj. 5 V, a sa druge strane ima LV1LV2 i tako dalje što označava Low voltage tj. 3,3 V.

Dakle, na HV pinove LLC-a ćemo spojiti Arduino koji koristi 5 V na data pinovima dok ćemo na LV pinove LLC-a spojiti Vidi X koji koristi 3,3 V na data pinovima prema shemi:

Za demonstraciju komunikacije ovaj put nećemo korisiti minimalnu Arduino skicu komunikacije jer smatramo kako ste već shvatili kako slati i primati podatke iz ranije opisanih primjera koristeći dva Vidi X-a ili Vidi X i Micro:BIT.

Ovoga ćemo puta za Arduino skicu uzeti davno napisan kod za pokretanje autića iz časopica VIDI broj 257/258. Tekst je opisivao kako autić na daljinsko upravljanje uz pomoć Arduina možemo prepraviti kako bismo ga mogli kontrolirati smartfonom i BT vezom.

Skicu možete pronaći na našem GitHubu na adresi https://github.com/VidiLAB-com/Arduino/tree/master/Arduino_Autic, a teksta se možete prisjetiti surfajući Vidilab-portalom na adresi https://vidilab.com/vidi-project-x/arduino/4529-how-to-arduino-autic.

Cilj je ove demonstracije na postojeći projekt, bez imalo modifikacije Arduino koda, spojiti Vidi X mikroračunalo i njime upravljati Arduino autićem. Tako spojen Vidi X omogućit će upravljanje autićem putem Wi-Fi veze ili bilo koje druge metode dostupne na Vidi X mikroračunalu, poput recimo infracrvenim daljinskim upravljačem.

Proučite li Arduino kod, vidjet ćete da on koristi serijsku vezu sa HC-06 BT modulom te umjesto tog modula postavljamo Logic Level Converter kako bismo uz pomoć njega mogli ostvariti serijsku komunikaciju s Vidi X-om, a da ga pri tome ne oštetimo naponom od 5 V na data pinovima Arduina.

Minimalni kod koji treba uploadati na Vidi X, a sa svrhom isprobavanja funkcionalnosti je:

void setup() {
Serial.begin(115200);
Serial1.begin(9600);
}
void loop() {
Serial1.println(“f”);
}

 

Možete primijetiti kako smo brzinu serijske komunikacije spustili na cca 9 Kbita naredbom Serial1.begin(9600); kako bi brzina komunikacije bila prilagođena onoj koju Arduino može razumjeti. A s obzirom na to kako je Arduino slabiji te sporiji mikrokontroler, mora sporije primati podatke i putem serijske veze.

U naredbi Serial1.println(“f”); šaljemo ASCII znak „f“ kao sinonim za forward, a s obzirom na to kako u skici za Arduino imamo dio case uvjeta koji glasi:

case ‘F’: case ‘f’:
setMotorRear(speed, 0);

 

 

Taj će dio koda pri primitku ASCII znaka „f“ pozvati funkciju setMotorRear koja će autiću narediti kretanje naprijed.

Shema spajanja Arduina na LLC, a zatim na Vidi X izgleda ovako: