Serial/UART cz8

Pamiętasz, kiedy drukarki, myszy i modemy miały grube kable z tymi ogromnymi, niezgrabnymi złączami? Te urządzenia prawdopodobnie używały UART do komunikacji z twoim komputerem. Aktualnie USB prawie całkowicie zastąpił te stare kable i złącza. UART zdecydowanie nie należy do zabytku, jest szeroko rozpowszechnione w elektronice w zakresie wymiany niewielkich ilości informacji.

UART oznacza uniwersalny asynchroniczny odbiornik/nadajnik. Przesyła dane asynchronicznie, co oznacza, że ​​nie ma sygnału zegarowego do synchronizacji. Transmitujący UART dodaje bit startu i stopu do przesyłanego pakietu danych. Bity te definiują początek i koniec pakietu, dzięki czemu odbierający UART wie, kiedy rozpocząć i zakończyć odczytywanie bitów.

Gdy odbierający UART wykryje bit startu, zaczyna odczytywać przychodzące bity z określoną częstotliwością znaną jako szybkość transmisji. Szybkość transmisji to miara szybkości przesyłania danych wyrażona w bitach na sekundę (bps).  Oba urządzenia muszą działać z mniej więcej taką samą szybkością transmisji. Szybkość transmisji między nadającymi i odbierającymi UART może różnić się tylko o około 10%, zanim taktowanie bitów stanie się zbyt odległe.

Działanie UART opiera się o dwie linie:
  • TX - wysyłania danych,
  • RX - odbierania danych.

*Gdy komunikujemy się pomiędzy dwoma urządzeniami musimy pamiętać o wspólnym GND.

 
Komunikacja pomiędzy komputerem a mikrokontrolerem
Zadanie:

Zbuduj program, który będzie zapalał diodę led po wysłaniu komunikatu w monitorze portu szeregowego. Aby użyć komunikacji UART z USB używamy polecenia Serial.

Do zbudowania będziemy potrzebowali:
  • Diodę Led
  • Rezystor 56Ω
  • Arduino (użyłem MKR1010 wifi)
Schemat:

schemat

Kod programu:
#define LedPin 2 // Pin dla diody LED
int dane;  	 // zmienna przechowująca dane z portu szeregowego

void setup()
{
  Serial.begin(9600);       // ustawi szybkość transmisji na 9600
  pinMode(2, OUTPUT);       // ustaw Pin 13 na OUTPUT
  Serial.println("Wpisz:"); // wyświetl w monitorze portu szeregowego komendy
  Serial.println(" 1: LED - on"); 
  Serial.println(" 0: LED - off"); 
}

void loop()
{
  if (Serial.available() > 0) // jeśli jakieś dane dotarły
  { 
    dane = Serial.read(); // oczytaj przychodzące dane szeregowe i zapisz do zmiennej dane
    if (dane == '1') {    // jeśli dane jest równe 1
      digitalWrite(LedPin, HIGH); // ustawi LedPin na stan wysoki
      Serial.println("LED - On"); // wyślij komunikat na porcie szeregowym
    } 
    else if (dane == '0'){         // jeśli nie jest równe 1
      digitalWrite(LedPin, LOW);   // ustawi LedPin na stan niski
      Serial.println("LED - off"); // wyślij komunikat na porcie szeregowym
    }
  }
}
Wynik:

wynik

Poza otrzymanym komunikatem zwrotnym dioda się zapala lub gasi odpowiednio dla wysłanej komendy.

 
Komunikacja pomiędzy dwoma mikrokontrolerami
Zadanie

Zbuduj układ z dwoma płytkami. Jedna z nich ma nadawać sygnał po wciśnięciu przycisku a druga odbierała i odpowiednio do komunikatu włączała lub wyłączała diodę Led. Aby użyć komunikacji dwóch urządzeń za pomocą UART z TX, RX używamy polecenia Serial1. Należy również pamiętać o wspólnym GND.

Do zbudowania będziemy potrzebowali:
  • Diodę Led
  • Switch
  • Rezystor 56Ω
  • 2x Arduino (użyłem MKR1010 wifi)
Interaktywny schemat:
Arduino
Kod programu (Transmiter):
Transmiter:
#define Button 1 // Definicja pinu 1 jako Button
char dane = '1'; // Zmienna przechowująca dane do wysyłki przez UART
bool wcisniety = false; // Zmienna przechowująca informacje czy przycisk był wciśnięty 
                   
void setup() {
  pinMode(Button, INPUT_PULLUP); // Deklaracja Button jako WEJŚCIE 
  Serial1.begin(9600); // Ustawi szybkość transmisji na 9600 Serial1 - Arduino <-> Arduino
  Serial.begin(9600);  // Ustawi szybkość transmisji na 9600 Serial1 - Arduino <-> PC
}

void loop() {
  if(digitalRead(Button) == LOW ){ // Jeśli przycisk wciśnięty
    if(dane == '0' && wcisniety == false) { // Jeśli przycisk nie był wciśnięty i dane = 0
      dane = '1'; 
      Serial1.print(dane); // Wyślij komunikat na Serial1 do Arduino
      Serial.print(dane);  // Wyślij komunikat na Serial do PC
    } 
    else if(dane == '1' && wcisniety == false) 
{ // Jeśli przycisk nie był wciśnięty i dane = 1
      dane = '0';
      Serial1.print(dane); // Wyślij komunikat na Serial1 do Arduino
      Serial.print(dane); // Wyślij komunikat na Serial do PC
    } 
    delay(200);     // Odczekaj 200ms
    wcisniety = true; // Ustawienie zmiennej na przycisk wciśnięty
  }
  else{
    wcisniety = false; // Ustawienie zmiennej na przycisk nie wciśnięty
  }
}
Kod programu (Odbiornik):
#define Led 2    // Definicja pinu 2 jako Led
char dane = '0'; // Zmienna przechowująca dane przesłane przez UART

void setup() {
  pinMode(Led, OUTPUT);     // Deklaracja Led jako WYJŚCIE
  digitalWrite(Led, LOW);   // Wyłącz Led
  Serial1.begin(9600);      // Ustawi szybkość transmisji na 9600 Serial1 - Arduino <-> Arduino
  Serial.begin(9600);       // Ustawi szybkość transmisji na 9600 Serial1 - Arduino <-> PC
}

void loop() {
  if(Serial1.available()) { // Czy Arduino odebrało dane
    dane = Serial1.read(); // Odczyt z Serial1 do zmiennej dane
  
    if(dane == '1') { // Jeśli dane = 1
      digitalWrite(Led, HIGH);   // Włącz Led
    }
    if(dane == '0') { // Jeśli dane = 0
      digitalWrite(Led, LOW);   // Wyłącz Led
    }
    
    Serial.print(dane); // Wyślij komunikat do PC
  }
}

Wynik możemy zaobserwować również w monitorze portu szeregowego:

wynik

  • 1 – komunikat zapalania diody Led.
  • 0 – komunikat gaszenia diody Led.