# 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 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.