MENU

Jak działa UART? Komunikacja między płytkami.

UART Arduino i NodeMCU

UART Arduino i NodeMCU

Nie wszystko musi działać po Wi-Fi. Czasem wystarczy kilka przewodów, żeby mikrokontrolery dogadały się ze sobą bez zbędnych kombinacji. Żadnych bibliotek, żadnych cudów – klasyczna komunikacja UART robi robotę od lat i nadal ma się świetnie. Od debugowania po szybkie przesyłanie danych między płytkami – działa, bo jest prosta.

W tym artykule pokażę Ci, jak połączyć dwi płytki za pomocą UART-a. W moim przypadku jest są to Arduino UNO R4 WiFi i NodeMCU E12 1.0. Zrobimy transmisję dwukierunkową – czyli obie płytki będą mogły ze sobą rozmawiać, coś jak cyfrowe walkie-talkie. Potrzeba tylko trzech kabelków, krótkiego kodu i ustalenia wspólnej prędkości transmisji.

Czego potrzebujesz?

Arduino UNO R4 WiFi
Płytka od Arduino z nowszym mikrokontrolerem Renesas – posłuży jako jeden z uczestników rozmowy.

Arduino uno r4

NodeMCU E12 1.0
Klasyk na ESP8266 – będzie drugim rozmówcą w komunikacji UART.

NodeMCU

3 przewody połączeniowe (typ w zależności od płytki, jaką posiadasz)
Połączą TX, RX i GND między płytkami.

Co to jest UART?

UART, czyli Universal Asynchronous Receiver/Transmitter, to jeden z najprostszych sposobów, by dwa urządzenia elektroniczne zaczęły się ze sobąkomunikować. Jak sama nazwa wskazuje, mamy tu do czynienia z asynchronicznym nadawcą i odbiorcą. Co to znaczy? Że nie potrzebujemy żadnego dodatkowego zegara, jak w SPI czy I2C. Wystarczy, że obie strony dogadają się co do prędkości transmisji – tzw. baud rate – np. 9600 czy 115200 bodów na sekundę.

Dane przesyłane są tu bajtami, czyli po 8 bitów, a komunikacja opiera się na dwóch liniach:

TX (Transmit) – linia, którą mikrokontroler wysyła dane,
RX (Receive) – linia, którą dane są odbierane.

Jeśli więc łączysz dwa mikrokontrolery przez UART, to TX jednej płytki leci do RX drugiej – i odwrotnie. Plus wspólna masa (GND), bo bez niej żaden sygnał nie będzie miał punktu odniesienia.

Jak działa UART?

W UART wszystko działa asynchronicznie – czyli bez zegara. Zamiast tego każdy bajt startuje od bitu startu (poziom niski), potem leci osiem bitów danych, a na koniec bit stopu (poziom wysoki), który mówi odbiorcy: „to już koniec znaku”.

bity w uart

Dzięki temu odbiornik wie, gdzie zacząć i gdzie skończyć, mimo że nie ma wspólnego zegara. Ale jest haczyk – jeśli obie strony nie będą miały ustawionej dokładnie tej samej prędkości transmisji, to zamiast sensownych danych dostaniesz sieczkę. Dlatego zawsze upewnij się, że baud rate się zgadza.

Dlaczego UART, skoro mamy tyle nowoczesnych opcji?

Bo jest prosty, a to bardzo dobry powód. Nie potrzebujesz bibliotek, konfiguracji stosów ani żadnych egzotycznych protokołów. Wystarczą dwa przewody (plus masa), trochę kodu i już możesz przesyłać dane z jednego mikrokontrolera do drugiego.

Oczywiście, są również pewne wady. UART to komunikacja punkt–punkt, więc nie podłączysz kilku urządzeń na jednej magistrali. No i bez zegara jest trochę bardziej podatny na zakłócenia – zwłaszcza przy długich kablach i wysokich prędkościach.

Jak podłączyć układ?

Podłączenie UART między dwoma mikrokontrolerami jest banalne – wystarczy skrzyżować linie transmisji. RX (Receive) jednej płytki łączymy z TX (Transmit) drugiej, a TX pierwszej z RX drugiej. Tylko tyle i aż tyle – bez żadnych rezystorów, czy dodatkowych układów. Oczywiście nie zapominamy o wspólnej masie (GND), bo bez tego żadne dane nie popłyną.

W naszym przypadku podłączamy Arduino UNO R4 WiFi do NodeMCU E12 1.0, czyli:

podłączenie płytek
Arduino Uno R4 WiFiNode MCU
TXRX
RXTX
GNDGND
  • UNO R4 WiFi TX (pin 1)NodeMCU RX (D9)
  • UNO R4 WiFi RX (pin 0)NodeMCU TX (D10)
  • GND → GND

I to wszystko! Mamy solidne, dwukierunkowe połączenie gotowe do przesyłania danych.

Jak skomunikować mikrokontrolery – programowanie płytek.

Napiszmy prosty program, w którym „nadajnik” wyśle tajną wiadomość do „odbiornika”, a odbiornik następnie przekaże ją do portu szeregowego, żebyśmy mogli zobaczyć efekt na ekranie.

Zaczynamy od napisania kodu dla naszego nadajnika, którym jest NodeMCU. Tutaj sprawa jest naprawdę prosta – nie potrzebujemy żadnych dodatkowych bibliotek czy skomplikowanej konfiguracji. Wystarczy, że w funkcji setup() uruchomimy komunikację szeregową, co robimy za pomocą:

void setup() {
  Serial.begin(9600);
  delay(1000);
}

Ustawiamy prędkość transmisji na 9600 bodów – to wystarczające, aby wysyłać nasze dane bez opóźnień i błędów. Następnie dorzucamy sekundowy delay(1000);, żeby dać płytce chwilę na pełne uruchomienie. Dzięki temu unikamy sytuacji, w której komunikat leci, zanim port szeregowy zdąży się w pełni zainicjować.

Przechodzimy do funkcji loop(). To tutaj wysyłamy naszą „tajną wiadomość”. Kod wygląda następująco:

void loop() {
  Serial.println("Hej tu NodeMCU");

  delay(5000); 
}

To, co się dzieje, to prosta sekwencja. Co pięć sekund NodeMCU wysyła przez port szeregowy wiadomość Hej tu NodeMCU. Ten tekst, jest wysyłąny przez UART i czeka, aż zostanie odebrany przez jakieś urządzenie. W tym przypadku to Arduino Uno R4 WiFi stanie się odbiornikiem. Na razie z perspektywy NodeMCU nie interesuje nas, co się dalej z tą wiadomością dzieje.

Kod odbiornika

eraz zajmijmy się odbiornikiem, czyli naszym Arduino Uno R4 WiFi. Kod jest nieco bardziej rozbudowany, bo tutaj nie tylko odbieramy dane, ale też je wyświetlamy na monitorze szeregowym, żebyś mógł zobaczyć, co właściwie się dzieje.
Zaczynamy od funkcji setup():

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  delay(1000);
  Serial.println("Arduino Uno R4 WiFi - Gotowe do odbierania!");
}

Uruchamiamy tutaj dwa niezależne porty szeregowe:

  1. Serial.begin(9600); – klasyczna komunikacja przez USB, żebyśmy mogli widzieć w monitorze szeregowym, co Arduino odbiera.
  2. Serial1.begin(9600); – komunikacja przez UART z NodeMCU.

Oba mają ustawioną tę samą prędkość transmisji, czyli 9600 bodów, dzięki czemu unikamy błędów przy odbiorze danych. Na końcu wrzucamy sekundowy delay, żeby upewnić się, że wszystko jest gotowe, a potem wysyłamy informację na monitor szeregowy o gotowości Arduino do odebrania jej.

W pętli loop() nasłuchujemy, czy na porcie UART (Serial1) pojawiły się jakieś dane. Jeśli są tam jakieś bajty, Arduino odczytuje je do momentu napotkania znaku końca linii (\n). Stosujemy tutaj funkcję readStringUntil('\n');, która zbiera wszystkie znaki do momentu, gdy znajdzie taki właśnie znak. To wygodna metoda, bo nie musimy się martwić o to, czy odebraliśmy całą wiadomość – dzieje się to automatycznie.

void loop() {
  if (Serial1.available()) {
    String receivedMessage = Serial1.readStringUntil('\n');
    if (receivedMessage.length() > 0) {
      Serial.print("Odebrano od NodeMCU: ");
      Serial.println(receivedMessage);
    }
  }
}

Gdy odebrana wiadomość ma jakąś zawartość (czyli nie jest pusta), wyświetlamy ją na monitorze szeregowym. Dzięki temu, gdy tylko NodeMCU wyśle wiadomość, pojawia się ona natychmiast na monitorze szeregowym Arduino.

Efekt końcowy

W swoim porcie szeregowym powinieneś widzieć takie wiadomości:

komunikat w porcie szeregowym w arduino ide

I to wszystko! NodeMCU wysyła swoją „tajną wiadomość”, Arduino ją odbiera i wyświetla na ekranie. Prosto, czytelnie i bez zbędnych komplikacji.

Taka dwukierunkowa komunikacja UART między mikrokontrolerami otwiera sporo możliwości. Możesz zbudować prosty system monitoringu, gdzie czujniki podpięte do jednego mikrokontrolera wysyłają dane do drugiego, który zajmuje się ich przetwarzaniem.

Jeśli wolisz komunikację bezprzewodową, to zajrzyj na mój artykuł Jak połączyć się z BLE na LilyGo T-ZigBeePa – ESP32-C3?. Tam opisuję, jak ogarnąć temat przesyłania danych bez kabli i dodatkowych modułów.

Masz pomysł, jak jeszcze można wykorzystać komunikację UART? A może napotkałeś na problem podczas budowy swojego układu? Daj znać w komentarzu!

KUP ELEMENTY TEGO ZESTAWU

119
00
19
90

KOMENTARZE

guest
0 komentarzy
najstarszy
najnowszy oceniany
Inline Feedbacks
View all comments

SZUKASZ PODZESPOŁÓW
DO NASTĘPNEGO PROJEKTU?

Wszystko co potrzebne znajdziesz w naszym sklepie z obsługą na 5 gwiazdek!

elektroweb.pl