硬件
協議規定
上位機同時控制兩路繼電器協議: "data":"switch":開關指令; "bit":"1&2":第一路和第二路
詢問兩路繼電器狀態: {"data":"switch","bit":"1&2","status":"-1"}
控制兩路繼電器吸合: {"data":"switch","bit":"1&2","status":"1&1"}
控制兩路繼電器斷開: {"data":"switch","bit":"1&2","status":"0&0"}
控制第一路吸合,第二路斷開: {"data":"switch","bit":"1&2","status":"1&0"}
控制第一路斷開,第二路吸合: {"data":"switch","bit":"1&2","status":"0&1"}
下位機回復兩路繼電器狀態:
第一路斷開,第二路吸合: {"data":"switch","bit":"1&2","status":"0&1"}
上位機控制一路繼電器協議: "bit":"1":第一路
詢問第一路繼電器狀態: {"data":"switch","bit":"1","status":"-1"}
詢問第二路繼電器狀態: {"data":"switch","bit":"2","status":"-1"}
控制第一路繼電器吸合: {"data":"switch","bit":"1","status":"1"}
控制第二路繼電器斷開: {"data":"switch","bit":"2","status":"0"}
下位機回復兩路繼電器狀態:
第一路斷開 {"data":"switch","bit":"1","status":"0"}
第二路吸合 {"data":"switch","bit":"2","status":"1"}
處理繼電器消息
--- 模塊功能:MQTT客戶端數據接收處理 -- @author openLuat -- @module mqtt.mqttInMsg -- @license MIT -- @copyright openLuat -- @release 2018.03.28 module(...,package.seeall) require"pins" local IntoFlag=false; local JsonTable = {};--組合JSON使用 --繼電器引腳 RelayPin1 = pins.setup(pio.P0_4,0) RelayPin1In = pio.P0_4 RelayPin2 = pins.setup(pio.P0_2,0) RelayPin2In = pio.P0_2 --記錄繼電器的狀態,狀態改變發送狀態 local RelayState1; local RelayState2; --處理繼電器數據 local function Relay(jsondata) IntoFlag = false; if jsondata["bit"] ~= nil then if jsondata["bit"] =="1&2" then --兩路繼電器 if jsondata["status"] ~= nil then if jsondata["status"] =="-1" then--查詢 IntoFlag=true; elseif jsondata["status"] =="0&0" then IntoFlag=true; RelayPin1(0); RelayPin2(0); elseif jsondata["status"] =="0&1" then IntoFlag=true; RelayPin1(0); RelayPin2(1); elseif jsondata["status"] =="1&0" then IntoFlag=true; RelayPin1(1); RelayPin2(0); elseif jsondata["status"] =="1&1" then IntoFlag=true; RelayPin1(1); RelayPin2(1); end if IntoFlag==true then JsonTable["data"] = "switch"; JsonTable["bit"] = "1&2"; JsonTable["status"] = pio.pin.getval(RelayPin1In).."&"..pio.pin.getval(RelayPin2In); --拼接繼電器狀態 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end elseif jsondata["bit"] =="1" then --控制第一路繼電器 if jsondata["status"] ~= nil then if jsondata["status"] =="-1" then--查詢 IntoFlag=true; elseif jsondata["status"] =="0" then IntoFlag=true; RelayPin1(0); elseif jsondata["status"] =="1" then IntoFlag=true; RelayPin1(1); end if IntoFlag==true then JsonTable["data"] = "switch"; JsonTable["bit"] = "1"; JsonTable["status"] = pio.pin.getval(RelayPin1In); --繼電器狀態 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end elseif jsondata["bit"] =="2" then --控制第一路繼電器 if jsondata["status"] ~= nil then if jsondata["status"] =="-1" then--查詢 IntoFlag=true; elseif jsondata["status"] =="0" then IntoFlag=true; RelayPin2(0); elseif jsondata["status"] =="1" then IntoFlag=true; RelayPin2(1); end if IntoFlag==true then JsonTable["data"] = "switch"; JsonTable["bit"] = "2"; JsonTable["status"] = pio.pin.getval(RelayPin2In); --繼電器狀態 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end end end end local function LoopTimer(param) if RelayState1 ~= pio.pin.getval(RelayPin1In) then--繼電器狀態變化,發送繼電器狀態 RelayState1 = pio.pin.getval(RelayPin1In) JsonTable["data"] = "switch" JsonTable["bit"] = "1" JsonTable["status"] = pio.pin.getval(RelayPin1In) --繼電器狀態 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end if RelayState2 ~= pio.pin.getval(RelayPin2In) then--繼電器狀態變化,發送繼電器狀態 RelayState2 = pio.pin.getval(RelayPin2In) JsonTable["data"] = "switch" JsonTable["bit"] = "2" JsonTable["status"] = pio.pin.getval(RelayPin2In) --繼電器狀態 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end sys.timerLoopStart(LoopTimer,1) --- MQTT客戶端數據接收處理 -- @param mqttClient,MQTT客戶端對象 -- @return 處理成功返回true,處理出錯返回false -- @usage mqttInMsg.proc(mqttClient) function proc(mqttClient) local result,data while true do result,data = mqttClient:receive(2000) --接收到數據 if result then local jsondata,result,errinfo = json.decode(data.payload)--判斷是不是json --dup,topic,id,payload,qos,retain if result and type(jsondata)=="table" then -- 是json數據 if jsondata["data"] ~= nil and jsondata["data"] =="switch" then Relay(jsondata) --處理繼電器 end else --非JSON數據 end uart.write(1, data.payload) --串口輸出接收的數據 --如果mqttOutMsg中有等待發送的數據,則立即退出本循環 if mqttOutMsg.waitForSend() then return true end else break end end return result or data=="timeout" end
測試
打開MQTT調試助手
提示:設備的IMEI可看自己模塊上的
訂閱的主題: device/設備的imei號
發布的主題: user/設備的imei號
控制兩路繼電器吸合
{"data":"switch","bit":"1&2","status":"1&1"}
控制兩路繼電器斷開
{"data":"switch","bit":"1&2","status":"0&0"}