Cześć,
w dzisiejszej części przedstawię w jaki sposób komunikować się po UART z Arduino, oraz jak Arduino może komunikować się z komputerem. Gorąco zapraszam do przeczytania.
Spis treści:
- Co to UART ?
- Wysyłanie danych z Arduino do komputera
- Różnica pomiędzy char, a String
- Wysyłanie danych z komputera do Arduino przy użyciu char
- Wysyłanie danych z komputera do Arduino przy użyciu String
- Różnica pomiędzy Serial.print(), a Serial.write()
- Wykorzystywanie UARTu jako prostego debuggera
- Obsługa dwóch lub więcej interfejsów UART (tylko Ardunio MEGA 2560)
1.Co to UART ?
Zanim zaczniemy to najpierw dowiedzmy się co to takiego UART. UART, czyli Universal Asynchronous Receiver and Transmitter jest to interfejs do asynchronicznego odbierania i wysłania danych. Transmisja ta nie wymaga synchronizacji zegara nadajnika i odbiornika. Przy transmisji asynchronicznej musimy określić:
- szybkość transmisji (określona w baud)
- długość słowa (1B, 2B…)
- ilość bitów stopu
- bit parzystości (jest albo go nie ma)
W większości przypadków standardowe ustawienia UART dla AVR to 9600/8-N-1 co oznacza:
- 9600- prędkość transmisji
- 8- długość słowa w bitach (8b = 1B)
- N- brak bitu parzystości
- 1- bit stopu
Jak wygląda transmisja:
Aby zainicjować transmisję, musi wystąpić bić startu, wyzwalany logicznym „0”, następnie przesyłane są nasze informacje, fachowo nazywane słowem. Długość słowa możemy sami wybrać, w moim przypadku jest to słowo 8 bitowe. Gdy nasze słowo zostanie przesłane; ramka transmisji/danych zostanie zamknięta logiczną „1”. Aby przesłać kolejne dane to musi ponownie wystąpić bit startu i tak w kółko.
Do transmisji szeregowej UART potrzebujemy dwa piny odpowiedzialne za transmisję:
- TxD- wysyłanie danych
- RxD- odbiór danych
Aby wysłać, bądź odebrać jakieś dane z komputera to musimy połączyć się portem COM…. ale mamy XXI i większość nowoczesnych komputerów, głównie laptopów nie posiada już tego portu. O ile w komputerach stacjonarnych znajdziemy jeszcze port COM wbudowany w płytę główną, bądź jako gniazdo do podłączenia śledzia COM na płycie głównej, to w laptopach już go nie uświadczymy. Aby przeskoczyć ten problem to musimy wykorzystać emulator portu COM na USB. W serwisach aukcyjnych znajduje się pod nazwą „przejściówka COM USB”, „konwerter COM USB”. Z własnego doświadczenia wiem, że będzie działać nawet „chiński” konwerter zakończony gniazdem D-SUB9 za parę złotych. Jednak wybrałbym emulator portu COM znajdujący się pod nazwą FT232RL firmy FTDI. Pozwala ona na szybką transmisję danych, z jak najmniejszym błędem, ponieważ te „chińskie” za parę złotych przy wyższej prędkości, potrafią już gubić dane.
W starszych modelach Arduino Uno, Duemilanove; FT232RL był właśnie wykorzystywany, m.in. jako programator. Teraz są to przeważnie mikrokontrolery AVR z obsługa USB.
Tyle słowem wstępu. Czas przejść do części zasadniczej kursu.
2. Wysyłanie danych z Arduino do komputera
Poniżej przedstawię najprostszy sposób wysyłania danych do komputera:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void setup() { Serial.begin(9600); //rozpocznij transmisję UART, o prędkości 9600 baud } void loop() { Serial.println("Hello World ! || feriar-lab.pl || Elektronika to nasza pasja"); //wyslij wiadomość zawartą w "" delay(500); //odczekaj 0.5 sekundy } |
Po wgraniu naszego programu, przechodzimy do monitora portu szeregowego, klikając lupę w prawym górnym rogu Arduino IDE. W nowo otwartym oknie, w dolnym prawym rogu ustawiamy prędkość na 9600, jak zdefiniowaliśmy w programie. Po zmianie prędkości, powinniśmy ujrzeć takie dane:
Teraz podnieśmy lekko poprzeczkę, tzn. podłączymy diody i przy włączeniu diody niech zostanie wysyłany komunikat o stanie diody:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
int ledR = 9; int ledG = 10; void setup() { pinMode(ledR, OUTPUT); pinMode(ledG, OUTPUT); Serial.begin(9600); } void loop() { digitalWrite(ledR, HIGH); Serial.println("zapalono czerwona diode"); delay (1000); digitalWrite(ledR, LOW); Serial.println("zgaszono czerwona diode"); delay (1000); digitalWrite(ledG, HIGH); Serial.println("zapalono zielona diode"); delay (1000); digitalWrite(ledG, LOW); Serial.println("zgaszono zielona diode"); delay (1000); } |
Jeżeli uważałeś na wcześniejszych częściach kursu to pewnie zauważyłeś, że jest to prosty kod, który zapala diody naprzemiennie, wysyłając informacje po UART o stanie diody, lecz w ten sposób program wysyła nam na „ślepo” predefiniowane informacje bez własnego przemyślenia. Zatem zróbmy tak, aby Arduino „rozszyfrowało” jaki stan podany jest na diody oraz wysłało go po UART.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
int ledR = 9; int ledG = 10; void setup() { pinMode(ledR, OUTPUT); pinMode(ledG, OUTPUT); Serial.begin(9600); } void loop() { digitalWrite(ledR, HIGH); Serial.print("Czerwona dioda: "); Serial.println(digitalRead(ledR)); delay (1000); digitalWrite(ledR, LOW); Serial.print("Czerwona dioda: "); Serial.println(digitalRead(ledR)); delay (1000); digitalWrite(ledG, HIGH); Serial.print("Zielona dioda: "); Serial.println(digitalRead(ledG)); delay (1000); digitalWrite(ledG, LOW); Serial.print("Zielona dioda: "); Serial.println(digitalRead(ledG)); delay (1000); } |
Jak widać, w powyższym programie rozbiliśmy linię Serial.println() z wcześniejszego przykładu na dwie linie.
Pierwsza linia:
1 |
Serial.print("Czerwona dioda: "); |
Podaje na UART tekst, dzięki któremu łatwiej będzie nam zlokalizować daną diodę.
Druga linia:
1 |
Serial.println(digitalRead(ledR)); |
Wysyła wartość funkcji digitalRead(), która odczytuje w tym przypadku, stan diody czerwonej. Pewnie zauważyłeś, że użyłem dwóch funkcji Serial.print() i Serial.println(), ale czym one się różnią ? Obie pełnią tą samą funkcję, tzn. wysyłają dane, lecz Serial.println() informuje monitor portu szeregowego, że następne dane mają być wpisane do nowej linii, w przeciwnym wypadku dane będą wszystkie w jednej linii.
W taki sposób wysyłane są dane do komputera. Teraz przejdziemy do wysyłania danych z komputera do Arduino, ale zanim to zrobimy to chciałbym przedstawić różnice w transmisji jednego znaku, a ciągu znaków.