5.6 KiB
DCC module
Since | Origin / Contributor | Maintainer | Source |
---|---|---|---|
2019-12-28 | vsky279 | vsky279 | dcc.c |
The dcc module implements decoder of the National Model Railroad Association (NMRA) Digital Command Control (DCC) decoder - see DCC wiki for details.
The hardware needed to decode the DCC signal can be built based on different DCC decoders implementation for Arduino, for inspiration see https://mrrwa.org/dcc-decoder-interface/. Basically the signal from the DCC bus is connected via an optocoupler to any GPIO pin. The DCC bus can be also used to power the ESP.
The module is based on the project NmraDcc https://github.com/mrrwa/NmraDcc by Alex Shepherd. The module is based on the version from May 2005, commit 6d12e6cd3f5f520020d49946652a94c1e3473f6b.
dcc.setup()
Initializes the dcc module and links callback functions.
Syntax
dcc.setup(DCC_command, ManufacturerId, VersionId, Flags, OpsModeAddressBaseCV, CV_callback)
Parameters
DCC_command(cmd, params)
calllback function that is called when a DCC command is decoded.cmd
parameters is one of the following values.params
contains a collection of parameters specific to given command.dcc.DCC_RESET
no additional parameters,params
isnil
.dcc.DCC_IDLE
no additional parameters,params
isnil
.dcc.DCC_SPEED
parameters collection members areAddr
,AddrType
,Speed
,Dir
,SpeedSteps
.dcc.DCC_SPEED_RAW
parameters collection members areAddr
,AddrType
,Raw
.dcc.DCC_FUNC
parameters collection members areAddr
,AddrType
,FuncGrp
,FuncState
.dcc.DCC_TURNOUT
parameters collection members areBoardAddr
,OutputPair
,Direction
,OutputPower
orAddr
,Direction
,OutputPower
.dcc.DCC_ACCESSORY
parameters collection has one memberBoardAddr
orAddr
orState
.dcc.DCC_RAW
parameters collection member areSize
,PreambleBits
,Data1
toData6
.dcc.DCC_SERVICEMODE
parameters collection has one memberInServiceMode
.
ManufacturerId
Manufacturer ID returned in CV 8. Commonlydcc.MAN_ID_DIY
.VersionId
Version ID returned in CV 7.Flags
one of or combination (OR operator) ofdcc.FLAGS_MY_ADDRESS_ONLY
Only process packets with My Address.dcc.FLAGS_DCC_ACCESSORY_DECODER
Decoder is an accessory decode.dcc.FLAGS_OUTPUT_ADDRESS_MODE
This flag applies to accessory decoders only. Accessory decoders normally have 4 paired outputs and a single address refers to all 4 outputs. Setting this flag causes each address to refer to a single output.dcc.FLAGS_AUTO_FACTORY_DEFAULT
Call DCC command callback withdcc.CV_RESET
command if CV 7 & 8 == 255.
OpsModeAddressBaseCV
Ops Mode base address. Set it to 0?CV_callback(operation, param)
callback function that is called when any manipulation with CV (Configuarion Variable) is requested.dcc.CV_VALID
to determine if a given CV is valid. This callback must determine if a CV is valid and return the appropriate value.param
collection has membersCV
andValue
.dcc.CV_READ
to read a CV. This callback must return the value of the CV.param
collection has one memberCV
determing the CV number to be read.dcc.CV_WRITE
to write a value to a CV. This callback must write the Value to the CV and return the value of the CV.param
collection has membersCV
andValue
.dcc.CV_RESET
Called when CVs must be reset to their factory defaults.
Returns
nil
Example
bit
module is used in the example though it is not needed for the dcc module functionality.
local PIN = 2 -- GPIO4
local addr = 0x12a
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 DCC_command(cmd, params)
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))
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 == CV_RESET then
oper = "Reset"
CV = {}
end
print(("[CV_callback] %s CV %d%s"):format(oper, param.CV or `nil`, param.Value and "\tValue: "..param.Value or "\tValue: nil"))
return result
end
dcc.setup(PIN,
DCC_command,
dcc.MAN_ID_DIY, 1,
--bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT, dcc.FLAGS_DCC_ACCESSORY_DECODER, dcc.FLAGS_MY_ADDRESS_ONLY),
bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT),
0, -- ???
CV_callback)
dcc.close()
Stops the dcc module.
Syntax
dcc.close()
Parameters
nil
Returns
nil