diff --git a/data/Speed.jpg b/data/Speed.jpg new file mode 100644 index 0000000..f1d8eae Binary files /dev/null and b/data/Speed.jpg differ diff --git a/data/Speed.png b/data/Speed.png new file mode 100644 index 0000000..e82a662 Binary files /dev/null and b/data/Speed.png differ diff --git a/data/Speed.xcf b/data/Speed.xcf new file mode 100644 index 0000000..183ca95 Binary files /dev/null and b/data/Speed.xcf differ diff --git a/welcome.html b/data/index.html similarity index 79% rename from welcome.html rename to data/index.html index 5139f76..05cae7b 100644 --- a/welcome.html +++ b/data/index.html @@ -13,10 +13,11 @@
-

Welcome!

+

ESP8266 DCC Command Station

This is your ESP8266 DCC Command Station.

Configure WiFi, manage XpressNet, and control your layout from here.

-

For documentation, see XpressNet Commands and Hardware Setup.

+

For documentation, see XpressNet Commands and Hardware Setup.

diff --git a/data/mouse.html b/data/mouse.html new file mode 100644 index 0000000..6dd2cc3 --- /dev/null +++ b/data/mouse.html @@ -0,0 +1,53 @@ + + + + + + Mouse Speedometer + + + +
+

Mouse Speedometer

+
+ + + + + +
+
+ + + +
+
+ + + diff --git a/data/speed.js b/data/speed.js new file mode 100644 index 0000000..4781a45 --- /dev/null +++ b/data/speed.js @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/data/speed.svg b/data/speed.svg new file mode 100644 index 0000000..7ec83cb --- /dev/null +++ b/data/speed.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/speedometer-svgrepo-com.svg b/data/speedometer-svgrepo-com.svg new file mode 100644 index 0000000..3e6dc0b --- /dev/null +++ b/data/speedometer-svgrepo-com.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/xpressnet.html b/data/xpressnet.html new file mode 100644 index 0000000..e396444 --- /dev/null +++ b/data/xpressnet.html @@ -0,0 +1,150 @@ + + + + + + XpressNet Command Reference + + + +
+

XpressNet Command Reference

+

This page describes the available XpressNet commands and how to implement them in your command station firmware.

+ +

XpressNet Command Table

+ + + + + + + + + + + +
Command NameCode (Hex)DescriptionTypical Usage
Locomotive Speed0xE4Set speed and direction for a locomotiveControl train movement
Function Group 10xE4Control F0-F4 functionsLights, sound, etc.
Function Group 20xE4Control F5-F8 functionsExtended functions
Accessory Control0x90Switch turnouts, signals, etc.Control layout accessories
Read Feedback0xF2Query feedback modulesDetect occupancy, sensors
Programming on Main0xEFWrite CVs to decoders on main trackDecoder configuration
Programming Track0xEDWrite/read CVs on programming trackSafe decoder programming
Request Version0x21Request command station versionHandshake, diagnostics
Emergency Stop0x80Stop all locomotives immediatelySafety/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. +
  3. 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.
  4. +
  5. 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.
    • +
    +
  6. +
  7. Response Generation: Some commands require a response (e.g., version request, feedback read). Format and send the appropriate reply bytes.
  8. +
  9. Error Handling: Implement checks for invalid or unsupported commands and respond with error codes if required by the protocol.
  10. +
  11. 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.
  12. +
+ +

Example: Handling a Locomotive Speed Command

+
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

+ + +
+ +

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 NameCode (Hex)Payload ExampleDescription
Switch Mode0xF00x00Switch to Analog mode
0x01Switch to DCC mode
0x02Switch to Marklin mode
Power Track0xF10x00Power OFF
0x01Power ON
+ +

Example Implementation in Firmware

+
// 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. +
  3. On message received, treat the payload as an XpressNet packet and process it.
  4. +
  5. Send any response packets back over WebSocket.
  6. +
+ +

Example (pseudo-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();
+}
+
+ +
+

These extensions allow you to add custom features and remote control to your XpressNet command station.

+
+ + diff --git a/platformio.ini b/platformio.ini index ff5e5f2..969ae30 100644 --- a/platformio.ini +++ b/platformio.ini @@ -7,3 +7,4 @@ lib_deps = tzapu/WiFiManager Wire adafruit/Adafruit SSD1306 +board_build.filesystem = littlefs diff --git a/src/main.cpp b/src/main.cpp index 90b08ab..fc2537e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "WiFiManagerHelper.h" #include "main.h" #include +#include #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels @@ -23,34 +24,56 @@ Adafruit_SSD1306 *display; // Create web server instance on port 80 ESP8266WebServer server(80); -// HTML content for welcome page -const char* welcome_html = R"HTML( - - - - - - Welcome to ESP8266 DCC Command Station - - - -
-

Welcome!

-

This is your ESP8266 DCC Command Station.

-

Configure WiFi, manage XpressNet, and control your layout from here.

-

For documentation, see XpressNet Commands and Hardware Setup.

-
- - -)HTML"; +// // HTML content for welcome page +// const char* welcome_html = R"HTML( +// +// +// +// +// +// Welcome to ESP8266 DCC Command Station +// +// +// +//
+//

Welcome!

+//

This is your ESP8266 DCC Command Station.

+//

Configure WiFi, manage XpressNet, and control your layout from here.

+//

For documentation, see XpressNet Commands and Hardware Setup.

+//
+// +// +// )HTML"; void handleWelcome() { - server.send(200, "text/html", welcome_html); + if (LittleFS.exists("/index.html")) { + File file = LittleFS.open("/index.html", "r"); + if (file) { + String html = file.readString(); + server.send(200, "text/html", html); + file.close(); + return; + } + } + server.send(404, "text/plain", "Welcome page not found"); +} + +void handleXpressNetPage() { + if (LittleFS.exists("/xpressnet.html")) { + File file = LittleFS.open("/xpressnet.html", "r"); + if (file) { + String html = file.readString(); + server.send(200, "text/html", html); + file.close(); + return; + } + } + server.send(404, "text/plain", "XpressNet page not found"); } void setup() { @@ -60,7 +83,32 @@ void setup() { displayInit(); Serial.println("[DEBUG] OLED display initialized"); setupWiFiManager(); + if (!LittleFS.begin()) { + Serial.println("[ERROR] LittleFS mount failed"); + while(true) { + display->clearDisplay(); + display->setTextSize(1); + display->setTextColor(SSD1306_WHITE); + display->setCursor(0, 0); + display->println("LittleFS Mount Failed!"); + display->display(); + delay(1000); + } + } else { + Serial.println("[DEBUG] LittleFS mounted"); + // List files in LittleFS root for debug + // Serial.println("[DEBUG] LittleFS root directory:"); + // Dir dir = LittleFS.openDir("/"); + // while (dir.next()) { + // Serial.print(" "); + // Serial.print(dir.fileName()); + // Serial.print(" (size: "); + // Serial.print(dir.fileSize()); + // Serial.println(")"); + // } + } server.on("/", handleWelcome); + server.on("/xpressnet.html", handleXpressNetPage); server.begin(); Serial.println("[DEBUG] Web server started"); }