SerialLink#
Введение#
SerialLink позволяет двум модулям EXP Brain обмениваться данными, отправляя и принимая необработанные последовательные данные по каналу VEX Link. Вместо сообщений с метками SerialLink передает буфер (строку или массив байтов). Это делает его полезным для сложных задач связи между роботами, таких как потоковая передача данных с датчиков, отправка пользовательских форматов пакетов или создание собственного протокола на основе байтов.
Каждое использование send добавляет данные в буфер приема связанного EXP Brain. Данные считываются в порядке их поступления (первым пришел — первым вышел). Если несколько буферов отправлены до того, как другой EXP Brain использует receive, они остаются в очереди и возвращаются по одному в порядке их отправки. Поскольку данные могут стоять в очереди, многократная отправка больших буферов в каждом цикле может создавать задержку; для критически важных по времени каналов связи отправляйте только то, что вам нужно.
Важно: Оба робота должны одновременно выполнять проекты, использующие интерфейс SerialLink SerialLink , иначе данные не будут передаваться/получаться.
На этой странице в качестве примера используется имя SerialLink SerialLink link . При необходимости замените его на собственное имя.
Ниже приведён список доступных методов:
is_linked– Возвращает значение, указывающее, активно ли данный мозг связан с парным мозгом.send– Отправляет короткое сообщение (с необязательными данными типа int/float) в сопряженный Brain.receive– Ожидает и возвращает следующее входящее сообщение.received– Регистрирует функцию, которая будет вызываться при получении нового сообщения.
Создать ссылку#
Создайте интерфейс SerialLink на обоих блоках управления EXP, чтобы установить канал связи между ними — либо беспроводным способом с помощью радиомодулей V5 Robot Radios, либо через проводной интеллектуальный кабель — чтобы роботы могли обмениваться необработанными последовательными данными.
SerialLink(smartport, name, linktype, wired)
Параметр |
Описание |
|---|---|
|
Для этой связи используется «умный порт» — порт, к которому подключено радиоустройство робота V5 (беспроводное соединение) или в который вставлен «умный кабель» (проводное соединение). Записывается как |
|
Уникальное имя для этой ссылки в виде строки. |
|
Роль, которую этот «мозг» будет использовать для этой пары связей. Каждая пара должна включать одного менеджера и одного работника:
|
|
Необязательно. Тип соединения: проводное или беспроводное:
|
Код для робота 1
""" Create a wireless link in Port 1 name: VEXRoboticsLink123456789 linktype: Manager """ link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER)Код для робота 2
""" Create a wireless link in Port 1 name: VEXRoboticsLink123456789 linktype: Worker """ link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER)
Доступные методы#
После настройки SerialLink и подключения модулей Brain вы можете использовать описанные ниже методы для отправки, получения и обработки необработанных последовательных данных.
is_linked#
Метод is_linked возвращает значение, указывающее, сопряжены ли модули EXP Brains на последовательном интерфейсе друг с другом.
True– Два мозга EXP объединены в пару и обмениваются данными по этой связи.False– Два мозга EXP не связаны между собой по этой ссылке.
Примечание: Рекомендуется всегда проверять правильность подключения модулей EXP Brains в начале проекта, прежде чем запускать какой-либо дальнейший код.
Usage:
link.is_linked()
Параметры |
Описание |
|---|---|
Этот метод не имеет параметров. |
Код для робота 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")Код для робота 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 , передавая необработанные байты по последовательному порту другому подключенному EXP Brain.
При чтении этих данных с помощью receive, receive вернет управление только после того, как соберет количество байтов, указанное параметром length Поэтому, если ваш код всегда вызывает receive с фиксированной length, вы должны убедиться, что каждое сообщение, отправленное с помощью send содержит ровно столько байтов (часто путем заполнения), чтобы получатель не блокировался в ожидании дополнительных байтов.
Если вы не хотите зависеть от точного подсчета байтов, используйте received; это позволяет обрабатывать любые доступные байты без необходимости указания конкретной длины.
Usage:
send(buffer)
Параметры |
Описание |
|---|---|
|
The data to send to the other linked EXP Brain. This can be a |
Код для робота 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")Код для робота 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 возвращает последовательные данные от другого связанного модуля EXP Brain в порядке FIFO (самые старые непрочитанные данные первыми).
Поскольку receive ожидает точного количества байтов, сообщения фиксированной длины часто требуют заполнения при использовании send , чтобы каждое сообщение достигало ожидаемого размера. Если отправитель передает меньше length байтов, receive продолжит ожидать оставшиеся байты и ничего не вернет.
Если очередь пуста и вы задаете таймаут timeout, receive ожидает новых данных в течение указанного количества миллисекунд. Если в течение этого времени ничего не поступает, функция возвращает NoneЛюбые данные, отправленные после этого, остаются в очереди для последующего чтения.
Usage:
receive(length, timeout)
Параметры |
Описание |
|---|---|
|
Количество байтов для получения. |
|
Необязательный параметр. Время ожидания в миллисекундах |
Код для робота 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)Код для робота 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 регистрирует функцию, которая будет вызываться всякий раз, когда EXP Brain получает последовательные данные.
Usage:
link.received(callback)
Параметры |
Описание |
|---|---|
|
Ранее определенная функция, которая выполняется, когда EXP Brain получает последовательные данные. |
Получено received обратный вызов с двумя аргументами:
Сигнатура функции обратного вызова:
callback(buffer, length)
Аргумент |
Описание |
|---|---|
|
A |
|
Количество действительных байтов, полученных в буфере |
Код для робота 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")Код для робота 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)