Łącze szeregowe#
Wstęp#
SerialLink umożliwia komunikację dwóch mózgów EXP poprzez wysyłanie i odbieranie surowych danych szeregowych przez łącze VEX. Zamiast komunikatów z etykietami, SerialLink przesyła bufor (ciąg znaków lub tablicę bajtów). Dzięki temu jest przydatny w zaawansowanej komunikacji między robotami, takiej jak strumieniowe przesyłanie danych z czujników, wysyłanie niestandardowych formatów pakietów lub tworzenie własnego protokołu na podstawie bajtów.
Każde użycie polecenia send dodaje dane do bufora odbiorczego połączonego modułu EXP Brain. Dane są odczytywane w kolejności ich nadejścia (pierwszy na wejściu, pierwszy na wyjściu). Jeśli wiele buforów zostanie wysłanych przed użyciem polecenia receive przez drugi moduł EXP Brain, pozostaną one w kolejce i będą zwracane pojedynczo w kolejności, w jakiej zostały wysłane. Ponieważ dane mogą być kolejkowane, wielokrotne wysyłanie dużych buforów w każdej pętli może powodować opóźnienia. W przypadku łączy o krytycznym znaczeniu czasowym wysyłaj tylko potrzebne dane.
Ważne: Oba roboty muszą jednocześnie realizować projekty wykorzystujące SerialLink , w przeciwnym razie żadne dane nie zostaną wysłane ani odebrane.
Ta strona używa przykładowej nazwy łącza link SerialLink W razie potrzeby zastąp ją własną, skonfigurowaną nazwą.
Poniżej znajduje się lista dostępnych metod:
is_linked– Zwraca informację, czy ten Mózg jest aktywnie połączony ze sparowanym Mózgiem.send– Wysyła krótką wiadomość (z opcjonalnymi danymi int/float) do sparowanego Mózgu.receive– czeka na następną przychodzącą wiadomość i ją zwraca.otrzymano
received– Rejestruje funkcję, która ma zostać wywołana po otrzymaniu nowej wiadomości.
Utwórz link#
Utwórz łącze szeregowe na obu mózgach EXP, aby ustanowić między nimi kanał komunikacyjny — bezprzewodowo za pomocą radioodbiorników V5 Robot Radios lub za pomocą przewodowego inteligentnego kabla — dzięki czemu roboty będą mogły przesyłać sobie nawzajem surowe dane szeregowe.
SerialLink(smartport, name, linktype, wired)
Parametr |
Opis |
|---|---|
|
Port Smart używany do tego połączenia – port, do którego podłączone jest radio robota V5 (bezprzewodowo) lub kabel Smart Cable (przewodowo). Zapisujemy to jako |
|
Unikalna nazwa, jaką należy podać temu linkowi w postaci ciągu znaków. |
|
Rola, jaką ten Mózg będzie pełnił dla tej pary łączy. Każda para musi zawierać jednego Menedżera i jednego Pracownika:
|
|
Opcjonalnie. Czy to połączenie jest przewodowe, czy bezprzewodowe:
|
Kod dla Robota 1
""" Create a wireless link in Port 1 name: VEXRoboticsLink123456789 linktype: Manager """ link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER)Kod dla Robota 2
""" Create a wireless link in Port 1 name: VEXRoboticsLink123456789 linktype: Worker """ link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER)
Dostępne metody#
Po skonfigurowaniu SerialLink i połączeniu Brains możesz używać poniższych metod do wysyłania, odbierania i odpowiadania na surowe dane szeregowe.
is_linked#
Metoda is_linked zwraca informację, czy mózgi EXP na SerialLinku są ze sobą sparowane.
True– Dwa mózgi EXP są sparowane i komunikują się poprzez to łącze.False– Dwa mózgi EXP nie są sparowane w tym łączu.
Uwaga: Dobrą praktyką jest zawsze sprawdzenie, czy EXP Brains są połączone na początku projektu, zanim uruchomisz dalszy kod.
Usage:
link.is_linked()
Parametry |
Opis |
|---|---|
Ta metoda nie ma żadnych parametrów. |
Kod dla Robota 1
# Send a message to the other robot # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") link.send("HELLO")Kod dla Robota 2
# Display the message that Robot 1 sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() def received_message(bytearray, length): # Slice the bytearray to the valid data data = bytearray[:length] # Decode and strip the message before displaying it text = data.decode().strip() brain.screen.print("Got: ", text) # Call received_message whenever a message is received link.received(received_message)
send#
send przesyła surowe bajty szeregowe do drugiego połączonego mózgu EXP.
Podczas odczytu tych danych za pomocą receive, receive zwróci dane dopiero po zebraniu liczby bajtów określonej przez parametr length . Z tego powodu, jeśli Twój kod zawsze wywołuje receive ze stałą length, powinieneś upewnić się, że każda wiadomość wysłana za pomocą send ma dokładnie taką liczbę bajtów (często poprzez uzupełnienie), aby odbiorca nie blokował się w oczekiwaniu na dodatkowe bajty.
Jeśli nie chcesz polegać na dokładnej liczbie bajtów, użyj zamiast tego received; pozwala to na obsługę dowolnych dostępnych bajtów bez wymagania określonej długości.
Usage:
send(buffer)
Parametry |
Opis |
|---|---|
|
Dane do wysłania do drugiego połączonego mózgu EXP. Może to być ciąg |
Kod dla Robota 1
# Send a message to the other robot # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") link.send("HELLO")Kod dla Robota 2
# Display the message that Robot 1 sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() def received_message(bytearray, length): # Slice the bytearray to the valid data data = bytearray[:length] # Decode and strip the message before displaying it text = data.decode().strip() brain.screen.print("Got: ", text) # Call received_message whenever a message is received link.received(received_message)
receive#
receive zwraca dane szeregowe z drugiego połączonego modułu EXP Brain w kolejności FIFO (najstarsze nieprzeczytane dane na początku).
Ponieważ receive oczekuje na dokładną liczbę bajtów, komunikaty o stałej długości często wymagają uzupełnienia przy użyciu receive , aby każdy komunikat osiągnął oczekiwany rozmiar. Jeśli nadawca prześle mniej niż send , length będzie kontynuować oczekiwanie na pozostałe bajty i nic nie zwróci.
Jeśli kolejka jest pusta i podasz limit czasu timeout, receive czeka do podanej liczby milisekund na nowe dane. Jeśli nic nie pojawi się w tym oknie, zwróci NoneWszelkie dane wysłane później pozostają w kolejce do późniejszego odczytu.
Usage:
receive(length, timeout)
Parametry |
Opis |
|---|---|
|
Liczba bajtów do odebrania. |
|
Optional. How long in milliseconds |
Kod dla Robota 1
# Send a math problem for the other Brain to solve # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") """ Change whether to "add" or "subtract", then what numbers to use in the operation. """ packet = "add,7,2.5" # Pad with spaces until it's exactly 16 bytes while len(packet) < 16: packet = packet + " " link.send(packet)Kod dla Robota 2
# Solve the math problem that the other Brain sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() # Receive exactly 16 bytes buffer = link.receive(16) # Remove the added " " padding text = buffer.decode().strip() # Separate the operator and numbers parts = text.split(",") operator = parts[0] a = float(parts[1]) b = float(parts[2]) # Use what operator was sent if operator == "add": result = a + b elif operator == "subtract": result = a - b # If not "add" or "subtract", do nothing else: pass brain.screen.print("Result = ", result)
received#
received rejestruje funkcję, która ma zostać wywołana za każdym razem, gdy EXP Brain otrzyma dane szeregowe.
Usage:
link.received(callback)
Parametry |
Opis |
|---|---|
|
Wcześniej zdefiniowana funkcja, która jest wykonywana, gdy EXP Brain odbiera dane szeregowe. |
Otrzymano received są wywoływane z dwoma argumentami:
Sygnatura wywołania zwrotnego:
callback(buffer, length)
Argument |
Opis |
|---|---|
|
Tablica bajtów |
|
Liczba prawidłowych bajtów odebranych w buforze |
Kod dla Robota 1
# Send a message to the other robot # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") link.send("HELLO")Kod dla Robota 2
# Display the message that Robot 1 sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() def received_message(bytearray, length): # Slice the bytearray to the valid data data = bytearray[:length] # Decode and strip the message before displaying it text = data.decode().strip() brain.screen.print("Got: ", text) # Call received_message whenever a message is received link.received(received_message)