OSCUP представляет собой протокол UART, предназначенный для работы с процессорами ARM и ESP32. Хорошо документированный код помогает выяснить, как реализовать пользовательский протокол на UART. При этом с помощью данного протокола вы можете передавать и получать данные, которые отслеживаются фиксированной преамбулой. Он реализует ACK и NACK для каждого отправленного пакета с целью управления ошибками или потерянными пакетами.
OSCUP (https://github.com/ProjectoOfficial/Oscup) полагается на примитивные библиотеки, предоставленные Espressiff, такие как /device/uart.h для взаимодействия с аппаратными возможностями и функциями низкого уровня. Протокол предоставляет две функции записи и чтения (write и read) для отправки и получения данных. Когда вы создаете новый объект OSCUP, вам нужно получить ID, который отслеживает устройство, которое отправило пакет. Опционально объект OSCUP может быть реализован, указав порт UART и соответствующие линии UART TX и UART RX. По умолчанию связь осуществляется по UART 0 или USB-порту. В результате можно использовать Oscup для связи между компьютером и ESP32, или между двумя ESP32.
Каждый раз, когда протокол пишет данные в UART, он вставляет команду внутри пакета. Команда обязательна, в противном случае вы можете использовать протокол Arduino Serial. Очевидно, что в приемнике вы должны различать команды, которые вы получаете. Есть 4 основных команды:
- SHARE: Эта команда указывает, что отправитель просто хочет поделиться этими данными с приемником (по незначительным причинам). Вы можете использовать его, если вы просто хотите вывести данные на другом устройстве.
- CONFIRM: эта команда указывает, что данные, которые будут отправлены, являются следствием действия (например, мы нажали кнопку на устройстве 1, мы отправляем данные на устройство 2, и мы хотим, чтобы это устройство 2 не только вывело эти данные, но и сохранило их).
- ACK: Используется, чтобы сообщить отправителю, что приемник получил пакет.
- NACK: Используется, чтобы сообщить отправителю, что приемник не получил пакет. Отправитель попытается отправить его снова, очевидно, вы можете настроить действие, которое вы предпочитаете предпринять при каждой команде.
OSCUP использует следующие функции:
- begin: инициализирует параметры UART и пересылает их в аппаратную часть для управления. Обязательно используйте это во внутренней настройке Void(). Требуется указать скорость передачи в бодах как единственные входные параметры, которые будут определять связь.
- write: функция записи принимает команду «определенной пользователем», длина полезной нагрузки и эффективной полезной нагрузки, которая имеет фиксированную длину 40 байтов. Эта функция записывает эти данные в UART и возвращает код ошибки.
- read: она считывает входящие данные и вставляет их в структуру Packet_T, определенную в файле in.h.
- get_timer: возвращает значение счетчика таймера.
- get_apb_clk: возвращает частоту APB. Обычно APB используется для установки частоты периферийных данных.
В качестве примера реализуем с помощью OSCUP пользовательский протокол UART между двумя ESP32. Подключите две платы ESP32 согласно следующей схеме:
Далее приведены три блока кода: для записи, чтения и код на Python для чтения.
#include <stdlib.h>
#include "Oscup.h"
uint8_t id = 0x5D;
Oscup oscup = Oscup(id);
void setup() {
oscup.begin(115200);
}
void loop() {
uint64_t tim = oscup.get_APB_clk();
char *arr2 = uint64_toBytes(tim);
uint8_t error = oscup.write((uint8_t)TxCommands::SHARE, sizeof(uint64_t), arr2);
free(arr2);
delay(2000);
}
char *uint64_toBytes(uint64_t number) {
size_t dim = sizeof(uint64_t);
char *buff = (char *)calloc(dim, sizeof(char));
for (int i = 0 ; i < dim; i++) {
buff[i] = (number >> (8 * i)) & 0xFF;
}
return buff;
}
#include <stdlib.h>
#include "Oscup.h"
uint8_t id = 0x5D;
packet_t packet;
uint8_t errore = 255;
Oscup oscup = Oscup(id);
void setup() {
oscup.begin(115200);
}
void loop() {
errore = oscup.read(&packet);
delay(3000);
}
from pyOscup import Oscup
from pyOscup import ErrorCodes
from struct import unpack
id = 0x1C
baudrate = 115200
port = "COM3"
oscup = Oscup(id, baudrate, port)
while True:
error, packet = oscup.read()
if error:
if error != ErrorCodes.NO_DATA:
print("Error: {}".format(error))
else:
id, command, length, payload, crc = packet.getParams()
print("id: {} - command: {} - length: {}".format(hex(id), command, length))
print("payload: {}".format(payload))
print("long long value: {}".format(unpack('Q', bytearray(payload[:8]))))
print("crc: {}".format(crc))
print("\n\n")
© digitrode.ru