Ajout prise en charge ESP-Display

This commit is contained in:
Serge NOEL
2025-12-01 13:53:54 +01:00
parent bcd88909b7
commit ae375b8fe2
26 changed files with 3945 additions and 1017 deletions

View File

@@ -2,7 +2,7 @@
* @file Config.h
* @brief Configuration management for the Locomotive Test Bench
*
* This module handles persistent storage of WiFi and system settings
* This module handles persistent storage of system settings
* using ESP32's Preferences library (NVS - Non-Volatile Storage).
*
* @author Locomotive Test Bench Project
@@ -15,20 +15,6 @@
#include <Arduino.h>
#include <Preferences.h>
/**
* @struct WiFiConfig
* @brief WiFi configuration parameters
*
* Stores both Access Point and Client mode settings.
*/
struct WiFiConfig {
String ssid; ///< WiFi network SSID (Client mode)
String password; ///< WiFi network password (Client mode)
bool isAPMode; ///< True = AP mode, False = Client mode
String apSSID; ///< Access Point SSID
String apPassword; ///< Access Point password (min 8 characters)
};
/**
* @struct SystemConfig
* @brief System operation configuration
@@ -37,6 +23,8 @@ struct WiFiConfig {
*/
struct SystemConfig {
bool isDCCMode; ///< True = DCC digital, False = DC analog
bool is3Rail; ///< True = 3-rail mode, False = 2-rail mode
bool powerOn; ///< True = power enabled, False = power off
uint16_t dccAddress; ///< DCC locomotive address (1-10239)
uint8_t speed; ///< Speed setting (0-100%)
uint8_t direction; ///< Direction: 0 = reverse, 1 = forward
@@ -71,7 +59,7 @@ public:
/**
* @brief Save current configuration to NVS
*
* Writes all WiFi and system settings to persistent storage.
* Writes all system settings to persistent storage.
* Should be called after any configuration changes.
*/
void save();
@@ -92,11 +80,12 @@ public:
*/
void reset();
WiFiConfig wifi; ///< WiFi configuration settings
SystemConfig system; ///< System operation settings
private:
Preferences preferences; ///< ESP32 NVS preferences object
};
#endif // CONFIG_H
#endif

View File

@@ -19,8 +19,11 @@
#include <Arduino.h>
// Pin definitions for DCC output
#define DCC_PIN_A 32 ///< DCC Signal A output pin
#define DCC_PIN_B 33 ///< DCC Signal B output pin (inverted)
// These share the same pins as the motor controller (LM18200)
// In DCC mode: GPIO 18 = DCC Signal A, GPIO 19 = DCC Signal B
// In DC mode: GPIO 18 = PWM, GPIO 19 = Direction
#define DCC_PIN_A 18 ///< DCC Signal A output pin (shared with MOTOR_PWM_PIN)
#define DCC_PIN_B 19 ///< DCC Signal B output pin (shared with MOTOR_DIR_PIN)
// DCC timing constants (microseconds) - NMRA standard
#define DCC_ONE_BIT_TOTAL_DURATION_MAX 64 ///< Max duration for '1' bit
@@ -99,6 +102,37 @@ public:
*/
bool isEnabled() { return enabled; }
// Programming Track Methods
/**
* @brief Factory reset decoder (send CV8 = 8)
* @return true if successful
*/
bool factoryReset();
/**
* @brief Set decoder address
* @param address New address (1-10239)
* @return true if successful
*/
bool setDecoderAddress(uint16_t address);
/**
* @brief Read CV value from decoder
* @param cv CV number (1-1024)
* @param value Pointer to store read value
* @return true if successful
*/
bool readCV(uint16_t cv, uint8_t* value);
/**
* @brief Write CV value to decoder
* @param cv CV number (1-1024)
* @param value Value to write (0-255)
* @return true if successful
*/
bool writeCV(uint16_t cv, uint8_t value);
private:
bool enabled; ///< DCC generator enabled flag
uint16_t currentAddress; ///< Current locomotive address
@@ -153,6 +187,40 @@ private:
* @return XOR checksum byte
*/
uint8_t calculateChecksum(uint8_t* data, uint8_t length);
// Programming track helper methods
/**
* @brief Send service mode packet (programming track)
* @param data Packet data bytes
* @param length Number of bytes
*/
void sendServiceModePacket(uint8_t* data, uint8_t length);
/**
* @brief Verify byte write on programming track
* @param cv CV number
* @param value Expected value
* @return true if ACK detected
*/
bool verifyByte(uint16_t cv, uint8_t value);
/**
* @brief Wait for ACK pulse from decoder
* @return true if ACK detected within timeout
*/
bool waitForAck();
/**
* @brief Calibrate ACS712 current sensor zero point
*
* Reads current sensor with no load to establish baseline.
* Should be called during initialization.
*/
void calibrateCurrentSensor();
};
// Programming track current sensing threshold (mA)
#define PROG_ACK_CURRENT_THRESHOLD 60 ///< Minimum ACK current (mA)
#endif

View File

@@ -15,10 +15,10 @@
#include <Arduino.h>
// Pin definitions for LM18200
// These can be adjusted based on your D1 Mini ESP32 wiring
#define MOTOR_PWM_PIN 25 ///< PWM signal output pin
#define MOTOR_DIR_PIN 26 ///< Direction control pin
#define MOTOR_BRAKE_PIN 27 ///< Brake control pin (active low)
// Adjusted for ESP32-2432S028R available GPIOs
#define MOTOR_PWM_PIN 18 ///< PWM signal output pin
#define MOTOR_DIR_PIN 19 ///< Direction control pin
#define MOTOR_BRAKE_PIN 23 ///< Brake control pin (active low)
/**
* @class MotorController

59
include/RelayController.h Normal file
View File

@@ -0,0 +1,59 @@
/**
* @file RelayController.h
* @brief Relay control for switching between 2-rail and 3-rail track configurations
*
* Controls a relay module to switch track wiring between:
* - 2-rail mode: Standard DC/DCC operation
* - 3-rail mode: Center rail + outer rails configuration
*
* @author Locomotive Test Bench Project
* @date 2025
*/
#ifndef RELAY_CONTROLLER_H
#define RELAY_CONTROLLER_H
#include <Arduino.h>
// Pin definition for relay control
#define RELAY_PIN 4 ///< Relay control pin (active HIGH)
/**
* @class RelayController
* @brief Controls relay for track configuration switching
*
* Simple relay control for switching between 2-rail and 3-rail modes.
* Relay energized = 3-rail mode
* Relay de-energized = 2-rail mode
*/
class RelayController {
public:
/**
* @brief Constructor
*/
RelayController();
/**
* @brief Initialize relay controller hardware
*
* Configures GPIO pin and sets to default 2-rail mode.
*/
void begin();
/**
* @brief Set rail mode
* @param is3Rail true = 3-rail mode, false = 2-rail mode
*/
void setRailMode(bool is3Rail);
/**
* @brief Get current rail mode
* @return true if 3-rail mode, false if 2-rail mode
*/
bool is3RailMode() { return is3Rail; }
private:
bool is3Rail; ///< Current rail mode state
};
#endif // RELAY_CONTROLLER_H

188
include/TouchscreenUI.h Normal file
View File

@@ -0,0 +1,188 @@
/**
* @file TouchscreenUI.h
* @brief Touchscreen user interface for locomotive test bench
*
* Provides a graphical interface on the ILI9341 TFT display with touch controls for:
* - Power ON/OFF button
* - DCC/Analog mode switching
* - Speed slider (0-100%)
* - 2-rail/3-rail configuration selector
* - Direction control
* - Status display
*
* @author Locomotive Test Bench Project
* @date 2025
*/
#ifndef TOUCHSCREEN_UI_H
#define TOUCHSCREEN_UI_H
#include <Arduino.h>
#include <TFT_eSPI.h>
#include <XPT2046_Touchscreen.h>
#include "Config.h"
#include "MotorController.h"
#include "DCCGenerator.h"
#include "RelayController.h"
// Touch calibration values for ESP32-2432S028R
#define TS_MIN_X 200
#define TS_MAX_X 3700
#define TS_MIN_Y 200
#define TS_MAX_Y 3750
// UI Colors
#define COLOR_BG 0x0000 // Black
#define COLOR_PANEL 0x2945 // Dark gray
#define COLOR_TEXT 0xFFFF // White
#define COLOR_POWER_ON 0x07E0 // Green
#define COLOR_POWER_OFF 0xF800 // Red
#define COLOR_DCC 0x07FF // Cyan
#define COLOR_ANALOG 0xFFE0 // Yellow
#define COLOR_SLIDER 0x435C // Gray
#define COLOR_SLIDER_ACTIVE 0x07E0 // Green
#define COLOR_BUTTON 0x4A49 // Button gray
#define COLOR_BUTTON_ACTIVE 0x2124 // Darker gray
#define COLOR_FUNCTION_OFF 0x31A6 // Dark blue-gray
#define COLOR_FUNCTION_ON 0xFD20 // Orange
/**
* @struct Button
* @brief Simple button structure for touch areas
*/
struct Button {
int16_t x, y, w, h;
String label;
uint16_t color;
bool visible;
};
/**
* @class TouchscreenUI
* @brief Manages touchscreen display and user interactions
*
* Provides complete UI for controlling the locomotive test bench,
* handling touch events, updating displays, and coordinating with
* motor controller, DCC generator, and relay controller.
*/
class TouchscreenUI {
public:
/**
* @brief Constructor
* @param cfg Pointer to configuration object
* @param motor Pointer to motor controller
* @param dcc Pointer to DCC generator
* @param relay Pointer to relay controller
*/
TouchscreenUI(Config* cfg, MotorController* motor, DCCGenerator* dcc, RelayController* relay);
/**
* @brief Initialize touchscreen and display
*
* Sets up TFT display, touch controller, and draws initial UI.
*/
void begin();
/**
* @brief Update UI and handle touch events
*
* Must be called regularly from main loop.
* Handles touch detection, UI updates, and state changes.
*/
void update();
/**
* @brief Force full screen redraw
*/
void redraw();
/**
* @brief Get power state
* @return true if power is ON
*/
bool isPowerOn() { return powerOn; }
private:
TFT_eSPI tft;
XPT2046_Touchscreen touch;
Config* config;
MotorController* motorController;
DCCGenerator* dccGenerator;
RelayController* relayController;
bool powerOn;
uint8_t lastSpeed;
bool lastDirection;
bool lastIsDCC;
bool lastIs3Rail;
uint32_t lastDccFunctions;
// Programming screen state
bool programmingMode;
uint16_t cvNumber;
uint8_t cvValue;
uint16_t newAddress;
uint8_t keypadMode; // 0=address, 1=CV number, 2=CV value
// UI element positions
Button btnPower;
Button btnMode;
Button btnRails;
Button btnDirection;
Button btnDccAddress;
// DCC function buttons (F0-F12)
#define NUM_FUNCTIONS 13
Button btnFunctions[NUM_FUNCTIONS];
// Programming mode buttons
Button btnProgramming;
Button btnProgBack;
Button btnFactoryReset;
Button btnSetAddress;
Button btnReadCV;
Button btnWriteCV;
// Numeric keypad (0-9, backspace, enter)
#define NUM_KEYPAD_BUTTONS 12
Button btnKeypad[NUM_KEYPAD_BUTTONS];
// Slider position and state
int16_t sliderX, sliderY, sliderW, sliderH;
int16_t sliderKnobX;
bool sliderPressed;
// Private methods
void drawUI();
void drawPowerButton();
void drawModeButton();
void drawRailsButton();
void drawDirectionButton();
void drawSpeedSlider();
void drawStatusBar();
void drawDccFunctions();
void drawDccAddressButton();
void drawProgrammingScreen();
void drawNumericKeypad();
void drawProgrammingStatus();
void handleTouch(int16_t x, int16_t y);
void updatePowerState(bool state);
void updateMode(bool isDCC);
void updateRailMode(bool is3Rail);
void updateDirection();
void updateSpeed(uint8_t newSpeed);
void toggleDccFunction(uint8_t function);
void enterProgrammingMode();
void exitProgrammingMode();
void handleKeypadPress(uint8_t key);
void performFactoryReset();
void performSetAddress();
void performReadCV();
void performWriteCV();
int16_t mapTouch(int16_t value, int16_t inMin, int16_t inMax, int16_t outMin, int16_t outMax);
};
#endif // TOUCHSCREEN_UI_H

View File

@@ -1,142 +0,0 @@
/**
* @file WebServer.h
* @brief Web server and REST API for remote control
*
* Provides web-based control interface with:
* - Responsive Bootstrap-based UI
* - RESTful API for control and configuration
* - LittleFS-based file serving
* - Real-time status updates
*
* @author Locomotive Test Bench Project
* @date 2025
*/
#ifndef WEB_SERVER_H
#define WEB_SERVER_H
#include <Arduino.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <ArduinoJson.h>
#include <DNSServer.h>
#include "Config.h"
#include "MotorController.h"
#include "DCCGenerator.h"
#include "LEDIndicator.h"
/**
* @class WebServerManager
* @brief Manages web server and API endpoints
*
* Serves web interface from LittleFS and provides REST API
* for controlling the locomotive test bench remotely.
*
* API Endpoints:
* - GET /api/status - Get current system status
* - POST /api/mode - Set control mode (analog/dcc)
* - POST /api/speed - Set speed and direction
* - POST /api/dcc/address - Set DCC address
* - POST /api/dcc/function - Control DCC functions
* - POST /api/wifi - Configure WiFi settings
*/
class WebServerManager {
public:
/**
* @brief Constructor
* @param cfg Pointer to Config object
* @param motor Pointer to MotorController
* @param dcc Pointer to DCCGenerator
* @param led Pointer to LEDIndicator
*/
WebServerManager(Config* cfg, MotorController* motor, DCCGenerator* dcc, LEDIndicator* led);
/**
* @brief Initialize web server
*
* Mounts LittleFS, sets up routes, and starts AsyncWebServer.
*/
void begin();
/**
* @brief Update web server (currently unused)
*
* AsyncWebServer handles requests asynchronously.
*/
void update();
private:
Config* config; ///< Configuration manager
MotorController* motorController; ///< Motor controller instance
DCCGenerator* dccGenerator; ///< DCC generator instance
LEDIndicator* ledIndicator; ///< LED indicator instance
AsyncWebServer server; ///< Async web server (port 80)
DNSServer dnsServer; ///< DNS server for captive portal
/**
* @brief Set up all HTTP routes and handlers
*/
void setupRoutes();
/**
* @brief Handle root page request
* @param request HTTP request object
*/
void handleRoot(AsyncWebServerRequest *request);
/**
* @brief Handle status request
* @param request HTTP request object
*/
void handleGetStatus(AsyncWebServerRequest *request);
/**
* @brief Handle mode change request
* @param request HTTP request object
*/
void handleSetMode(AsyncWebServerRequest *request);
/**
* @brief Handle speed setting request
* @param request HTTP request object
*/
void handleSetSpeed(AsyncWebServerRequest *request);
/**
* @brief Handle DCC function request
* @param request HTTP request object
*/
void handleSetFunction(AsyncWebServerRequest *request);
/**
* @brief Handle config retrieval request
* @param request HTTP request object
*/
void handleGetConfig(AsyncWebServerRequest *request);
/**
* @brief Handle WiFi configuration request
* @param request HTTP request object
*/
void handleSetWiFi(AsyncWebServerRequest *request);
/**
* @brief Handle restart request
* @param request HTTP request object
*/
void handleRestart(AsyncWebServerRequest *request);
/**
* @brief Get system status as JSON
* @return JSON string with status information
*/
String getStatusJSON();
/**
* @brief Get configuration as JSON
* @return JSON string with configuration
*/
String getConfigJSON();
};
#endif

View File

@@ -1,87 +0,0 @@
/**
* @file WiFiManager.h
* @brief WiFi connection management for AP and Client modes
*
* Handles WiFi connectivity in both Access Point and Client modes,
* with automatic reconnection support.
*
* @author Locomotive Test Bench Project
* @date 2025
*/
#ifndef WIFI_MANAGER_H
#define WIFI_MANAGER_H
#include <Arduino.h>
#include <WiFi.h>
#include "Config.h"
/**
* @class WiFiManager
* @brief Manages WiFi connectivity and modes
*
* Provides WiFi functionality in two modes:
* - Access Point (AP): Creates standalone network
* - Client (STA): Connects to existing WiFi network
*
* Features automatic reconnection in client mode.
*/
class WiFiManager {
public:
/**
* @brief Constructor
* @param cfg Pointer to Config object for WiFi settings
*/
WiFiManager(Config* cfg);
/**
* @brief Initialize WiFi based on configuration
*
* Sets up either AP or Client mode based on config settings.
* Called during system startup.
*/
void begin();
/**
* @brief Set up Access Point mode
*
* Creates a standalone WiFi network using configured
* SSID and password. Default IP: 192.168.4.1
*/
void setupAccessPoint();
/**
* @brief Connect to existing WiFi network
*
* Attempts to connect as client to configured network.
* Falls back to AP mode if connection fails after 10 seconds.
*/
void connectToWiFi();
/**
* @brief Check if WiFi is connected
* @return true if connected (or AP mode active), false otherwise
*/
bool isConnected();
/**
* @brief Get current IP address
* @return IP address as string (AP IP or STA IP)
*/
String getIPAddress();
/**
* @brief Update WiFi status and handle reconnection
*
* Should be called regularly from main loop.
* Handles automatic reconnection in client mode.
*/
void update();
private:
Config* config; ///< Pointer to configuration object
unsigned long lastReconnectAttempt; ///< Timestamp of last reconnect attempt
static const unsigned long RECONNECT_INTERVAL = 30000; ///< Reconnect interval (30 seconds)
};
#endif