Istnieje wiele sposobów na napisanie protokołu szeregowego w zależności od potrzebnej funkcjonalności i wymaganej kontroli błędów.
Niektóre z typowych rzeczy, które widzisz w protokołach point-to-point:
Koniec wiadomości
Najprostsze protokoły ASCII mają po prostu koniec sekwencji znaków wiadomości, często \r
lub \n
jako to, co jest drukowane po naciśnięciu klawisza Enter. Mogą być używane protokoły binarne 0x03
lub inne wspólne bajty.
Początek wiadomości
Problem z samym końcem wiadomości polega na tym, że nie wiesz, jakie inne bajty zostały już odebrane podczas wysyłania wiadomości. Te bajty byłyby następnie poprzedzone komunikatem i spowodowałyby błędną interpretację. Na przykład, jeśli Arduino właśnie obudził się ze snu, może być trochę śmieci w buforze szeregowym. Aby obejść ten problem, musisz rozpocząć sekwencję wiadomości. W twoim przykładzie ^
często w protokołach binarnych0x02
Sprawdzanie błędów
Jeśli komunikat może zostać uszkodzony, potrzebujemy kontroli błędów. Może to być suma kontrolna, błąd CRC lub coś innego.
Escape Characters
Może się zdarzyć, że suma kontrolna doda znak kontrolny, taki jak bajt „początek komunikatu” lub „koniec komunikatu”, lub wiadomość zawiera wartość równą znakowi kontrolnemu. Rozwiązaniem jest wprowadzenie postaci ucieczki. Znak zmiany znaczenia jest umieszczany przed zmodyfikowanym znakiem kontrolnym, tak aby rzeczywisty znak kontrolny nie był obecny. Np. Jeśli znakiem początkowym jest 0x02, za pomocą znaku ucieczki 0x10 możemy wysłać wartość 0x02 w komunikacie jako parę bajtów 0x10 0x12 (bajtowy znak kontrolny XOR)
Numer pakietu
Jeśli wiadomość jest uszkodzona, możemy poprosić o ponowne wysłanie wiadomości typu nack lub spróbować ponownie, ale jeśli wysłano wiele wiadomości, tylko ostatnia wiadomość może zostać wysłana ponownie. Zamiast tego pakietowi można nadać liczbę, która przewija się po określonej liczbie wiadomości. Na przykład, jeśli liczba ta wynosi 16, urządzenie nadawcze może przechowywać ostatnie 16 wysłanych wiadomości, a jeśli jakieś są uszkodzone, urządzenie odbierające może zażądać ponownego wysłania przy użyciu numeru pakietu.
Długość
Często w protokołach binarnych widzisz bajt długości, który informuje urządzenie odbierające, ile znaków jest w wiadomości. Dodaje to kolejny poziom sprawdzania błędów, tak jakby nie odebrano prawidłowej liczby bajtów, a następnie wystąpił błąd.
Specyficzne dla Arduino
Podczas opracowywania protokołu dla Arduino należy przede wszystkim zastanowić się, jak niezawodny jest kanał komunikacyjny. Jeśli wysyłasz za pośrednictwem większości bezprzewodowych mediów, XBee, WiFi itp., Wbudowane jest już sprawdzanie błędów i ponawianie prób, a zatem nie ma sensu umieszczać ich w protokole. Jeśli wysyłasz przez RS422 na kilka kilometrów, będzie to konieczne. To, co chciałbym uwzględnić, to początek i koniec znaków wiadomości, tak jak Ty. Moja typowa implementacja wygląda mniej więcej tak:
>messageType,data1,data2,…,dataN\n
Ograniczenie części danych przecinkiem pozwala na łatwą analizę, a wiadomość jest wysyłana za pomocą ASCII. Protokoły ASCII są świetne, ponieważ można wpisywać wiadomości na monitorze szeregowym.
Jeśli potrzebujesz protokołu binarnego, być może w celu zmniejszenia rozmiarów wiadomości, będziesz musiał zaimplementować funkcję zmiany znaczenia, jeśli bajt danych może być taki sam jak bajt kontrolny. Binarne znaki sterujące są lepsze w systemach, w których pożądane jest pełne spektrum sprawdzania błędów i ponownych prób. W razie potrzeby ładunek może nadal być ASCII.