edit readme

This commit is contained in:
pgdalmeida 2026-05-12 13:46:18 +02:00
parent e7301db427
commit 9c38c10300
Signed by: pedro.almeida
GPG Key ID: D4A6C394DF13F1D7
1 changed files with 187 additions and 109 deletions

View File

@ -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:** `<cmd>[y|p][d]<arg1>,<arg2>`
- 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 | `<position>, <speed>` |
| `;` | Overwrite XACTUAL register directly | `<value>` |
| `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 | `<sgt>` |
| `u` | Enter AUTO stepping mode | `<num_steps>` (must be > 2) |
| `h` | Save heading calibration to EEPROM | `0, <heading_value>` |
| `y` | Load heading calibration from EEPROM | `0` |
| `d` | Enter MANUAL mode | — |
| `p` | Advance yaw one step (AUTO mode) | — |
| `v` | Set yaw speed | `<vmax>` |
| `+` | Set yaw right limit to current position | — |
| `-` | Set yaw left limit to current position | — |
| `/` | Set both yaw limits manually | `<right>, <left>` |
| `?` | 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: <X_enc>, <X_act>, <X_err>, <dev_warn>, <sg_event>, <sg_status>, <sg_stop>
```
**Pitch:**
```
PITCH: <X_enc>, <X_act>, <X_err>, <dev_warn>, <sg_event>, <sg_status>, <sg_stop>, <endstop_l>, <endstop_r>
```
| 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