# Firmware Arduino sketch for the LattePanda's onboard ATmega32U4 (Leonardo). Controls two stepper motor axes via TMC5160 drivers, manages thermal regulation, and communicates with the host over the serial link. ## PlatformIO Configuration Target: `leonardo` (ATmega32U4) at 115200 baud. ```bash pio run --environment megaatmega2560 --target upload ``` ### Dependencies | Library | Version | Purpose | |---------|---------|---------| | adafruit/DHT sensor library | ^1.4.4 | DHT22 temperature/humidity readings | | adafruit/Adafruit Unified Sensor | ^1.1.4 | Unified sensor abstraction | | TMC5160 (bundled) | — | Stepper motor driver via SPI | ## Architecture ``` src/ ├── main.cpp # Entry point, main loop ├── config/ │ ├── Constants.h # All tunable parameters │ └── Pins.h # Pin assignments ├── motor/ │ ├── MotorConfig.h # Axis IDs, status enum │ ├── MotorDriver.* # TMC5160 initialization, power control │ ├── MotorAxis.* # Per-axis state, register reads, SGT/encoder handling │ └── Homing.* # Endstop homing routine ├── serial/ │ └── CommandParser.* # Serial command dispatch └── thermal/ └── ThermalManager.* # DHT sensor + PWM fan control ``` ## Pinout | Pin | Function | |-----|----------| | 0 | TMC5160 ENABLE (Pitch) | | 1 | TMC5160 CS (Pitch) | | 7 | TMC5160 ENABLE (Yaw) | | 8 | TMC5160 CS (Yaw) | | 9 | DHT22 DATA | | 10 | Fan PWM | | 11 | Fan sense | ## Motor Configuration Both axes use TMC5160 stepper drivers with closed-loop control. | Parameter | Yaw | Pitch | |-----------|-----|-------| | Steps/round | 177,000 | 500,000 | | Gear ratio | 739.556 | 739.556 | | Global scaler | 80 | 50 | | Default Vmax | 50,000 | 250,000 | | Endstop speed | 25,000 | 150,000 | Key constants in [config/Constants.h](src/config/Constants.h): - `ENC_DEVIATION_LIMIT` — Maximum allowed encoder-position deviation (1500 steps) - `ACCELERATION` — Default acceleration profile (20,000) ### Gimbal Status States ```c typedef enum { GIMBAL_STATUS_ERROR = -2, GIMBAL_STATUS_BOOT = -1, GIMBAL_STATUS_RESET = 0, GIMBAL_STATUS_ENC_INIT = 1, GIMBAL_STATUS_INITIALIZED= 2, GIMBAL_STATUS_AUTO = 3, GIMBAL_STATUS_MANUAL = 4 } gimbal_status; ``` ## Serial Protocol Commands are received character-by-character. A leading command character is followed by optional comma-separated numeric arguments (hex by default; append `d` for decimal). ### Command Reference | Command | Args | Description | |---------|------|-------------| | `r` | — | Reset motor params, power on both axes | | `q` | — | Run endstop homing on yaw then pitch | | `!` | — | Power off both motors | | `*` | — | Power on both motors | | `m` | pos, speed | Move yaw to position with given speed | | `s` | — | Stop both motors | | `b` | — | Reset encoder deviation warning flags | | `t` | — | Set Xenc to Xact (sync encoder to actual position) | | `e` | — | Reset SGT (step goal threshold) on both axes | | `w` | value | Set SGT value | | `u` | step_len | Set auto-scan step length (must be > 2) | | `h` | axis, hdg | Set heading calibration, save to EEPROM | | `y` | axis | Load heading calibration from EEPROM | | `d` | — | Set yaw to manual mode | | `p` | — | Step yaw to next position (used for scan trigger) | | `v` | speed | Set yaw Vmax | | `+` | — | Record right encoder position | | `-` | — | Record left encoder position | | `/` | right, left | Set right and left encoder positions | | `?` | — | Print encoder range info | | `;` | value | Write raw value to Yaw register 0x21 | ### Telemetry Output Every `INFO_PRINT_INTERVAL_MS` (250 ms), both axes print status lines prefixed with `$`: ``` $Xenc;Xerr;sgt_val;sgt_stat;is_moving;control_status;hdg;deviation_warn;humid;temp;fan_pwm ``` ## Thermal Management DHT22 sensor on pin 9 drives a PWM fan on pin 10. | Parameter | Value | Description | |-----------|-------|-------------| | `THERMAL_FAN_ON_TEMP` | 25°C | Fan activation threshold | | `THERMAL_FAN_GAIN` | 20 | PWM gain per degree above threshold | | `THERMAL_FAN_MAX_PWM` | 255 | Maximum PWM duty cycle | | `THERMAL_LOOP_INTERVAL` | 250 ms | Sensor read interval | Fan PWM = `min(255, (temp - 25) * 20)` ## EEPROM Storage Heading calibration data is stored at EEPROM address 0: - Offset 0: `float` — current heading (`c_hdg`) - Offset 4: `int32_t` — encoder distance offset from heading reference