Files
Maison/ESP32/DCC-Loco
2026-02-10 12:12:11 +01:00
..
2026-02-10 12:12:11 +01:00
2026-02-10 12:12:11 +01:00
2026-02-10 12:12:11 +01:00
2026-02-10 12:12:11 +01:00
2026-02-10 12:12:11 +01:00

DCC Locomotive Decoder

ESP32-H2 based DCC locomotive decoder with advanced features for model railroading.

Features

  • DCC Signal Decoding: Full NMRA-compliant DCC decoder supporting short (1-127) and long (128-10239) addresses
  • Motor Control: TB67H450FNG H-bridge motor driver with:
    • 128-step speed control
    • Configurable acceleration/deceleration
    • Load compensation with PID control
    • Current sensing
  • LED Control: WS2812 addressable LED support
    • Multiple lighting effects (solid, blink, pulse, directional)
    • Function-mapped lighting
    • Adjustable brightness
  • RailCom Feedback: Bidirectional communication with command station
  • Accessory Outputs: 2x N-channel MOSFET outputs for accessories
    • Smoke generators
    • Sound modules
    • Other low-side switched loads
  • Configuration: WiFi/Bluetooth configuration via WebSocket
    • Web-based interface
    • CV (Configuration Variable) management
    • Real-time status monitoring

Hardware Requirements

Components

  • ESP32-H2 Development Board (e.g., ESP32-H2-DevKitM-1)
  • TB67H450FNG Motor Driver IC
  • WS2812 or compatible addressable LEDs
  • N-channel MOSFETs (2x) for accessory outputs (e.g., IRLZ44N)
  • Optocoupler for DCC signal isolation (e.g., 6N137 or PC817)
  • Current sense resistor (0.1Ω - 0.5Ω, 1W or higher)
  • Capacitors: 100µF electrolytic, 0.1µF ceramic
  • Resistors: Pull-ups/pull-downs as needed
  • Push button for configuration mode

Power Supply

  • Track Power: 12-18V DC from DCC track
  • Logic Power: 3.3V for ESP32-H2 (use onboard regulator or external LDO)
  • Motor Power: Same as track power (filtered)

Wiring Diagram

DCC Input

DCC Track Signal
     |
     +---[1kΩ]---+---[Optocoupler Anode]
     |          |
   [10kΩ]     [0.1µF]
     |          |
    GND        GND

Optocoupler Cathode ---[470Ω]--- 3.3V
Optocoupler Output  --- GPIO4 (PIN_DCC_INPUT)
Optocoupler Ground  --- GND

TB67H450FNG Motor Driver

ESP32-H2          TB67H450FNG          Motor
GPIO5 ----------- IN1
GPIO6 ----------- IN2
GPIO7 ----------- PWM
                  OUT1 --------------- M+
                  OUT2 --------------- M-
                  VM  ---------------- Track+ (12-18V)
                  VCC ---------------- 3.3V
                  GND ---------------- GND
                  
Current Sensing:
                  IPROPI ------------- GPIO8 (via voltage divider)
                  [0.1Ω Rs between OUT2 and GND]

TB67H450FNG Pin Configuration:

Pin Connection Description
VM Track Power (12-18V) Motor power supply
VCC 3.3V Logic power supply
IN1 GPIO5 Input 1 (phase A)
IN2 GPIO6 Input 2 (phase B)
PWM GPIO7 PWM speed control
OUT1 Motor+ Motor output 1
OUT2 Motor- Motor output 2
IPROPI GPIO8 Current monitor output
GND GND Ground

Motor Control Truth Table:

IN1 IN2 PWM Operation
L L X Brake (standby)
H L PWM Forward
L H PWM Reverse
H H X Brake (active)

WS2812 LED Strip

ESP32-H2          WS2812
GPIO9 ----------- DIN (Data In)
3.3V/5V --------- VCC (check LED voltage requirements)
GND ------------- GND

Note: Add a 330-470Ω resistor in series with DIN
      Add a 100-1000µF capacitor across VCC and GND near LEDs

RailCom

ESP32-H2          Circuit
GPIO10 ---------- UART TX (to RailCom transmitter)
GPIO11 ---------- DCC Cutout Detection (optional)

RailCom Transmitter Circuit:
UART TX --- [Transistor Driver] --- Track Signal
(Sends during DCC cutout window)

Accessory Outputs (N-FETs)

ESP32-H2          N-FET (IRLZ44N)     Load
GPIO12 ---------- Gate 1
                  Source 1 ---------- GND
                  Drain 1 ----------- Load 1 (-)
                  
GPIO13 ---------- Gate 2
                  Source 2 ---------- GND
                  Drain 2 ----------- Load 2 (-)

Load (+) connects to positive supply
Add 10kΩ pull-down resistor from Gate to Source on each FET

Configuration Button

GPIO14 ---------- Button ---------- GND
(Internal pull-up enabled)

Complete Pin Assignment Table

Pin Function Connection Notes
GPIO4 DCC Input Optocoupler output DCC signal from track
GPIO5 Motor IN1 TB67H450FNG IN1 Motor phase A
GPIO6 Motor IN2 TB67H450FNG IN2 Motor phase B
GPIO7 Motor PWM TB67H450FNG PWM Speed control
GPIO8 Current Sense TB67H450FNG IPROPI ADC input
GPIO9 LED Data WS2812 DIN LED control
GPIO10 RailCom TX UART1 TX RailCom feedback
GPIO11 Cutout Detect DCC cutout circuit Optional
GPIO12 Accessory 1 N-FET Gate Output 1
GPIO13 Accessory 2 N-FET Gate Output 2
GPIO14 Config Button Push button to GND Enter config mode

Note: Pin assignments can be modified in src/main.cpp (PIN DEFINITIONS section).

Software Setup

Prerequisites

Installation

  1. Clone or download this repository
  2. Open the DCC-Loco folder in PlatformIO (VS Code with PlatformIO extension)
  3. Build the project:
    pio run
    
  4. Upload to ESP32-H2:
    pio run --target upload
    
  5. Monitor serial output:
    pio device monitor
    

Configuration

Initial Setup

On first boot, the decoder initializes with default values:

  • Address: 3 (short address)
  • Acceleration: 10
  • Deceleration: 10
  • LED Brightness: 128 (50%)
  • RailCom: Enabled
  • Load Compensation: Enabled

Configuration Mode

To enter configuration mode:

  1. Hold the configuration button (GPIO14) for 3 seconds
  2. The decoder creates a WiFi Access Point:
    • SSID: DCC-Loco-XXXXXX (XXXXXX = device ID)
    • Password: dcc12345
  3. Connect to the WiFi AP
  4. Open a web browser and navigate to http://192.168.4.1
  5. Use the web interface to:
    • Read/Write Configuration Variables (CVs)
    • Test outputs
    • Monitor decoder status
    • Reset to defaults
  6. Press the configuration button again to exit config mode

Configuration Variables (CVs)

Standard NMRA CVs:

CV Name Default Description
1 Primary Address 3 Short address (1-127)
2 Vstart 1 Start voltage
3 Acceleration Rate 10 Acceleration rate (0-255)
4 Deceleration Rate 10 Deceleration rate (0-255)
5 Vhigh 255 Maximum voltage
6 Vmid 128 Mid voltage
7 Version ID 1 Decoder version
8 Manufacturer ID 13 Manufacturer ID (DIY)
17-18 Extended Address - Long address (128-10239)
29 Configuration Data 6 Config bits (address mode, speed steps)

Custom CVs:

CV Name Default Description
50 Motor Kp 50 PID proportional gain (value/10)
51 Motor Ki 5 PID integral gain (value/10)
52 Motor Kd 10 PID derivative gain (value/10)
53 RailCom Enable 1 Enable RailCom (0=off, 1=on)
54 Load Comp Enable 1 Enable load compensation (0=off, 1=on)
55 LED Brightness 128 LED brightness (0-255)
56 Accessory 1 Mode 2 Accessory output 1 mode
57 Accessory 2 Mode 2 Accessory output 2 mode

Accessory Modes:

  • 0 = Always off
  • 1 = Always on
  • 2 = Function controlled
  • 3 = PWM control
  • 4 = Blinking
  • 5 = Speed dependent

WebSocket Protocol

The configuration server uses WebSocket for real-time communication.

Connect: ws://<decoder-ip>/ws

Commands:

Read CV:

{
  "command": "read_cv",
  "cv": 1
}

Write CV:

{
  "command": "write_cv",
  "cv": 1,
  "value": 5
}

Get Status:

{
  "command": "get_status"
}

Reset to Defaults:

{
  "command": "reset"
}

Responses:

CV Read:

{
  "type": "cv_read",
  "cv": 1,
  "value": 3
}

Status:

{
  "type": "status",
  "address": 3,
  "speed": 0,
  "direction": true,
  "signal": true,
  "current": 150,
  "functions": [false, false, true, ...]
}

Code Structure

DCC-Loco/
├── platformio.ini          # PlatformIO configuration
├── README.md               # This file
├── include/                # Header files
│   ├── DCCDecoder.h       # DCC signal decoding
│   ├── CVManager.h        # Configuration variable management
│   ├── LEDController.h    # WS2812 LED control
│   ├── MotorDriver.h      # TB67H450FNG motor control
│   ├── RailCom.h          # RailCom feedback
│   ├── AccessoryOutputs.h # Accessory output control
│   └── ConfigServer.h     # WiFi/Bluetooth config server
├── src/                    # Implementation files
│   ├── main.cpp           # Main application
│   ├── DCCDecoder.cpp
│   ├── CVManager.cpp
│   ├── LEDController.cpp
│   ├── MotorDriver.cpp
│   ├── RailCom.cpp
│   ├── AccessoryOutputs.cpp
│   └── ConfigServer.cpp
├── lib/                    # Custom libraries (if any)
├── data/                   # Web files (future use)
└── Hardware/               # KiCad project files (future)

Module Descriptions

DCCDecoder

Decodes DCC packets using interrupt-driven bit detection. Supports:

  • Short and long addresses
  • 128-step speed control
  • Functions F0-F28
  • Emergency stop
  • Signal quality monitoring

CVManager

Manages Configuration Variables in non-volatile storage using ESP32 Preferences:

  • NMRA-compliant CV storage
  • Factory reset functionality
  • Address management (short/long)

LEDController

Controls WS2812 addressable LEDs with FastLED:

  • Multiple light modes (solid, blink, pulse, directional)
  • Function mapping to LEDs
  • Brightness control
  • Up to 16 LEDs

MotorDriver

Controls TB67H450FNG motor driver:

  • Forward/reverse control
  • PWM speed control
  • Acceleration/deceleration curves
  • Load compensation with PID
  • Current monitoring

RailCom

Implements RailCom feedback protocol:

  • Channel 1: Address broadcast
  • Channel 2: Status information
  • 250kbaud communication
  • Cutout detection

AccessoryOutputs

Controls 2x N-FET outputs:

  • Multiple modes (on/off, function, PWM, blink, speed-dependent)
  • Function mapping
  • Independent control

ConfigServer

Web-based configuration interface:

  • WiFi Access Point mode
  • WebSocket real-time communication
  • CV read/write
  • Status monitoring
  • Reset functionality

Testing

Basic Test Procedure

  1. Power Up Test

    • Connect decoder to track power (12-18V DC)
    • Verify ESP32-H2 boots (check serial output)
    • Verify no smoke or excessive heat
  2. DCC Signal Test

    • Apply DCC signal to track
    • Check serial monitor for "DCC OK" messages
    • Verify correct address detection
  3. Motor Test

    • Send speed commands via DCC controller
    • Verify smooth acceleration/deceleration
    • Test forward and reverse
    • Check emergency stop
  4. LED Test

    • Verify headlights change with direction
    • Test function-controlled LEDs (F1, F2, etc.)
    • Check brightness adjustment
  5. Accessory Test

    • Activate mapped functions (F3, F4)
    • Verify N-FET outputs switch correctly
    • Test different output modes
  6. Configuration Test

    • Enter configuration mode (hold button 3s)
    • Connect to WiFi AP
    • Read/write CVs via web interface
    • Verify changes take effect after exit

Troubleshooting

No DCC Signal:

  • Check optocoupler wiring
  • Verify GPIO4 receives signal
  • Check for proper DCC track voltage

Motor doesn't run:

  • Verify TB67H450FNG connections
  • Check motor power supply (VM)
  • Verify PWM signal on GPIO7
  • Check motor connections

LEDs don't light:

  • Verify WS2812 data line connection
  • Check LED power supply voltage
  • Ensure correct NUM_LEDS setting
  • Check for loose connections

Can't enter config mode:

  • Verify button wiring (GPIO14 to GND)
  • Check serial monitor for messages
  • Try holding button longer (>3s)

WiFi AP not visible:

  • Check ESP32-H2 WiFi support
  • Verify sufficient power supply
  • Check for WiFi interference
  • Review serial output for errors

Advanced Features

Load Compensation

The decoder includes PID-based load compensation to maintain consistent speed under varying loads:

  • Monitors motor current
  • Adjusts PWM duty cycle
  • Tunable via CVs 50-52
  • Can be disabled via CV54

Custom Function Mapping

Edit src/main.cpp to customize LED and accessory mappings:

// Example: Map F5 to LED 2 with pulse effect
ledController.mapFunctionToLED(5, 2, LIGHT_PULSE);

// Example: Map F6 to accessory output 1
accessories.mapFunction(1, 6);

RailCom Customization

Extend RailCom data transmission in src/RailCom.cpp:

  • Add more status information in Channel 2
  • Implement CV read-back
  • Add custom data fields

Future Enhancements

  • Sound decoder support
  • SUSI interface for external sound modules
  • Bluetooth configuration
  • Advanced lighting effects (mars light, ditch lights)
  • Function remapping via CV
  • Dual motor support
  • ABC brake support
  • Servo outputs

Hardware Design Files

KiCad schematic and PCB files will be added to the Hardware/ folder in future releases.

License

This project is open-source and available under the MIT License.

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Submit a pull request

Support

For issues, questions, or suggestions:

  • Open an issue on GitHub
  • Check documentation in doc/ folder
  • Review source code comments

Credits

  • NMRA DCC specifications
  • ESP32-H2 Arduino core
  • FastLED library
  • AsyncWebServer library

Version History

  • v1.0 (2026-01-15): Initial release
    • DCC decoding
    • Motor control with load compensation
    • WS2812 LED support
    • RailCom feedback
    • Accessory outputs
    • WiFi configuration

Happy Model Railroading! 🚂