loco-engineering / simpledcc-arduino

Wireless DCC / WCC decoders for railway modelling (trains and accessories) and other models/toys based on Arduino
https://loco.engineering
9 stars 1 forks source link
arduino dcc dcc-decoder decoder digital-command-control esp esp32 esp32-arduino model-railroad model-railroad-arduino model-railroad-automation model-railroading model-railway remote-control wireless

Note: The project is in active development

DCC (Digital Command Control) / WCC (Wireless Command Control) decoders for model railways, LEGO and toys based on Arduino and ESP32S3 SOCs

License: Attribution-NonCommercial 4.0 International

For commercial use, please contact us at hey@loco.engineering with a description of your project and how you intend to use it.

If you like this project and its concept, please spread the word and don't forget to give us a star on GitHub. Your support helps us grow!

Why We Started Working on SimpleDCC

DCC (Digital Command Control) for model railways operates on a basic principle—a command station sends messages to DCC decoders via two wires or rails. Unlike most wireless systems, it doesn't involve encryption, authorization, or acknowledgment packets. However, updating the logic on DCC decoders remains a challenge, as it can't be done directly from a laptop or mobile phone without a command station. DCC decoder logic is typically predefined by the manufacturer, only allowing users to toggle certain features or outputs.

For example, if you want to test a new level crossing signal before installing it on your layout, you need to program decoders and sometimes use additional proprietary modules just to get the signals working (as seen in the Viessmann 5057 manual). The core concept behind SimpleDCC is to streamline DCC by enabling direct programming and control of DCC decoders from a browser on a computer, mobile phone, or tablet. A SimpleDCC decoder connects to a laptop or mobile device via Wi-Fi, USB, or even Bluetooth, eliminating the need for a command station. You can add custom logic to any decoder or use our DCC templates. The project is open-source (though a special commercial license is required for commercial use—contact us for more information).

What is WCC (Wireless Command Control)?

WCC (Wireless Command Control) is an open wireless system for operating model railways, LEGO® trains, RC cars, and other models or toys. WCC can run on DC, AC (including tracks with DCC), or battery power and requires only one essential hardware component:

Additionally, unpowered NFC stickers can be used optionally to provide more interaction possibilities.

WCC consists of:

The main difference between DCC and WCC lies in how messages or packets are transmitted. WCC messages are sent wirelessly, eliminating the need for wires, while DCC packets/messages are delivered through tracks or wires. Furthermore, WCC enables two-way communication between decoders, allowing trains, cars, and accessories to send messages directly to each other. Unlike DCC, WCC doesn't require a command station at all.

For more detailed information about WCC, please visit https://loco.engineering/docs

How SimpleDCC/WCC Decoders Differs from Other DCC Projects/Decoders

The main differences are:

Getting Started

How to build and upload custom firmware

Steps below are tested with ESP32-S3-WROOM-1-N16R8 modules. All Loco.Engineering boards are shipped with the default firmware that's why you shouldn't upload the firmware manually.

I don't see any logs

In case if you use Loco.Engineering decoder and don't see any logs in Arduino IDE, use the follow settings (Top Menu -> Tools -> ...)

Additional notes

if (DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER)
    {
        // and this isn't an Ops Mode Write or we are NOT faking the Multifunction Ops mode address in CV 33+34 or
        // it's not our fake address, then return
        if ( (CmdMasked != 0b11100000) || (DccProcState.OpsModeAddressBaseCV == 0))
            return ;

        uint16_t FakeOpsAddr = readCV (DccProcState.OpsModeAddressBaseCV) | (readCV (DccProcState.OpsModeAddressBaseCV + 1) << 8) ;
        uint16_t OpsAddr = Addr & 0x3FFF ;

        if (OpsAddr != FakeOpsAddr)
            return ;
    }

    // We are looking for FLAGS_MY_ADDRESS_ONLY but it does not match and it is not a Broadcast Address then return
    else if ( (DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY) && (Addr != getMyAddr()) && (Addr != 0))
        return ;

If you use your own version of NmraDCC (the repository includes the default version of NmraDCC when you download or clone the repository), you should comment the code above otherwise the decoder will be able to handle only accessory packets.

Contact Us

Feel free to contact us at hey@loco.engineering if you have any questions or feedback.