2015-04-14 4 views
2

Я пытаюсь создать программу Lua для мониторинга периодических сообщений о состоянии ведомого устройства. Ведомое устройство отправляет свой статус в 16-битные шестнадцатеричные слова, которые мне нужно преобразовать в двоичную строку, поскольку каждый бит относится к свойству устройства. Я могу получить входную строку, и у меня есть таблица, содержащая 16 ключей для каждого параметра. Но мне сложно понять, как преобразовать шестнадцатеричное слово в строку из 16 бит, чтобы я мог ее контролировать.Lua: Шестнадцатеричное слово для двоичного преобразования

Вот основная функция того, над чем я начинаю работать.

function slave_Status(IP,Port,Name) 
    status = path:read(IP,Port) 
    sTable = {} 
    if status then 
     sTable.ready=bit32.rshift(status:byte(1), 0) 
     sTable.paused=bit32.rshift(status:byte(1), 1) 
     sTable.emergency=bit32.rshift(status:byte(1), 2) 
     sTable.started=bit32.rshift(status:byte(1), 3) 
     sTable.busy=bit32.rshift(status:byte(1), 4) 
     sTable.reserved1=bit32.rshift(status:byte(1), 5) 
     sTable.reserved2=bit32.rshift(status:byte(1), 6) 
     sTable.reserved3=bit32.rshift(status:byte(1), 7) 
     sTable.reserved4=bit32.rshift(status:byte(2), 0) 
     sTable.delay1=bit32.rshift(status:byte(2), 1) 
     sTable.delay2=bit32.rshift(status:byte(2), 2) 
     sTable.armoff=bit32.rshift(status:byte(2), 3) 
     sTable.shieldoff=bit32.rshift(status:byte(2), 4) 
     sTable.diskerror=bit32.rshift(status:byte(2), 5) 
     sTable.conoff=bit32.rshift(status:byte(2), 6) 
     sTable.envoff=bit32.rshift(status:byte(2), 7) 
    end 
end 

Надеюсь, этот подход понятен? Я хотел бы получить Hex-строки, например 0x18C2, и повернуть их на 0001 1000 1100 0010, сдвигая правый бит вправо и помещая его в соответствующий ключ. Затем позже в функции я буду следить, изменился ли этот бит к лучшему или к худшему.

Если я запускаю аналогичную функцию в Терминаторе в Linux, и распечатывать пары я получаю следующее возвращение:

49 
24 
12 
6 
3 
1 
0 
0 
56 
28 
14 
7 
3 
1 
0 
0 

Это где я, не понимая, как принимать каждое значение и установить его на куски

Я довольно новичок в этом, поэтому я не сомневаюсь, что есть более простой способ сделать это. Если мне нужно будет объяснить дальше, я попробую.

ответ

2

Я бы подошел к этому иначе, чем тот, который предложил Павел.

Во-первых, создать таблицу, хранящую свойства устройств:

local tProperty = { 
    "ready", 
    "paused", 
    "emergency", 
    "started", 
    "busy", 
    "reserved1", 
    "reserved2", 
    "reserved3", 
    "reserved4", 
    "delay1", 
    "delay2", 
    "armoff", 
    "shieldoff", 
    "diskerror", 
    "conoff", 
    "envoff", 
} 

Тогда, так как устройство отправляет данные в 0xYYYY, вы можете позвонить tonumber напрямую (если не строка). Используйте функцию для хранения каждого бита в таблице:

function BitConvert(sInput) 
    local tReturn, iNum = {}, tonumber(sInput) -- optionally pass 16 as second argument to tonumber 
    while iNum > 0 do 
     table.insert(tReturn, 1, iNum % 2) 
     iNum = math.floor(iNum/2) 
    end 
    for i = #tProperty - #tReturn, 1, -1 do 
     table.insert(tReturn, 1, 0) 
    end 
    return tReturn 
end 

А потом, карта и таблицы вместе:

function Map(tKeys, tValues) 
    local tReturn = {} 
    for i = 1, #tKeys do 
     tReturn[ tKeys[i] ] = tValues[i] 
    end 
    return tReturn 
end 

В конце концов, вы бы:

function slave_Status(IP, Port, Name) 
    local status = path:read(IP, Port) 
    local sTable = Map(tProperty, BitConvert(status)) 
end 
+0

Я отделил ваш код и запустил его в Terminator, чтобы лучше понять метод вашего безумия. Я запускал только «битконверт (sInput)» и печатал ключ, значения терминов 'tReturn {}'. Он разбивает его на двоичный, что отлично. Но когда он распределяет двоичные члены, он, кажется, обратный. Мне нравится ваш подход, потому что он явно показывает мне, как вы будете обращаться к этому преобразованию методично. Но мне нужно переключить порядок, который кажется. Я увижу о переводе заказа. В противном случае, я люблю ваш подход hjpotter92! Спасибо. – Pwrcdr87

+0

@ Pwrcdr87 Если заказ отменен; измените все 'table.insert (tReturn, 1, val)' на 'table.insert (tReturn, val)' – hjpotter92

+0

изменено 'table.insert (tReturn, 1, iNum% 2)' to 'table.insert (tReturn, iNum % 2) 'и' table.insert (tReturn, 1, 0) 'to' table.insert (tReturn, 0) '.Приказ перевернут, как вы заявили! Я знаю, что я новичок, но я должен был заметить, что каждая запись помещается в первую позицию каждого списка! Большое спасибо hjpotter! Отличный ответ! – Pwrcdr87

3

tonumber(s, 16) преобразует шестнадцатеричное представление в десятичное число, а string.char вернет представление символа/байта числа. Проверьте это значение recent SO answer на примере того, как они могут быть использованы; решение в ответе может сработать для вас.

+0

Спасибо за ваше предложение. Я просмотрел связанные и понял, почему вы это предоставили. Но мне нравится подход hjpotter немного больше. Извините, но спасибо за ваш вклад! – Pwrcdr87

Смежные вопросы