#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). Я думал, что это не имеет отношения к моей проблеме, поэтому я оставил это, но теперь я уже не так уверен.