Как объединить байты в пользовательском протоколе для последовательного подключения Bluetooth

#lua #bit-manipulation #bitwise-operators

Вопрос:

Я хочу создать пользовательский протокол для отправки некоторых данных через соединение Bluetooth. Идея состоит в том, чтобы иметь начальный байт и заканчивать кадр контрольной суммой. Данные состоят как из целых чисел со знаком, так и без знака 8, 16 и 32 бит.

Из различных фрагментов кода, найденных на этом сайте и в остальной части Интернета, я собрал следующее с некоторыми фиктивными данными для проверки результата:

 local function checksum(val)
    c = 0
    for i = 0, string.len(val), 1 do
        c = bit32.bxor(c, string.byte(val, i))
    end
    return string.char(c)
end

local function i32(val)
    local b32HH = bit32.band(bit32.rshift(val, 24), 0xff);
    local b32HL = bit32.band(bit32.rshift(val, 16), 0xff);
    local b32LH = bit32.band(bit32.rshift(val, 8), 0xff);
    local b32LL = bit32.band(val, 0xff);
    return string.char(b32HH, b32HL, b32LH, b32LL)
end

local function i16(val)
    local b16H = bit32.band(bit32.rshift(val, 8), 0xff);
    local b16L = bit32.band(val, 0xff);
    return string.char(b16H, b16L)
end

local function i8(val)
    local b8 = bit32.band(val, 0xff);
    return string.char(b8)
end

local function sendFrame()
    local a = 2059368940    -- int32    4 bytes
    local b = -1201540427   -- int32    4 bytes
    local c = 682519180     -- int32    4 bytes
    local d = 38331         -- uint16   2 bytes
    local e = 1643          -- uint16   2 bytes
    local f = 177           -- uint8    1 byte

    local frame = string.char(0x17) -- start byte, just a random value
    frame = frame .. i32(a)
    frame = frame .. i32(b)
    frame = frame .. i32(c)
    frame = frame .. i16(d)
    frame = frame .. i16(e)
    frame = frame .. i8(f)
    frame = frame .. checksum(frame)
    println(frame)
end

sendFrame()
 

Когда я запускаю это в Lua 5.2, я получаю эту ошибку:

 $lua main.lua
lua: main.lua:45: attempt to call a nil value (global 'println')
stack traceback:
    main.lua:45: in local 'sendFrame'
    main.lua:48: in main chunk
    [C]: in ?
 

Очевидно, мое объединение строк для создания фрейма приводит к nil значению, но я не могу понять, почему.

Ответ №1:

Это потому, что вы используете println() в строке 45. println() это не команда в Lua, вы просто хотите использовать старую добрую моду print() . Если вам не нужен newline персонаж в конце, сделайте io.write() вместо него.

Комментарии:

1. Мой плохой, я заменил println() serialWrite() , потому что хотел, чтобы мой пример был простым. С print() помощью я не получаю никаких предупреждений, но он также ничего не печатает.

2. О, я вижу, вы пробовали ио.может быть, написать? Я не знаю наверняка, будет ли это иметь большее значение или нет. Извините, что не слишком разбираюсь в сериалах по Bluetooth

3. serialWrite() это специфично для платформы, на которой я запускаю этот скрипт (радиоуправляемый передатчик, работающий под управлением OpenTX). Я думал, что это не имеет отношения к моей проблеме, поэтому я оставил это, но теперь я уже не так уверен.