151 lines
6.7 KiB
HTML
151 lines
6.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>XpressNet Command Reference</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; background: #f4f4f4; color: #333; margin: 0; padding: 0; }
|
|
.container { max-width: 800px; margin: 40px auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); padding: 32px; }
|
|
h1, h2, h3 { color: #0077cc; }
|
|
table { width: 100%; border-collapse: collapse; margin-bottom: 24px; }
|
|
th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
|
|
th { background: #e9e9e9; }
|
|
pre { background: #f8f8f8; padding: 12px; border-radius: 4px; }
|
|
a { color: #0077cc; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>XpressNet Command Reference</h1>
|
|
<p>This page describes the available XpressNet commands and how to implement them in your command station firmware.</p>
|
|
|
|
<h2>XpressNet Command Table</h2>
|
|
<table>
|
|
<tr><th>Command Name</th><th>Code (Hex)</th><th>Description</th><th>Typical Usage</th></tr>
|
|
<tr><td>Locomotive Speed</td><td>0xE4</td><td>Set speed and direction for a locomotive</td><td>Control train movement</td></tr>
|
|
<tr><td>Function Group 1</td><td>0xE4</td><td>Control F0-F4 functions</td><td>Lights, sound, etc.</td></tr>
|
|
<tr><td>Function Group 2</td><td>0xE4</td><td>Control F5-F8 functions</td><td>Extended functions</td></tr>
|
|
<tr><td>Accessory Control</td><td>0x90</td><td>Switch turnouts, signals, etc.</td><td>Control layout accessories</td></tr>
|
|
<tr><td>Read Feedback</td><td>0xF2</td><td>Query feedback modules</td><td>Detect occupancy, sensors</td></tr>
|
|
<tr><td>Programming on Main</td><td>0xEF</td><td>Write CVs to decoders on main track</td><td>Decoder configuration</td></tr>
|
|
<tr><td>Programming Track</td><td>0xED</td><td>Write/read CVs on programming track</td><td>Safe decoder programming</td></tr>
|
|
<tr><td>Request Version</td><td>0x21</td><td>Request command station version</td><td>Handshake, diagnostics</td></tr>
|
|
<tr><td>Emergency Stop</td><td>0x80</td><td>Stop all locomotives immediately</td><td>Safety/emergency</td></tr>
|
|
</table>
|
|
<p><em>Note: Actual codes and command structure may vary by implementation. Refer to the official XpressNet protocol documentation for full details.</em></p>
|
|
|
|
<h2>Implementing XpressNet in Your Command Station</h2>
|
|
<ol>
|
|
<li><b>Serial Communication:</b> XpressNet typically uses RS485 or TTL UART. Set up a serial interface at the required baud rate (commonly 62500 baud).</li>
|
|
<li><b>Command Parsing:</b> 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.</li>
|
|
<li><b>Command Handling:</b>
|
|
<ul>
|
|
<li>For each recognized command, implement a handler function (e.g., <code>handleLocomotiveSpeed()</code>, <code>handleAccessoryControl()</code>).</li>
|
|
<li>Extract parameters (address, speed, function bits, etc.) from the command bytes.</li>
|
|
<li>Update your internal state or send DCC packets as needed.</li>
|
|
</ul>
|
|
</li>
|
|
<li><b>Response Generation:</b> Some commands require a response (e.g., version request, feedback read). Format and send the appropriate reply bytes.</li>
|
|
<li><b>Error Handling:</b> Implement checks for invalid or unsupported commands and respond with error codes if required by the protocol.</li>
|
|
<li><b>Integration with DCC:</b> For commands that affect trains or accessories, translate XpressNet commands into DCC packets and send them to the track using your DCC output routines.</li>
|
|
</ol>
|
|
|
|
<h3>Example: Handling a Locomotive Speed Command</h3>
|
|
<pre><code>void handleLocomotiveSpeed(const uint8_t* data, size_t len) {
|
|
// Parse address, speed, direction from data
|
|
// Update DCC packet buffer
|
|
// Send DCC packet to track
|
|
}
|
|
</code></pre>
|
|
|
|
<h3>References</h3>
|
|
<ul>
|
|
<li><a href="https://www.opendcc.de/elektronik/xpressnet/xpressnet_e.html">XpressNet Protocol Specification</a></li>
|
|
<li><a href="https://www.nmra.org/index-nmra-standards-and-recommended-practices">DCC Protocol Overview</a></li>
|
|
</ul>
|
|
|
|
<hr>
|
|
|
|
<h2>Custom (DIY) XpressNet Extensions</h2>
|
|
<p>You can add your own special commands to XpressNet by using unused command codes. Below are examples for switching mode and power control.</p>
|
|
<table>
|
|
<tr><th>Command Name</th><th>Code (Hex)</th><th>Payload Example</th><th>Description</th></tr>
|
|
<tr><td>Switch Mode</td><td>0xF0</td><td>0x00</td><td>Switch to Analog mode</td></tr>
|
|
<tr><td></td><td></td><td>0x01</td><td>Switch to DCC mode</td></tr>
|
|
<tr><td></td><td></td><td>0x02</td><td>Switch to Marklin mode</td></tr>
|
|
<tr><td>Power Track</td><td>0xF1</td><td>0x00</td><td>Power OFF</td></tr>
|
|
<tr><td></td><td></td><td>0x01</td><td>Power ON</td></tr>
|
|
</table>
|
|
|
|
<h3>Example Implementation in Firmware</h3>
|
|
<pre><code>// 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 ...
|
|
}
|
|
}
|
|
</code></pre>
|
|
|
|
<hr>
|
|
|
|
<h2>XpressNet over IP (WebSocket)</h2>
|
|
<p>You can encapsulate XpressNet packets in WebSocket frames for remote control over IP. On the ESP8266, use a WebSocket server library (e.g., arduinoWebSockets).</p>
|
|
|
|
<h3>Basic Steps:</h3>
|
|
<ol>
|
|
<li>Start a WebSocket server on the ESP8266.</li>
|
|
<li>On message received, treat the payload as an XpressNet packet and process it.</li>
|
|
<li>Send any response packets back over WebSocket.</li>
|
|
</ol>
|
|
|
|
<h3>Example (pseudo-code):</h3>
|
|
<pre><code>#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();
|
|
}
|
|
</code></pre>
|
|
|
|
<hr>
|
|
<p>These extensions allow you to add custom features and remote control to your XpressNet command station.</p>
|
|
</div>
|
|
</body>
|
|
</html>
|