From 9c38c103001a3bc5489e5e48ce9ead1b28cf0efe Mon Sep 17 00:00:00 2001 From: pgdalmeida Date: Tue, 12 May 2026 13:46:18 +0200 Subject: [PATCH] edit readme --- firmware/README.md | 296 ++++++++++++++++++++++++++++----------------- 1 file changed, 187 insertions(+), 109 deletions(-) diff --git a/firmware/README.md b/firmware/README.md index f6b2fba..935c23d 100644 --- a/firmware/README.md +++ b/firmware/README.md @@ -1,136 +1,214 @@ -# Firmware +# FireWatchTower — 2-Axis Gimbal Controller -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. +Firmware for a 2-axis motorised gimbal (yaw + pitch) running on an Arduino-compatible AVR microcontroller. Built around the TMC5160 stepper driver chip, with encoder feedback, automatic homing, thermal management, and a serial command interface. -## PlatformIO Configuration +--- -Target: `leonardo` (ATmega32U4) at 115200 baud. +## Hardware -```bash -pio run --environment megaatmega2560 --target upload -``` +| Component | Details | +|---|---| +| MCU | ATmega32U4 (Arduino Leonardo-compatible) | +| Motor driver | TMC5160 × 2 (one per axis) | +| Communication | SPI @ 4 MHz, Mode 3 | +| Temperature sensor | DHT11 | +| Fan control | PWM output + tachometer input | -### Dependencies +### Pin assignments -| 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 | +| Pin | Function | +|---|---| +| 8 | TMC5160 CS — Yaw | +| 7 | TMC5160 EN — Yaw | +| 1 | TMC5160 CS — Pitch | +| 0 | TMC5160 EN — Pitch | +| 9 | DHT11 data | +| 10 | Fan PWM output | +| 11 | Fan tachometer input | -## Architecture +### Axis parameters + +| Parameter | Yaw | Pitch | +|---|---|---| +| Steps per revolution | 177,000 | 500,000 | +| Gear ratio | 739.56 | 739.56 | +| Default speed (VMAX) | 50,000 | 250,000 | +| Global current scaler | 80 | 50 | + +--- + +## Project structure ``` src/ -├── main.cpp # Entry point, main loop +├── main.cpp ├── config/ -│ ├── Constants.h # All tunable parameters -│ └── Pins.h # Pin assignments +│ ├── Constants.h — tuning values, thresholds, timing +│ └── 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 +│ ├── MotorConfig.h — axis IDs, EEPROM layout, gimbal_status enum +│ ├── MotorAxis.h/.cpp — per-axis state and TMC5160 register interface +│ ├── MotorDriver.h/.cpp— SPI init, register config, enable/disable +│ └── Homing.h/.cpp — homing state machines (non-blocking) ├── serial/ -│ └── CommandParser.* # Serial command dispatch -└── thermal/ - └── ThermalManager.* # DHT sensor + PWM fan control +│ └── CommandParser.h/.cpp — serial command protocol +├── thermal/ +│ └── ThermalManager.h/.cpp — DHT11 reading and fan PWM control +└── hal/ + └── SPI_HAL.cpp — TMC-API SPI callbacks (chip select per axis) ``` -## 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 | +## Building -## Motor Configuration +This project uses [PlatformIO](https://platformio.org/). -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; +**Build:** +```bash +pio run ``` -## 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 +**Build and upload:** +```bash +pio run --target upload ``` -## Thermal Management +**Clean:** +```bash +pio run --target clean +``` -DHT22 sensor on pin 9 drives a PWM fan on pin 10. +**Serial monitor:** +```bash +pio device monitor --baud 115200 +``` -| 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)` +## Axis lifecycle -## EEPROM Storage +Each axis progresses through the following states after power-on: -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 +``` +BOOT → RESET → ENC_INIT → INITIALIZED → AUTO / MANUAL + ↓ + ERROR (homing failed) +``` + +- **BOOT** — initial state, hardware not yet configured +- **RESET** — registers written, motor enabled, ready to home +- **ENC_INIT** — homing sequence in progress +- **INITIALIZED** — endstop limits known, axis ready for operation +- **AUTO** — stepping through positions automatically +- **MANUAL** — responding to direct move commands +- **ERROR** — homing failed; send `r` to reset and try again + +--- + +## Homing + +Each axis must be homed before normal operation. Send `q` over serial to start. + +**Yaw** uses stallGuard (encoder deviation detection) as a virtual endstop — the motor drives into a mechanical stop, the TMC5160 detects the current spike, and the position is recorded. No physical switches required. + +**Pitch** uses physical hardware endstop switches. The TMC5160 latches the position (XLATCH) the instant a switch triggers, giving an accurate limit reading. + +Once both limits are found, the axis validates the measured travel range and moves to the centre position. + +--- + +## Serial command protocol + +Connect at **115200 baud**. Commands are single characters sent over the serial port. + +**Format:** `[y|p][d],` + +- Axis specifier (optional): `y` = yaw only, `p` = pitch only, omit = both +- Base specifier (optional): `d` after axis = decimal arguments (default is hex) + +### Command reference + +| Command | Description | Arguments | +|---|---|---| +| `r` | Reset: re-init registers and enable coils | — | +| `q` | Start homing sequence | — | +| `!` | Disable motor coils (free-wheel) | — | +| `*` | Enable motor coils (holding torque) | — | +| `m` | Move to absolute position | `, ` | +| `;` | Overwrite XACTUAL register directly | `` | +| `s` | Stop (decelerate to zero) | — | +| `b` | Clear encoder deviation warning flag | — | +| `t` | Sync encoder to actual position | — | +| `e` | Clear stallGuard event flag (both axes) | — | +| `w` | Set stallGuard threshold | `` | +| `u` | Enter AUTO stepping mode | `` (must be > 2) | +| `h` | Save heading calibration to EEPROM | `0, ` | +| `y` | Load heading calibration from EEPROM | `0` | +| `d` | Enter MANUAL mode | — | +| `p` | Advance yaw one step (AUTO mode) | — | +| `v` | Set yaw speed | `` | +| `+` | Set yaw right limit to current position | — | +| `-` | Set yaw left limit to current position | — | +| `/` | Set both yaw limits manually | `, ` | +| `?` | Print current yaw endstop positions | — | + +### Examples + +``` +q — home both axes +qy — home yaw only +md 500000,35000 — move both axes to position 500000 at speed 35000 (decimal) +my 1F400,8888 — move yaw to 0x1F400 at speed 0x8888 (hex, default) +!p — disable pitch motor +w 60 — set stallGuard threshold to 60 on both axes +``` + +--- + +## Serial status output + +Every 250 ms the firmware prints a status line for each axis: + +**Yaw:** +``` +YAW: , , , , , , +``` + +**Pitch:** +``` +PITCH: , , , , , , , , +``` + +| Field | Description | +|---|---| +| `X_enc` | Encoder position (external encoder) | +| `X_act` | Step counter position (internal) | +| `X_err` | Tracking error (X_act − X_enc) | +| `dev_warn` | Encoder deviation warning flag | +| `sg_event` | StallGuard event flag | +| `sg_status` | StallGuard status bit | +| `sg_stop` | StallGuard stop flag | +| `endstop_l` | Left endstop state (pitch only) | +| `endstop_r` | Right endstop state (pitch only) | + +--- + +## Thermal management + +The DHT11 sensor is read every 250 ms. The fan PWM output is controlled proportionally: + +- Below 25 °C: fan off +- Above 25 °C: PWM = (temperature − 25) × 20, capped at 255 + +--- + +## Dependencies + +Managed automatically by PlatformIO: + +- `TMC-API` — Trinamic vendor library for TMC5160 register access +- `DHT sensor library` — Adafruit DHT11/22 driver +- `Adafruit Unified Sensor` +- `SPI` — Arduino built-in +- `EEPROM` — Arduino built-in \ No newline at end of file