2015-04-14 76 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 

我希望這種方法可以理解嗎?我希望收到十六進制字符串,例如0x18C2,然後將其轉至0001 1000 1100 0010,將最右邊的位移到右側並將其放入正確的鍵中。然後在函數的後面,我會監視這個位是好壞的。

如果我跑終結者在Linux中有類似的功能,並打印出對我得到以下回報:

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

這是我不理解如何把每個值並將其設置爲位

我很新,所以我不懷疑有一個更簡單的方法來做到這一點。如果我需要進一步解釋,我會嘗試。

回答

2

我會以不同於Paul提出的方式來處理這個問題。

首先,創建一個表,用於存儲設備的性能:

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

我把你的代碼分離出來並運行在終結者中,以更好地理解你瘋狂背後的方法。我只運行了'BitConvert(sInput)'並打印了'tReturn {}'的鍵值。它確實將它分解成二元組,這非常棒。但是,當它分配二元條款時,它似乎是相反的。我喜歡你的方法,因爲它明確告訴我你將如何有條不紊地進行這種轉換。但我需要切換看起來的順序。我會看到關於翻轉訂單。否則,我愛你的方法hjpotter92!謝謝。 – Pwrcdr87

+0

@ Pwrcdr87如果順序顛倒;將所有'table.insert(tReturn,1,val)'改爲'table.insert(tReturn,val)' – hjpotter92

+0

將'table.insert(tReturn,1,iNum%2)'改爲'table.insert(tReturn,iNum %2)'和'table.insert(tReturn,1,0)'到'table.insert(tReturn,0)'。如您所述,訂單已翻轉!我知道我是新人,但我應該注意到,每個條目都被列入每個列表的第一位!非常感謝hjpotter!很好的答案! – Pwrcdr87

3

tonumber(s, 16)會將十六進制表示轉換爲十進制數,string.char將返回數字的符號/字節表示。查看這recent SO answer爲例如如何使用它們;答案中的解決方案可能適用於您。

+0

謝謝爲您的建議。我查看了鏈接,並理解你爲什麼提供它。但我更喜歡hjpotter的方法。對不起,但感謝您的意見! – Pwrcdr87

相關問題