Drone

Public

@neilpate

Share Drone

Check access before sharing the link.

Who can open this board

Anyone can open this board. No sign-in is required.

This link opens the latest version. Copying it does not grant additional access.

Loading 3D model… large boards can take a moment.

README

Drone

CI

A learning project: build a quadcopter from scratch — own hardware, own firmware, no existing flight stack.

The drone is the artefact; understanding the whole stack end-to-end is the deliverable.

What we're building

  • Platform: BBC micro:bit v2 (nRF52833) for Phases 1–3; custom nRF5340 PCBA for Phases 4–5.
  • Language: Rust (no_std, embassy-nrf) on the firmware; Rust on the PC-side ground-station application too.
  • IMU: ICM-42688-P on SPI (external; micro:bit's onboard sensor has no gyro).
  • Airframe: quadcopter.
  • Flight stack: rolling our own — no PX4 / ArduPilot.

See doc/00-vision.md for the full vision and the phased milestone plan.

Status

Phase 2 (advanced prototyping) in progress. The whole stack runs on hardware. The drone has made first free flights — brief untethered, self-levelling hops on its own battery under closed-loop control — with telemetry over a two-hop radio link and PID gains tuned live from the ground station and now persisted to flash (ADR 0025): tune, save, power-cycle, and the gains survive.

  • Round trip, ~100 Hz, ~25–30 ms. The groundstation app sends four-axis pilot commands (sliders or a gamepad) over USB-CDC to a remote micro:bit, which relays to the drone over IEEE 802.15.4 (ADR 0014). Telemetry returns the same path as a high/low-rate split frame (ADR 0027), postcard + COBS framed, every buffer sized at compile time from the shared types.
  • Firmware — an Embassy task graph. A supervisor failsafe (ADR 0017) is the sole publisher of motor commands: a five-state machine with a stick arm/disarm gesture, idle auto-disarm, and loss-of-link detection within ~100 ms.
  • Sense → estimate → control. The ICM-42688-P IMU (ADR 0003) is read over SPI at 1 kHz; a complementary filter (ADR 0022) gives a roll/pitch estimate; a single-loop angle-mode PID (ADR 0024) mixes it and the pilot command into a four-motor demand. IMU zeroing is re-runnable from the ground station; every gain is a runtime message, saveable to flash.
  • Actuation + ESC telemetry. DShot300 drives a 4-in-1 AM32 ESC (parts list); each ESC's KISS serial telemetry — RPM, pack voltage, temperature — is read back over an idle-framed UART and logged.
  • Discipline. Frames, signs and command newtypes are fixed in ADR 0021; the pure logic (filter, controller, supervisor, wire types) is host-tested in firmware-drone-core.

The ground station plots and logs every signal live, times the round trip, pushes and saves PID gains, shows a live 3D view of the drone's attitude, and pairs with an offline analyze tool that turns a telemetry log into a legible flight report.

Recent tuning work — validating the integral term as a centre-of-mass trim corrector, balancing the airframe by the per-motor effort split, and re-zeroing out a one-directional drift — is consolidated into a new control-troubleshooting field guide (doc/06-control-troubleshooting.md).

Next (to finish Phase 2): rebuild on the lighter next-generation frame — the previous flight frame was retired in a lost-control crash — with the IMU mounted near the centre of mass (which should cut the estimator lag at its source) and a fresh, softer re-tune; plus a firmware power-limit mode and the netted test enclosure (doc/07-safety.md). In parallel, Phase 4 is well underway — the custom nRF5340 flight controller (drone_fc v2, ADR 0026, ADR 0028) is fully routed with turnkey PCBA fab exports out to PCBWay; the micro:bit stays the tuning platform meanwhile.

See doc/progress.md for the dated milestone history, doc/dev-environment.md for the toolchain, and doc/decisions/ for the full decision history.

Repository layout

  • AGENTS.md — shared context file for AI coding assistants (Copilot, Claude, etc.). Read first.
  • crates/ — Cargo workspace. firmware-drone-microbit (on-target binary), firmware-drone-shared (board-agnostic tasks/signals), firmware-drone-core (host-testable logic).
  • doc/ — design notes, vision, architecture, hardware/software/control docs.
  • doc/02-architecture.md — system architecture overview (two micro:bits, RF link, ground-station evolution).
  • doc/decisions/ — Architecture Decision Records (ADRs).
  • hardware/ — mechanical (Fusion 360) and electrical (KiCad).

Testing

Host-testable logic (wire types, the supervisor state machine, the ground-station helpers) is unit-tested and run with cargo-nextest:

cargo nextest run                                                 # workspace host crates
cargo nextest run --manifest-path crates/groundstation/Cargo.toml # the GUI crate

A tracked pre-push git hook runs the suite before every push, and GitHub Actions runs fmt + clippy + tests on every push and pull request (the badge above). On-target firmware is exercised on hardware, not in CI. See doc/ci-and-testing.md for the details and the one-time hook setup.

Decisions so far

  • ADR 0001 — Real-hardware quadcopter, roll our own firmware, learning-first scope.
  • ADR 0002 — BBC micro:bit v2 + Rust for Phases 1–3.
  • ADR 0003 — External IMU: ICM-42688-P on SPI.
  • ADR 0004 — Concurrency model: Embassy + channel-based actor pattern, no BSP.
  • ADR 0005 — PC-side software in Rust; shared proto crate for the wire protocol.
  • ADR 0006 — Mechanical CAD: Fusion 360; commit .f3d source + .stl mesh (STEP dropped, amended 2026-07-09).
  • ADR 0007 — Testing and CI: unit-test everything possible, local-first feedback, core/task split, HIL deferred.
  • ADR 0008 — Repository folder layout: crates/, doc/, hardware/{mechanical,electrical}/, all lowercase.
  • ADR 0009 — Workspace bootstrap from day one; firmware-<role> naming; core/task split realised as sibling crates.
  • ADR 0010 — Board Support Package layer: board module inside firmware-drone, Cargo-feature-selected, tasks take erased types.
  • ADR 0011 — Task tracking: GitHub Issues as canonical backlog, Projects board as view, labels as taxonomy, batched filing.
  • ADR 0012 — Lint and format policy: main stays rustfmt-clean and clippy-clean; suppressions require justification.
  • ADR 0013 — Async inter-task communication: 2×2 rule over Channel / Watch / Signal / PubSubChannel.
  • ADR 0014 — Radio link: IEEE 802.15.4 (raw PHY/MAC), channel 20.
  • ADR 0015 — Host-testable no_std crates: cfg_attr(not(test), no_std), inline mod tests, cargo test honours default-members.
  • ADR 0016 — Newtype per physical quantity for shared types: distinct newtypes per quantity, no shared PercentageValue base.
  • ADR 0017 — Supervisor task as failsafe state machine: 4-state enum, tick-driven, pure logic in firmware-drone-core, supervisor is the sole publisher of motor commands.
  • ADR 0018 — PC ground-station link: USB-CDC virtual COM port to nRF52833 UART, 115 200 8N1, postcard + COBS framing (Proposed; first cut shipped with plain ASCII).
  • ADR 0019 — Airframe and propulsion class: 3" ducted cinewhoop, 4S LiPo, 1507-class motors, DShot 4-in-1 ESC, fully 3D-printed PETG frame (Proposed).
  • ADR 0020 — Telemetry aggregator: a dedicated task is the sole publisher of TelemetryState, tick-sampling per-source Watches at 100 Hz and owning frame-level fields.
  • ADR 0021 — Coordinate frames and command semantics: world NED + body FRD, right-hand sign conventions, angle (self-levelling) mode first, remote sends raw normalised stick deflections (Proposed).
  • ADR 0022 — Attitude estimation: complementary filter for roll and pitch (fixed-gain accel/gyro blend); yaw stays rate-only; pure filter in firmware-drone-core (Proposed).
  • ADR 0023 — Motor numbering, layout, and rotation directions: quad-X, Betaflight numbering (M1 rear-right … M4 front-left), props-out rotation, with the derived mixer sign table (Proposed).
  • ADR 0024 — Control law: single-loop PD per axis, angle mode for roll/pitch and rate mode for yaw, derivative on the measured gyro; a single-publisher controller stage the supervisor mixes in Armed (Proposed).
  • ADR 0025 — Persist control parameters to flash: log-structured parameter store in internal flash, disarmed-gated save-on-command from the ground station (Accepted).
  • ADR 0026 — Phase 4 custom PCBA: nRF5340 module on a hand-designed KiCad carrier (Proposed).
  • ADR 0027 — Split telemetry into high-rate and low-rate frames: fast flight data + slower housekeeping (Proposed).
  • ADR 0028 — Fabricate the v2 flight-controller board: turnkey PCBA on PCBWay (Proposed).

Licence

Dual-licensed under either of:

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.

Comments

No comments yet. Be the first to ask about this board.

Ask about this board

Sign in to BoardRepo

New here? Signing in creates your account; there is no separate sign-up.