545 lines
14 KiB
Markdown
545 lines
14 KiB
Markdown
# 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://<decoder-ip>/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!** 🚂
|