Prosty szeregowy protokół komunikacyjny punkt-punkt

Potrzebuję prostego protokołu komunikacyjnego pomiędzy dwoma urządzeniami (PC i mikrokontroler). Komputer musi wysłać kilka poleceń i parametrów do mikro. Mikro musi przesłać tablicę bajtów (dane z czujnika).

Dane muszą być zabezpieczone przed hałasem (poza sprawdzaniem parzystości, myślę, że potrzebuję innej metody korekcji danych).

Czy jest na to jakieś standardowe rozwiązanie? (Potrzebuję tylko pomysłu, a nie kompletnego rozwiązania).

P. S. każda rada jest mile widziana. P. P. S przepraszam za błędy gramatyczne, mam nadzieję, że rozumiesz.

Edycja 1. nie zdecydowałem, czy będzie master / slave protokół lub obie strony mogą zainicjować komunikację. Komputer musi wiedzieć, kiedy micro wykonało zadanie i może wysyłać dane. Może w sposób ciągły sondować mikro, jeśli dane są gotowe, lub mikro może wysyłać dane, gdy zadanie jest wykonane. Nie wiem, co jest lepsze i prostsze.

Edycja 2. sprzęt i warstwa fizyczna protokół. od RS-232C Standard szeregowy używany w PC, będę używać asynchronicznej komunikacji. Będę używał tylko sygnałów RxD, TXD i GND. Nie mogę użyć dodatkowych przewodów, ponieważ mikrokontroler AFAIK ich nie obsługuje. BTW używam układu AVR ATmega128.

Więc użyję stałej szybkości transmisji, 8 bitów danych, 2 bitów stopu bez sprawdzania parzystości(lub z?).

łącze danych Protokół. O to chodziło przede wszystkim moje pytanie. Thanks for suggesting HDLC, protokoły PPP i Modbus. Zbadam to.

Author: Vanuan, 2009-05-03

12 answers

Użyłbym HDLC . Miałem z tym szczęście w przeszłości. Chciałbym dla punktu do punktu serial po prostu użyć asynchroniczne kadrowanie i zapomnieć o wszystkich innych rzeczy sterowania, ponieważ prawdopodobnie byłoby przesadą.

Oprócz użycia HDLC do ramkowania pakietu. Formatuję mój pakiet w następujący sposób. W ten sposób opcje są przekazywane za pomocą 802.11

U8 cmd;
U8 len;
u8 payload[len];

Całkowity rozmiar każdego pakietu poleceń to len +2

Następnie definiujesz polecenia takie jak

#define TRIGGER_SENSOR 0x01
#define SENSOR_RESPONSE 0x02

Inną zaletą jest to, że możesz dodawać nowe polecenia i jeśli poprawnie zaprojektujesz swój parser tak, aby ignorował niezdefiniowane polecenia, będziesz mieć trochę wstecznej kompatybilności.

Więc złożenie tego wszystkiego razem pakiet będzie wyglądał następująco.

 // total packet length minus flags len+4
 U8 sflag;   //0x7e start of packet end of packet flag from HDLC
 U8 cmd;     //tells the other side what to do.
 U8 len;     // payload length
 U8 payload[len];  // could be zero len
 U16 crc;
 U8 eflag;   //end of frame flag

System będzie następnie monitorował strumień szeregowy dla flagi 0x7e i kiedy tam jest, sprawdzasz długość, aby sprawdzić, czy jest pklen > = 4 i pklen=len+4 i czy crc jest poprawne. Uwaga nie polegaj tylko na crc dla małe pakiety otrzymasz wiele fałszywych alarmów również sprawdzić długość. Jeśli długość lub crc nie pasuje po prostu zresetuj długość i crc i zacznij od dekodowania nowej ramki. Jeśli jest to dopasowanie, skopiuj pakiet do nowego bufora i przekaż go do funkcji przetwarzania poleceń. Zawsze Resetuj długość i crc po otrzymaniu flagi.

Dla funkcji przetwarzania poleceń chwyć cmd i len, a następnie użyj przełącznika do obsługi każdego typu poleceń. Wymagam również, aby pewne zdarzenia wysłały odpowiedź więc system zachowuje się jak zdalne wywołanie procedury, które jest sterowane zdarzeniami.

Więc na przykład urządzenie czujnika może mieć timer lub reagować na polecenie, aby wykonać odczyt. Następnie sformatuje pakiet i wyśle go do komputera, a komputer odpowie, że otrzymał pakiet. Jeśli nie, urządzenie czujnika może zostać ponownie wysłane z limitem czasu.

Również podczas wykonywania transferu sieciowego powinieneś zaprojektować go jako stos sieciowy, taki jak OSI modle jako Foredecker punkty nie zapominaj o warstwie fizycznej . Mój post z HDLC to warstwa łącza danych i RPC i obsługa poleceń to warstwa aplikacji .

 34
Author: Rex Logan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:05

Protokoły RS232 są trudne. Sugestia użycia HDLC jest dobra, ale nie całe rozwiązanie. Są inne rzeczy, o których musisz zdecydować:

  • Jak zostanie określona szybkość transmisji między tymi dwoma urządzeniami? Autobuad? Predefiniowane, czy ustawione?
  • Czy będziesz sterował przepływem w oprogramowaniu, sprzęcie czy obu? Uwaga, jeśli używasz sprzętowej kontroli przepływu, to musisz upewnić się, że kable są prawidłowo zbudowane. A propos kabli, to jest ogromny ból z RS233. W zależności od urządzenia może być konieczne użycie kabla przelotowego, kabla krzyżowego lub wariantu.
  • Korzystanie z mechanizmu sterowania przepływem opartego na oprogramowaniu może być skuteczne, ponieważ pozwala na użycie najprostszego kabla-tylko trzech przewodowych (TX, RX i common).
  • czy wybierasz 7 lub 8 bitowe słowo?
  • parzystość sprzętowa lub Sprawdzanie błędów oprogramowania.

Proponuję wybrać 8 bitów danych, bez parzystości sprzętowej, 1 bit stopu i użyć przepływu opartego na oprogramowaniu Kontrola. Powinieneś używać autobaud, jeśli twój sprzęt go obsługuje. Jeśli nie, to autobaud jest diabelsko trudny do zrobienia w oprogramowaniu.

 10
Author: Foredecker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-03 19:08:46

Jest tu kilka dobrych odpowiedzi, oto kilka przydatnych wskazówek:

Nawet jeśli pakiety nie są rozdzielone w czasie, bajt synchronizacji jest niezbędnym sposobem na zmniejszenie liczby miejsc, z których należy próbować zbudować pakiet. Twoje urządzenia często będą musiały radzić sobie z wieloma śmieciowymi danymi (np. końcem pakietu w locie po włączeniu lub wynikiem kolizji sprzętowej). Bez bajtu synchronizacji będziesz musiał spróbować utworzyć pakiet z każdego otrzymanego bajtu. The sync bajt oznacza, że tylko 1/255 bajtów losowego szumu może być pierwszym bajtem pakietu. Również fantastyczne, gdy chcesz węszyć na protokole.

Posiadanie adresu na swoich pakietach lub nawet odrobiny powiedzenia master / slave lub pc / device jest przydatne, gdy patrzysz na pakiety za pomocą snoop tool jakiegoś typu lub innego. Można to zrobić, mając inny bajt synchronizacji dla komputera niż urządzenie. Oznacza to również, że urządzenie nie zareaguje na własne echo.

Ty może warto zajrzeć do korekcji błędów (np. Hamming). Pakiet 8 bitów danych do 12-bitowego zabezpieczonego bajtu. Każdy z tych 12 bitów może zostać przerzucony na trasie, a oryginalne 8 bitów odzyskane. Przydatne do przechowywania danych (używane na płytach CD) lub tam, gdzie urządzenie nie może łatwo ponownie wysłać (łącza satelitarne, jednokierunkowe rf).

Numery pakietów ułatwiają życie. Przesyłany pakiet zawiera numer, odpowiedzi mają ten sam numer i flagę z napisem "response". Oznacza to, że pakiety, które nigdy arrived (Sync corrupted say) są łatwo wykrywane przez nadawcę, a w trybie full-duplex z powolnym łączem można wysłać dwa polecenia przed otrzymaniem pierwszej odpowiedzi. Ułatwia to również analizę protokołu (osoba trzecia może zrozumieć, które pakiety zostały odebrane bez wiedzy o protokole bazowym)

Posiadanie jednego mistrza to niesamowite uproszczenie. To powiedziawszy, w środowisku full-duplex nie ma to większego znaczenia. Wystarczy powiedzieć, że zawsze powinieneś to robić, chyba że próbujesz oszczędzać energię lub robisz coś wywołanego zdarzeniami na końcu urządzenia (stan wejściowy zmieniony, próbka gotowa).

 8
Author: Tom Leys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:05

Moja propozycja to modbus. Jest to wydajny i łatwy standardowy protokół komunikacji z urządzeniami posiadającymi Czujniki i parametry (np. PLC). Specyfikacje można uzyskać pod adresem http://www.modbus.org . istnieje od 1979 roku i zyskuje na popularności, nie będziesz miał problemu ze znalezieniem przykładów i bibliotek.

 5
Author: Martin Liesén,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-04 21:51:06

Czytałem to pytanie kilka miesięcy temu, mając dokładnie ten sam problem, i tak naprawdę nie znalazłem nic wystarczająco wydajnego dla małego 8-bitowego mikro z niewielką ilością pamięci RAM. Zainspirowany CAN I linem, zbudowałem coś, co zrobi to zadanie. Nazwałem go MIN (Microcontroller Interconnect Network) i wgrałem go na GitHub tutaj:

Https://github.com/min-protocol/min

Istnieją dwie implementacje: jedna w embedded C, druga w Pythonie dla PC. Plus małe " cześć świat " program testowy, w którym komputer wysyła polecenia, a oprogramowanie układowe zapala diodę LED. Pisałem na blogu o uruchomieniu tego na tablicy Arduino tutaj:

Https://kentindell.wordpress.com/2015/02/18/micrcontroller-interconnect-network-min-version-1-0/

MIN jest dość proste. Poprawiłem reprezentację warstwy 0 (8 bitów danych, 1 bit stopu, bez parzystości), ale pozostawiłem szybkość transmisji otwartą. Każda ramka zaczyna się od trzech bajtów 0xaa co w binarnym to 1010101010, fajny pulsetrain do zrobienia wykrywanie szybkości autobaud, jeśli jeden koniec chce dynamicznie dostosowywać się do drugiego. Ramki to 0-15 bajtów ładunku, z 16-bitową sumą kontrolną Fletchera, a także bajtem kontrolnym i 8-bitowym identyfikatorem (informującym aplikację o tym, co zawiera dane ładunku).

Protokół używa wypychania znaków tak, że 0xAA 0xaa 0xaa zawsze wskazuje początek ramki. Oznacza to, że jeśli urządzenie wyjdzie z resetu, zawsze synchronizuje się z początkiem następnej klatki (celem projektowym dla MIN nigdy nie było przepuszczenie niekompletna lub nieprawidłowa ramka). Oznacza to również, że nie ma potrzeby stosowania specyficznych ograniczeń czasowych między bajtami i między klatkami. Pełne informacje o protokole znajdują się w GitHub repo wiki.

Jest miejsce na przyszłe ulepszenia z MIN. Zostawiłem tam kilka hooków do przekazywania komunikatów blokowych (zarezerwowane są 4 bity bajtu sterującego) i do negocjacji wyższego poziomu możliwości (zarezerwowany jest identyfikator 0xFF), więc jest mnóstwo możliwości dodania wsparcia dla powszechnie wymaganych funkcjonalność.

 5
Author: Ken Tindell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-18 16:51:00

Oto alternatywny protokół:

u8  Sync          // A constant value which always marks the start of a packet
u16 Length        // Number of bytes in payload
u8  Data[Length]  // The payload
u16 Crc           // CRC

Użyj RS232 / UART, ponieważ komputer (port szeregowy) i procesor (UART) mogą sobie z tym poradzić z minimalnym kłopotem (wystarczy chip MAX232 lub podobny do zmiany poziomu).

I używając RS232 / UART, nie musisz się martwić o master / slave, jeśli to nie ma znaczenia. W razie potrzeby dostępna jest kontrola przepływu.

Sugerowane Oprogramowanie PC: napisz własne, lub Docklight do prostego monitorowania i kontroli (wersja ewaluacyjna jest bezpłatna).

Dla większego sprawdzania błędów, najprostszym jest sprawdzanie parzystości, lub jeśli potrzebujesz czegoś bardziej wydajnego, może kodowanie konwolucyjne .

W każdym razie, cokolwiek robisz: trzymaj to prosto!

EDIT: Korzystanie z RS232 z komputerem jest jeszcze łatwiejsze niż kiedyś, ponieważ możesz teraz uzyskać konwertery USB na RS232/TTL. Jeden koniec wchodzi do gniazda USB komputera i pojawia się jako normalny port szeregowy; drugi wychodzi na 5 V lub 3,3 V sygnały, które mogą być podłączone bezpośrednio do procesora, bez konieczności zmiany poziomu.

Użyliśmy TTL-232R-3v3 z układu FDTI, który doskonale sprawdza się w tego typu aplikacjach.

 3
Author: Steve Melnikoff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-14 17:03:40

Moja jedyna sugestia jest taka, że jeśli potrzebujesz ochrony przed hałasem, możesz użyć full-duplex RS-422/485. Możesz użyć układu scalonego podobnego do tego Po stronie AVR, a następnie konwertera RS-232->RS-422 po stronie PC, takiego jak 485ptbr tutaj. Jeśli znajdziesz lub wykonasz ekranowany kabel (dwie skręcone ekranowane pary), będziesz miał jeszcze większą ochronę. A wszystko to jest niewidoczne dla mikro i PC-bez zmian oprogramowania.

Cokolwiek robisz upewnij się, że używasz full-duplex system i upewnij się, że linie read/write enable są zapewnione na IC.

 2
Author: Stephen Friederichs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-06 02:35:12

Możesz rzucić okiem na Telemetry i związane z nim implementacje desktopowe w Pythonie Pytelemetry

Główne cechy

Jest to protokół oparty na PubSub , ale w przeciwieństwie do MQTT jest to protokół point-to-point, nie jest brokerem .

Jak każdy protokół pubsub, możesz publikować z jednego końca na topic i być powiadamianym na drugim końcu w tym temacie.

Po stronie osadzonej publikowanie tematu jest tak proste, jak :

publish("someTopic","someMessage")

Dla liczb:

publish_f32("foo",1.23e-4)
publish_u32("bar",56789)

Ten sposób wysyłania zmiennych może wydawać się ograniczony, ale następnym krokiem milowym jest dodanie dodatkowego znaczenia do parsowania tematu, robiąc takie rzeczy:

// Add an indexing meaning to the topic
publish("foo:1",45) // foo with index = 1
publish("foo:2",56) // foo with index = 2

// Add a grouping meaning to the topic
publish("bar/foo",67) // foo is under group 'bar'

// Combine
publish("bar/foo:45",54)

Jest to dobre, jeśli trzeba wysłać tablice, złożone struktury danych, itp.

Również wzór PubSub jest świetny ze względu na swoją elastyczność. Możesz budować aplikacje master / slave, urządzenia do urządzenia itp.

Biblioteka C Wersja GitHub

C Biblioteka jest bardzo prosta do dodania na każdym nowym urządzeniu, o ile masz na niej przyzwoitą bibliotekę UART.

Wystarczy utworzyć instancję struktury danych o nazwie TM_transport (zdefiniowanej przez Telemetry) i przypisać 4 Wskaźniki funkcjiread readable write writeable.

// your device's uart library function signatures (usually you already have them)
int32_t read(void * buf, uint32_t sizeToRead);
int32_t readable();
int32_t write(void * buf, uint32_t sizeToWrite);
int32_t writeable();

Aby użyć telemetrii, wystarczy dodać następujący kod

// At the beginning of main function, this is the ONLY code you have to add to support a new device with telemetry
TM_transport transport;
transport.read = read;
transport.write = write;
transport.readable = readable;
transport.writeable = writeable;

// Init telemetry with the transport structure
init_telemetry(&transport);  

// and you're good to start publishing
publish_i32("foobar",...

Biblioteka Pythona Wersja PyPI

Po stronie pulpitu znajduje się moduł pytelemetry, który implementuje protokół.

Jeśli znam Pythona, poniższy kod łączy się z portem szeregowym, publikuje raz na temat foo, wypisuje wszystkie odebrane tematy w ciągu 3 sekund, a następnie kończy się.

import runner
import pytelemetry.pytelemetry as tm
import pytelemetry.transports.serialtransport as transports
import time

transport = transports.SerialTransport()
telemetry = tm.pytelemetry(transport)
app = runner.Runner(transport,telemetry)

def printer(topic, data):
    print(topic," : ", data)

options = dict()
options['port'] = "COM20"
options['baudrate'] = 9600

app.connect(options)

telemetry.subscribe(None, printer)
telemetry.publish('bar',1354,'int32')
time.sleep(3)

app.terminate()

Jeśli nie znasz Pythona, możesz użyć interfejsu wiersza poleceń

Pytelemetry CLI Wersja PyPI

Wiersz poleceń można uruchomić za pomocą

pytlm

Wtedy możesz connect, ls(lista) odebrane Tematy, print dane otrzymane w temacie, pub (opublikuj) w temacie, lub otwórz plot w temacie do wyświetlanie odebranych danych w czasie rzeczywistym

Tutaj wpisz opis obrazka

Tutaj wpisz opis obrazka

 2
Author: Overdrivr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 08:07:26

Odnośnie sprawdzania parzystości (jak już tu kilka razy padło):

Są w większości bezużyteczne. Jeśli obawiasz się, że pojedynczy bit może zostać zmieniony w wyniku błędu, jest bardzo prawdopodobne, że drugi bit może również ulec zmianie i otrzymasz fałszywy wynik dodatni z kontroli parzystości.

Użyj czegoś lekkiego, takiego jak CRC16 z tabelą Wyszukiwania - można ją obliczyć, ponieważ każdy bajt jest odbierany i jest w zasadzie tylko XOR. Sugestia Steve ' a Melnikoffa jest świetna dla małych mikrosów.

I would sugeruj również przesyłanie danych czytelnych dla człowieka, a nie surowych danych binarnych (jeśli wydajność nie jest twoim priorytetem). Sprawi to, że debugowanie i pliki dziennika będą o wiele przyjemniejsze.

 1
Author: Peter Gibson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-14 12:23:50

Nie podajesz dokładnie, jak zachowuje się mikrokontroler, ale czy wszystko przesyłane z mikro będzie bezpośrednią odpowiedzią na polecenie z komputera? Jeśli do to wydaje się, że możesz użyć jakiegoś protokołu master / slave (Zazwyczaj będzie to najprostsze rozwiązanie). Jeśli obie strony mogą zainicjować komunikację, potrzebujesz bardziej ogólnego protokołu warstwy łącza danych. HDLC{[2] } jest klasycznym protokołem do tego celu. Chociaż pełny protokół prawdopodobnie jest przesadą dla Twoich potrzeb, możesz na przykład użyj przynajmniej tego samego formatu ramki. Możesz również zajrzeć do PPP , aby zobaczyć, czy są jakieś przydatne części.

 0
Author: hlovdal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-02 22:59:40

Może to pytanie może być całkowicie głupie, ale czy ktoś rozważał użycie jednego z modemu X/Y/Z protokołów?

Główną zaletą korzystania z jednego z powyższych protokołów jest duża dostępność gotowych do użycia implementacji w różnych środowiskach programistycznych.

 0
Author: Chris Ciesielski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 13:25:48

SLIP i UDP. Poważnie.

Wszystkie komputery PC i podobne urządzenia mówią tym.

Jest dobra książka i przykłady z TCP Lean

Jeremy Bentham podstępnie ma PIC robiący pracy TCP / IP. AVR jest tak dobry jak zdjęcie, prawda ?

Zamiast tego polecam UDP, to całkiem proste.

 -1
Author: Tim Williscroft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-01 03:46:52