This repository has been archived on 2026-06-17. You can view files and clone it, but cannot push or open issues or pull requests.
FireWatchTower_2axis/firmware/README.md

6.3 KiB
Raw Permalink Blame History

FireWatchTower — 2-Axis Gimbal Controller

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.


Hardware

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

Pin assignments

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

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
├── config/
│   ├── Constants.h       — tuning values, thresholds, timing
│   └── Pins.h            — pin assignments
├── motor/
│   ├── 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.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)

Building

This project uses PlatformIO.

Build:

pio run

Build and upload:

pio run --target upload

Clean:

pio run --target clean

Serial monitor:

pio device monitor --baud 115200

Axis lifecycle

Each axis progresses through the following states after power-on:

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