Initialisation depot
This commit is contained in:
226
ESP32/DCC-Bench/include/DCCGenerator.h
Normal file
226
ESP32/DCC-Bench/include/DCCGenerator.h
Normal file
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* @file DCCGenerator.h
|
||||
* @brief NMRA DCC (Digital Command Control) signal generator
|
||||
*
|
||||
* Generates DCC protocol signals for controlling digital model locomotives.
|
||||
* Implements NMRA DCC standard with support for:
|
||||
* - Short addresses (1-127) and long addresses (128-10239)
|
||||
* - 128-step speed control
|
||||
* - Function control (F0-F12 implemented, expandable to F28)
|
||||
*
|
||||
* @note Requires external DCC booster circuit for track output
|
||||
* @author Locomotive Test Bench Project
|
||||
* @date 2025
|
||||
*/
|
||||
|
||||
#ifndef DCC_GENERATOR_H
|
||||
#define DCC_GENERATOR_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// Pin definitions for DCC output
|
||||
// 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
|
||||
#define DCC_ONE_BIT_TOTAL_DURATION_MIN 55 ///< Min duration for '1' bit
|
||||
#define DCC_ZERO_BIT_TOTAL_DURATION_MAX 10000 ///< Max duration for '0' bit
|
||||
#define DCC_ZERO_BIT_TOTAL_DURATION_MIN 95 ///< Min duration for '0' bit
|
||||
|
||||
#define DCC_ONE_BIT_PULSE_DURATION 58 ///< Half-cycle for '1' bit (58μs)
|
||||
#define DCC_ZERO_BIT_PULSE_DURATION 100 ///< Half-cycle for '0' bit (100μs)
|
||||
|
||||
/**
|
||||
* @class DCCGenerator
|
||||
* @brief DCC protocol signal generator
|
||||
*
|
||||
* Generates NMRA-compliant DCC signals for digital locomotive control.
|
||||
* Supports variable speed, direction, and function commands.
|
||||
*
|
||||
* @warning Output signals are low-power logic level.
|
||||
* Requires external booster circuit for track connection.
|
||||
*/
|
||||
class DCCGenerator {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
DCCGenerator();
|
||||
|
||||
/**
|
||||
* @brief Initialize DCC generator hardware
|
||||
*
|
||||
* Configures output pins to idle state.
|
||||
*/
|
||||
void begin();
|
||||
|
||||
/**
|
||||
* @brief Enable DCC signal generation
|
||||
*
|
||||
* Starts sending DCC packets to the track.
|
||||
*/
|
||||
void enable();
|
||||
|
||||
/**
|
||||
* @brief Disable DCC signal generation
|
||||
*
|
||||
* Stops DCC output and sets pins to safe state.
|
||||
*/
|
||||
void disable();
|
||||
|
||||
/**
|
||||
* @brief Set locomotive speed and direction
|
||||
* @param address DCC address (1-10239)
|
||||
* @param speed Speed value (0-100%)
|
||||
* @param direction Direction: 0 = reverse, 1 = forward
|
||||
*/
|
||||
void setLocoSpeed(uint16_t address, uint8_t speed, uint8_t direction);
|
||||
|
||||
/**
|
||||
* @brief Control DCC function
|
||||
* @param address DCC address (1-10239)
|
||||
* @param function Function number (0-28)
|
||||
* @param state true = ON, false = OFF
|
||||
*/
|
||||
void setFunction(uint16_t address, uint8_t function, bool state);
|
||||
|
||||
/**
|
||||
* @brief Update DCC signal generation
|
||||
*
|
||||
* Must be called regularly from main loop to send DCC packets.
|
||||
* Sends speed and function packets at appropriate intervals.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* @brief Check if DCC is enabled
|
||||
* @return true if DCC mode is active
|
||||
*/
|
||||
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
|
||||
uint8_t currentSpeed; ///< Current speed setting
|
||||
uint8_t currentDirection; ///< Current direction (0=rev, 1=fwd)
|
||||
uint32_t functionStates; ///< Function states bit field
|
||||
|
||||
unsigned long lastPacketTime; ///< Timestamp of last packet sent
|
||||
static const unsigned long PACKET_INTERVAL = 30; ///< Packet interval (ms)
|
||||
|
||||
// DCC packet construction and transmission
|
||||
|
||||
/**
|
||||
* @brief Send a complete DCC packet
|
||||
* @param data Byte array containing packet data
|
||||
* @param length Number of bytes in packet
|
||||
*/
|
||||
void sendPacket(uint8_t* data, uint8_t length);
|
||||
|
||||
/**
|
||||
* @brief Send a single DCC bit
|
||||
* @param value true = '1' bit, false = '0' bit
|
||||
*/
|
||||
void sendBit(bool value);
|
||||
|
||||
/**
|
||||
* @brief Send DCC preamble (14 '1' bits)
|
||||
*/
|
||||
void sendPreamble();
|
||||
|
||||
/**
|
||||
* @brief Send a single byte
|
||||
* @param data Byte to send
|
||||
*/
|
||||
void sendByte(uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Send speed command packet
|
||||
*/
|
||||
void sendSpeedPacket();
|
||||
|
||||
/**
|
||||
* @brief Send function group packet
|
||||
* @param group Function group number
|
||||
*/
|
||||
void sendFunctionPacket(uint8_t group);
|
||||
|
||||
/**
|
||||
* @brief Calculate XOR checksum
|
||||
* @param data Data bytes
|
||||
* @param length Number of bytes
|
||||
* @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
|
||||
Reference in New Issue
Block a user