Перейти к содержанию
Материалы раздела

COBS

Модуль для кодирования и декодирования данных с использованием алгоритма COBS (Consistent Overhead Byte Stuffing). COBS используется для фреймирования бинарных данных при передаче по последовательным каналам связи, гарантируя отсутствие нулевых байтов в передаваемых данных.

cobs.encode(data [, mode])

Кодирует данные с использованием COBS.

Аргументы:

  • data: строка с бинарными данными для кодирования
  • mode (опционально): режим кодирования
    • nil или false - стандартный COBS
    • true или “tinyframe” - режим TinyFrame (payload до 254 байт)
    • “raw” или “standard” - стандартный COBS

Возвращает: закодированную строку

local cobs = require("cobs")

-- Стандартное кодирование
local encoded = cobs.encode("Hello\0World")

-- Кодирование в режиме TinyFrame
local encoded = cobs.encode("data", true)
local encoded = cobs.encode("data", "tinyframe")

cobs.decode(data [, mode])

Декодирует COBS-закодированные данные.

Аргументы:

  • data: закодированная строка
  • mode (опционально): режим декодирования (аналогично encode)

Возвращает: декодированную строку

Одноразовая функция принимает ровно один полный кадр: нулевой разделитель должен быть последним байтом data. Хвост после первого разделителя, в том числе второй склеенный кадр, считается ошибкой. Для потока из нескольких кадров используйте cobs.new() и buffer:feed().

local cobs = require("cobs")

local original = "Hello World"
local encoded = cobs.encode(original)
local decoded = cobs.decode(encoded)
print(decoded)  -- Hello World

cobs.encode_tinyframe(data)

Кодирует данные в режиме TinyFrame. Эквивалентно cobs.encode(data, true).

Аргументы:

  • data: строка для кодирования (максимум 254 байта)

Возвращает: закодированную строку

local encoded = cobs.encode_tinyframe("short data")

cobs.decode_tinyframe(data)

Декодирует данные из режима TinyFrame. Эквивалентно cobs.decode(data, true).

Аргументы:

  • data: закодированная строка (минимум 2 байта)

Возвращает: декодированную строку

local decoded = cobs.decode_tinyframe(encoded)

cobs.new(maxlen [, mode])

Создает буфер для потокового декодирования COBS-фреймов. Полезно при приеме данных по частям через UART или другой последовательный интерфейс.

Аргументы:

  • maxlen: максимальный размер буфера в байтах
  • mode (опционально): режим декодирования (см. encode)

Возвращает: объект буфера

local cobs = require("cobs")

-- Создание буфера на 256 байт
local buffer = cobs.new(256)

-- Создание буфера в режиме TinyFrame
local buffer = cobs.new(256, true)

buffer:feed(chunk)

Добавляет данные в буфер и возвращает все полностью принятые фреймы.

Аргументы:

  • chunk: строка с данными для добавления (может быть nil)

Возвращает: таблицу с декодированными фреймами (может быть пустой)

local cobs = require("cobs")
local buffer = cobs.new(256)

-- Симуляция приема данных по частям
local frames = buffer:feed(chunk1)
for _, frame in ipairs(frames) do
    print("Received frame: " .. frame)
end

local frames = buffer:feed(chunk2)
-- ...

buffer:reset()

Сбрасывает буфер, очищая все накопленные данные.

buffer:reset()

buffer:pending()

Возвращает количество байтов, ожидающих обработки в буфере.

Возвращает: число байтов

local pending = buffer:pending()
print("Pending bytes: " .. pending)

Пример: прием данных через UART

local cobs = require("cobs")
local uart = require("uart")

-- Создаем буфер для приема
local buffer = cobs.new(512)

-- Настраиваем UART
uart.attach(uart.UART1, 115200, 8, uart.PARNONE, uart.STOP1)

while true do
    -- Читаем данные из UART
    -- *cl возвращает данные вместе с нулевым COBS-разделителем.
    -- *l здесь не подходит: он использует нулевой байт как конец строки,
    -- но не передаёт его buffer:feed().
    local data = uart.read(uart.UART1, "*cl", 100, 512, 0)

    if data then
        -- Добавляем в буфер и получаем готовые фреймы
        local frames = buffer:feed(data)

        for _, frame in ipairs(frames) do
            -- Обрабатываем каждый принятый фрейм
            print("Frame received: " .. #frame .. " bytes")
        end
    end
end

Пример: отправка данных

local cobs = require("cobs")
local uart = require("uart")

-- Подготовка данных для отправки
local data = "sensor:temperature:25.5"
local encoded = cobs.encode(data)

-- Отправка через UART
uart.write(uart.UART1, encoded)