133 lines
5.7 KiB
Markdown
133 lines
5.7 KiB
Markdown
# XpressNet Command Reference
|
|
|
|
This document describes the available XpressNet commands and how to implement them in your command station firmware.
|
|
|
|
## XpressNet Command Table
|
|
|
|
| Command Name | Code (Hex) | Description | Typical Usage |
|
|
|-----------------------|------------|---------------------------------------------|------------------------------|
|
|
| Locomotive Speed | 0xE4 | Set speed and direction for a locomotive | Control train movement |
|
|
| Function Group 1 | 0xE4 | Control F0-F4 functions | Lights, sound, etc. |
|
|
| Function Group 2 | 0xE4 | Control F5-F8 functions | Extended functions |
|
|
| Accessory Control | 0x90 | Switch turnouts, signals, etc. | Control layout accessories |
|
|
| Read Feedback | 0xF2 | Query feedback modules | Detect occupancy, sensors |
|
|
| Programming on Main | 0xEF | Write CVs to decoders on main track | Decoder configuration |
|
|
| Programming Track | 0xED | Write/read CVs on programming track | Safe decoder programming |
|
|
| Request Version | 0x21 | Request command station version | Handshake, diagnostics |
|
|
| Emergency Stop | 0x80 | Stop all locomotives immediately | Safety/emergency |
|
|
|
|
*Note: Actual codes and command structure may vary by implementation. Refer to the official XpressNet protocol documentation for full details.*
|
|
|
|
## Implementing XpressNet in Your Command Station
|
|
|
|
1. **Serial Communication**: XpressNet typically uses RS485 or TTL UART. Set up a serial interface at the required baud rate (commonly 62500 baud).
|
|
|
|
2. **Command Parsing**: In your firmware, implement a parser that reads incoming bytes and matches them to the command table above. Use a state machine to handle multi-byte commands.
|
|
|
|
3. **Command Handling**:
|
|
- For each recognized command, implement a handler function (e.g., `handleLocomotiveSpeed()`, `handleAccessoryControl()`).
|
|
- Extract parameters (address, speed, function bits, etc.) from the command bytes.
|
|
- Update your internal state or send DCC packets as needed.
|
|
|
|
4. **Response Generation**: Some commands require a response (e.g., version request, feedback read). Format and send the appropriate reply bytes.
|
|
|
|
5. **Error Handling**: Implement checks for invalid or unsupported commands and respond with error codes if required by the protocol.
|
|
|
|
6. **Integration with DCC**: For commands that affect trains or accessories, translate XpressNet commands into DCC packets and send them to the track using your DCC output routines.
|
|
|
|
### Example: Handling a Locomotive Speed Command
|
|
```cpp
|
|
void handleLocomotiveSpeed(const uint8_t* data, size_t len) {
|
|
// Parse address, speed, direction from data
|
|
// Update DCC packet buffer
|
|
// Send DCC packet to track
|
|
}
|
|
```
|
|
|
|
### References
|
|
- [XpressNet Protocol Specification](https://www.opendcc.de/elektronik/xpressnet/xpressnet_e.html)
|
|
- [DCC Protocol Overview](https://www.nmra.org/index-nmra-standards-and-recommended-practices)
|
|
|
|
---
|
|
|
|
## Custom (DIY) XpressNet Extensions
|
|
|
|
You can add your own special commands to XpressNet by using unused command codes. Below are examples for switching mode and power control.
|
|
|
|
| Command Name | Code (Hex) | Payload Example | Description |
|
|
|---------------|------------|----------------|----------------------------|
|
|
| Switch Mode | 0xF0 | 0x00 | Switch to Analog mode |
|
|
| | | 0x01 | Switch to DCC mode |
|
|
| | | 0x02 | Switch to Marklin mode |
|
|
| Power Track | 0xF1 | 0x00 | Power OFF |
|
|
| | | 0x01 | Power ON |
|
|
|
|
### Example Implementation in Firmware
|
|
```cpp
|
|
// Handle custom XpressNet commands
|
|
void handleCustomXpressNet(const uint8_t* data, size_t len) {
|
|
uint8_t cmd = data[0];
|
|
switch (cmd) {
|
|
case 0xF0: // Switch Mode
|
|
if (len > 1) {
|
|
uint8_t mode = data[1];
|
|
switch (mode) {
|
|
case 0x00: /* setAnalogMode(); */ break;
|
|
case 0x01: /* setDCCMode(); */ break;
|
|
case 0x02: /* setMarklinMode(); */ break;
|
|
}
|
|
}
|
|
break;
|
|
case 0xF1: // Power Track
|
|
if (len > 1) {
|
|
if (data[1] == 0x01) {
|
|
// powerOnTrack();
|
|
} else {
|
|
// powerOffTrack();
|
|
}
|
|
}
|
|
break;
|
|
// ... handle other custom commands ...
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## XpressNet over IP (WebSocket)
|
|
|
|
You can encapsulate XpressNet packets in WebSocket frames for remote control over IP. On the ESP8266, use a WebSocket server library (e.g., arduinoWebSockets).
|
|
|
|
**Basic Steps:**
|
|
1. Start a WebSocket server on the ESP8266.
|
|
2. On message received, treat the payload as an XpressNet packet and process it.
|
|
3. Send any response packets back over WebSocket.
|
|
|
|
**Example (pseudo-code):**
|
|
```cpp
|
|
#include <WebSocketsServer.h>
|
|
WebSocketsServer webSocket = WebSocketsServer(81);
|
|
|
|
void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
|
if (type == WStype_BIN) {
|
|
// Process XpressNet packet
|
|
handleXpressNet(payload, length);
|
|
// Optionally send response:
|
|
// webSocket.sendBIN(num, response, responseLen);
|
|
}
|
|
}
|
|
|
|
void setup() {
|
|
// ... WiFi setup ...
|
|
webSocket.begin();
|
|
webSocket.onEvent(onWebSocketEvent);
|
|
}
|
|
|
|
void loop() {
|
|
webSocket.loop();
|
|
}
|
|
```
|
|
|
|
---
|
|
These extensions allow you to add custom features and remote control to your XpressNet command station.
|