# 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 - [PlatformIO](https://platformio.org/) installed - Git (optional) ### Installation 1. Clone or download this repository 2. Open the `DCC-Loco` folder in PlatformIO (VS Code with PlatformIO extension) 3. Build the project: ```bash pio run ``` 4. Upload to ESP32-H2: ```bash pio run --target upload ``` 5. Monitor serial output: ```bash 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:///ws` **Commands:** Read CV: ```json { "command": "read_cv", "cv": 1 } ``` Write CV: ```json { "command": "write_cv", "cv": 1, "value": 5 } ``` Get Status: ```json { "command": "get_status" } ``` Reset to Defaults: ```json { "command": "reset" } ``` **Responses:** CV Read: ```json { "type": "cv_read", "cv": 1, "value": 3 } ``` Status: ```json { "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: ```cpp // 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!** 🚂