nodemcu-firmware/docs/modules/dcc.md

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 is nil.
    • dcc.DCC_IDLE no additional parameters, params is nil.
    • dcc.DCC_SPEED parameters collection members are Addr, AddrType, Speed,Dir, SpeedSteps.
    • dcc.DCC_SPEED_RAW parameters collection members are Addr, AddrType, Raw.
    • dcc.DCC_FUNC parameters collection members are Addr, AddrType, FuncGrp,FuncState.
    • dcc.DCC_TURNOUT parameters collection members are BoardAddr, OutputPair, Direction,OutputPower or Addr, Direction,OutputPower.
    • dcc.DCC_ACCESSORY parameters collection has one member BoardAddr or Addr or State.
    • dcc.DCC_RAW parameters collection member are Size, PreambleBits, Data1 to Data6.
    • dcc.DCC_SERVICEMODE parameters collection has one member InServiceMode.
  • ManufacturerId Manufacturer ID returned in CV 8. Commonly dcc.MAN_ID_DIY.
  • VersionId Version ID returned in CV 7.
  • Flags one of or combination (OR operator) of
    • dcc.FLAGS_MY_ADDRESS_ONLYOnly 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 with dcc.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_VALIDto determine if a given CV is valid. This callback must determine if a CV is valid and return the appropriate value. param collection has members CV and Value.
    • dcc.CV_READ to read a CV. This callback must return the value of the CV. param collection has one member CV 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 members CV and Value.
    • 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