|

Komunikacja USART (Serial Port)

USART (Universal Synchronous / Asynchronous Receiver-Transmitter) to sprzętowy moduł, który umożliwia komunikację szeregową między płytką Arduino, a innymi urządzeniami (np. komputer, moduły czujników, Bluetooth, inne mikrokontrolery) za pomocą pinów Rx i Tx.

UART realizuje transmisję i odbiór danych w sposób asynchroniczny, co oznacza, że nie wymaga dodatkowego sygnału zegarowego do synchronizacji.

Arduino posiada wbudowany moduł CP2102 (lub CH340 w przypadku chińskich zamienników) do komunikacji seryjnej z komputerem za pomocą kabla USB.

TTL (Transistor-Transistor Logic) to standard logicznego poziomu napięcia używany w wielu urządzeniach elektronicznych. W arduino korzysta się często z poziomu napięć 3.3V i 5V.

Transmisja może nastąpić tylko wtedy, kiedy obydwa urządzenia dzielą te same ustawienia:

  • Szybkość transmisji (baud rate – częstotliwość pulsów zegara / ilość bitów na sekundę)
  • Format ramki danych
  • Warunek rozpoczęcia / zakończenia transmisji (start/stop)

 

Wysyłanie danych

Dane można wysyłać za pomocą metody print lub write:

print / println wysyła dane skonwertowane na znaki (ASCII)

Serial.print(12);
Serial.println("Hej");

Funkcja println wyświetla argumenty i dodaje znak przejścia do nowej linii (‘\r\n’)

Serial.print("Hej");
Serial.print('\r');
Serial.print('\n');

write wysyła dane w postaci bajta danych (liczby)

Serial.write(65);

Pobieranie danych

Wysyłanie danych do komputera powoduje ich wyświetlenie w Serial.Monitorze. W przypadku wysyłania danych między płytkami lub z komputera do płytki, należy te dane odebrać i przetworzyć.

Serial.available

Dane wysyłane do portu szeregowego są przechowywane w 64 bajtowym buforze. Pobierając dane, warto sprawdzić czy są one dostępne. Można to zrobić za pomocą metody Serial.available(), która zwraca ilość bajtów(znaków) do odczytania z Serial port (wraz z Enterem).

if (Serial.available() > 0) { }

Program odczyta dane z bufora w określonym domyślnie czasie (1s).

Czas oczekiwania można zmienić za pomocą metody:

Serial.setTimeout(1000); // czas w ms

Dane z portu Serial można pobierać za pomocą kilku dostępnych metod:

Serial.read()

Serial.read() zwraca wartości numeryczne znaków lub znak ASCII w zależności od typu danych

byte recData = Serial.read(); // zwraca wartość liczbową znaku ASCII
char recChar = Serial.read(); // zwraca znak ASCII

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    char a = Serial.read();
    if (a == '1') {
      digitalWrite(13, 1);
    } else if (a == '0') {
      digitalWrite(13, 0);
    }
  }
}

Serial.readString()

Serial.readString() zwraca wartość typu string

String recData = Serial.readString(); 

Serial.readStringUntil()

Serial.readStringUntil() zwraca wartość typu string bez znaku Enter

String recData = Serial.readStringUntil('\n'); 

Serial.readBytes()

Serial.readBytes() zwraca liczbę otrzymanych bajtów (bytesLength), które można przypisać do tablicy o określonej długości (BUF_SIZE)

const int BUF_SIZE = 50;
char bytesReceived[BUF_SIZE];

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

void loop() {
  if (Serial.available()) {
    int bytesLength = Serial.readBytes(bytesReceived, BUF_SIZE);
    Serial.print("Liczba bajtów: ");
    Serial.println(bytesLength);
    Serial.print("Otrzymane bajty: ");
    for(int i = 0; i < bytesLength; i++)
      Serial.print(bytesReceived[i]);
  }
}

Serial.parseInt()

Serial.parseInt() parseInt zwraca z bufora pierwszą napotkaną wartość liczbową (lub 0 w przypadku przekroczenia czasu)

paresInt przyjmuje argumenty: SKIP_NONE, SKIP_ALL, SKIP_WHITESPACE
Serial.parseInt(SKIP_ALL, ’,’);

if(Serial.available()){
  int a = Serial.parseInt();
  Serial.print(a);
}

Serial.parseFloat()

Serial.parseFloat() zwraca kolejną liczbę rzeczywistą (lub 0 w przypadku przekroczenia czasu)

if(Serial.available()){
  float b = Serial.parseFloat();
  Serial.print(b);
}

serialEvent() to metoda/event, który wywoła się za każdym razem, kiedy w buforze danych pojawi się informacja do pobrania. Ważne by pobrać dane z bufora, a tym samym go wyzerować, aby event nie wykonywał się ciągle.

void serialEvent(){
  if(Serial.available()){
    Serial.println(Serial.read());
  }
}

Line ending

Wysyłane dane mają swój początek i koniec. Istnieją specjalne znaki, które to określają.

Carriage Return  '\r’

New line '\n'(w systemie windows \n zawiera obydwa znaki: \r\n)

W zależności od projektu i sposobu komunikacji, należy tę opcję odpowiednio dostosować.

Pobieranie i wyświetlanie danych z użyciem serialEvent

String inputString = "";    
bool stringComplete = false;

void setup() {
  Serial.begin(9600);
  inputString.reserve(200);
}

void loop() {
  if (stringComplete) {
    Serial.println(inputString);
    inputString = "";
    stringComplete = false;
  }
}

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

Zobacz: Komunikacja Serial z modułem USB UART TTL

Zobacz: Komunikacja I2C w Arduino

Zobacz: Komunikacja SPI w Arduino

Zobacz: Komunikacja radiowa SPI NRF24L01 z Arduino

Podobne wpisy

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *