nodemcu-firmware/lua_examples/dcc/dcc.lua

90 lines
2.3 KiB
Lua

-- Simple example for responding to NMRA DCC commands
-- author @voborsky
local PIN = 2 -- GPIO4
local addr = 0x12a
local CV = {[29]=0,
[1]=bit.band(addr, 0x3f), --CV_ACCESSORY_DECODER_ADDRESS_LSB (6 bits)
[9]=bit.band(bit.rshift(addr,6), 0x7) --CV_ACCESSORY_DECODER_ADDRESS_MSB (3 bits)
}
local function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local cmd_last
local params_last
local function is_new(cmd, params)
if cmd ~= cmd_last then return true end
for i,j in pairs(params) do
if params_last[i] ~= j then return true end
end
return false
end
local function DCC_command(cmd, params)
if not is_new(cmd, params) then return end
if cmd == dcc.DCC_IDLE then
return
elseif cmd == dcc.DCC_TURNOUT then
print("Turnout command")
elseif cmd == dcc.DCC_SPEED then
print("Speed command")
elseif cmd == dcc.DCC_FUNC then
print("Function command")
else
print("Other command", cmd)
end
for i,j in pairs(params) do
print(i, j)
end
print(("="):rep(80))
cmd_last = cmd
params_last = deepcopy(params)
end
local function CV_callback(operation, param)
local oper = ""
local result
if operation == dcc.CV_WRITE then
oper = "Write"
CV[param.CV]=param.Value
elseif operation == dcc.CV_READ then
oper = "Read"
result = CV[param.CV]
elseif operation == dcc.CV_VALID then
oper = "Valid"
result = 1
elseif operation == dcc.CV_RESET then
oper = "Reset"
CV = {}
end
print(("[CV_callback] %s CV %d%s")
:format(oper, param.CV, param.Value and "\tValue: "..param.Value or "\tValue: nil"))
return result
end
dcc.setup(PIN,
DCC_command,
dcc.MAN_ID_DIY, 1,
-- Accessories (turnouts) decoder:
--bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT, dcc.FLAGS_DCC_ACCESSORY_DECODER, dcc.FLAGS_MY_ADDRESS_ONLY),
-- Cab (train) decoder
bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT),
0, -- ???
CV_callback)