Safeguard
Supply Chain Security•

How a Drone Is Made: Flight Controller, ESCs, Motors, GNSS and Remote ID

A drone is a frame, brushless motors, ESCs, a flight controller, GNSS, radios, a lithium pack and firmware. Here is each build step and what to secure.

Safeguard Security Team
51 min read

A multirotor drone is made by mounting brushless motors and propellers on a carbon fibre or moulded frame, wiring each motor to an electronic speed controller (ESC), and connecting the ESCs to a flight controller board that carries a microcontroller, an inertial measurement unit, a barometer and a magnetometer. A GNSS receiver, a radio link, a camera or payload, a lithium battery pack and, in the United States, a Remote ID broadcast complete the aircraft. Firmware ties it together: an autopilot stack such as PX4 or ArduPilot runs the control loops, talks MAVLink to a ground station, and is the part you build, verify, sign and update like any other software.

This post goes one level deeper than our live drone posts. For what the broadcast contains and who has to comply, see Drone Remote ID explained. For what the autopilot does when the link, GPS or battery fails, see PX4 failsafes explained. Fleet operators should keep the drone fleet software security checklist open alongside this one, and anyone planning longer missions should read whether you can fly beyond visual line of sight today. The cell chemistry behind the battery is covered in how lithium ion batteries are made and the board itself in how a printed circuit board is made.

Drone makers keep their bills of materials, yields and factory test scripts private. Where we describe an open source project, we use that project's own documentation. Where we describe the law, we quote the regulation. We do not invent factory numbers.

Key takeaways

  • A multirotor has eight subsystems: frame, propulsion (motors, propellers, ESCs), flight controller with its sensors, navigation (GNSS and compass), radio links, payload (camera and gimbal), power (battery and power module), and identification (Remote ID).
  • ESCs turn a throttle command into three phase current for a brushless motor. PX4 supports PWM, OneShot, DShot and DroneCAN ESCs. DShot is digital, carries a checksum, needs no throttle range calibration, and comes in DShot150, DShot300 and DShot600, where the number is the bit rate in kilobits per second.
  • The flight controller is an STM32H7 or i.MX RT class microcontroller on most current open hardware, running PX4 on the NuttX real time operating system or ArduPilot, often with a Linux companion computer for vision and networking.
  • Firmware can be locked to your own keys. ArduPilot documents a secure bootloader that holds up to 10 public keys and refuses unsigned firmware. Get the procedure wrong and the board can be rendered inoperative, so practise on a spare.
  • MAVLink 2 message signing adds a 13 byte signature (link ID, 48 bit timestamp, 48 bit truncated SHA-256) and gives authentication and replay protection. It does not encrypt anything, and PX4 always accepts four safety messages unsigned.
  • In the US, 14 CFR Part 89 says that after 16 September 2023 no one may fly a drone that needs Remote ID unless it is a standard Remote ID drone, carries a broadcast module, or flies inside an FAA Recognized Identification Area. Production rules applied after 16 September 2022.
  • Flight batteries are lithium polymer or lithium ion packs described by cell count (S) and a maker's C rating. Lithium cells must be a type proven against UN Manual of Tests and Criteria section 38.3 before they can be shipped, and US air passengers face 100 Wh and 160 Wh thresholds.
  • Safeguard does not inspect airframes, ESC firmware images or flight controller boards. Its fit is the software around the drone: the autopilot repository you fork, the companion computer image, and the ground station and fleet services your team writes.

From raw material to a flight-ready drone: the step table

This table is the map for the rest of the post. Order varies by maker, and consumer drones fold several rows into one sealed assembly line. Each row names the check, not a yield, because no maker we found publishes yields.

StepInputWhat happensTest or certification at this stageFirmware or keys involved
1. MaterialsCarbon fibre sheet or tube, glass filled nylon, aluminium, copper wire, neodymium magnets, electrical steel laminations, FR4 laminate, lithium cellsPurchased against specificationsIncoming inspection, certificates of conformance, UN 38.3 test summary for cellsNone
2. FrameCarbon plate, tubes, moulded armsCNC routing or moulding, then bonding and fasteningDimensional check, arm stiffness and resonance checks where the maker does themNone
3. MotorsStator laminations, enamelled copper, magnets, bell, shaft, bearingsStator stacked and coated, teeth wound, magnets bonded into the bell, rotor balancedWinding resistance, insulation (hipot), KV and no-load current, vibration after balancingNone
4. PropellersGlass or carbon filled polymer, or carbon compositeInjection moulding or layup, then balancingStatic and dynamic balance, visual inspection for voidsNone
5. ESC boardsPCB, MOSFETs, gate drivers, microcontroller, current senseSMT assembly and reflow, then firmware flashingBoard test, flash verify, spin test on a reference motorESC firmware (for example AM32 or a maker's own)
6. Flight controllerMultilayer PCB, MCU, IMUs, barometer, magnetometer, power regulatorsSMT assembly, IMU mounting on an isolated sub board where designed, conformal coating where specifiedElectrical test, bootloader flash, sensor self test, factory temperature calibration of IMUsBootloader, optionally with signing keys
7. GNSS and compassGNSS module, patch antenna, magnetometerAssembled on a mast module away from current carrying wiresSatellite acquisition test, compass calibrationGNSS receiver firmware
8. Radios and Remote IDRC receiver, telemetry radio or IP link, Remote ID transmitterIntegrated, antennas routedRadio pairing, range check, FCC Part 15 conformity for the radio, Remote ID self testRadio firmware, Remote ID serial number
9. PayloadCamera, gimbal, gimbal controllerMounted and balancedGimbal calibration, image testCamera and gimbal firmware
10. Battery packCells, nickel strip or tabs, balance leads, BMS or smart battery board, caseCells matched, welded, wrappedCell matching, internal resistance, charge and discharge cycle, transport classificationSmart battery firmware where present
11. IntegrationAll of the aboveWiring harness, power module, final assemblyContinuity, power on, sensor health, motor order and direction with props offAutopilot firmware flashed and versioned
12. CalibrationAssembled aircraftAccelerometer, gyro, compass, radio and ESC setupCalibration reports from the autopilotParameters stored on the flight controller
13. Flight testCalibrated aircraftHover, attitude and position tests, failsafe triggersVibration and log review, Remote ID broadcast checked on a receiverLogs saved with firmware hash
14. ReleaseTested aircraftSerial numbers recorded, registration data, packagingFAA-accepted Remote ID Declaration of Compliance covering the drone or module serial numbers, battery shipping marksFirmware version and signing key ID recorded

What an open source build shows about step 11 to 13

Open projects document the integration and calibration steps that commercial lines keep private. PX4 documents onboard and offboard thermal calibration of the accelerometer, gyro, magnetometer and barometer, ideally in an environmental chamber as the board warms from its lowest to highest calibration temperature, and notes that many common boards can be heated to about 70 °C with a simple setup. ArduPilot documents IMU temperature calibration in which the autopilot is cold soaked and then warmed on the next boot. A factory does the same thing at scale with thermal chambers and fixtures; a hobby builder does it with a freezer and patience.

A dated timeline of drone rules and open source milestones

Dates below were checked against the primary source listed in Sources.

DateEventSource
1 January 2008Lithium cells and batteries manufactured on or after this date need a manufacturer test summary under 49 CFR 173.185eCFR via LII
1 January 2015Epoch for the MAVLink 2 signing timestamp (10 microsecond units since this date)MAVLink Developer Guide
15 January 2021FAA final rule "Remote Identification of Unmanned Aircraft" published at 86 FR 4390Federal Register
10 March 2021FAA delays the rule's 16 March 2021 effective date to 21 April 2021 (86 FR 13629)Federal Register
12 September 2022FAA enforcement policy: for production noncompliance on or before 16 December 2022, the FAA will consider all circumstances before enforcing (87 FR 55685)Federal Register
16 September 2022After this date, producers may not produce drones for US operation unless they meet the Remote ID production rules (14 CFR 89.510 and 89.515)14 CFR Part 89
16 September 2023After this date, no person may operate a drone in US airspace unless the operation meets 14 CFR 89.110 or 89.115, unless otherwise authorized14 CFR 89.105
15 September 2023FAA enforcement policy: for operator noncompliance on or before 16 March 2024, the FAA will consider all circumstances, including module supply and cost and FRIA approval delays (88 FR 63518)Federal Register
PX4 v1.14Remote ID (Open Drone ID over MAVLink) support appears in PX4, marked experimentalPX4 User Guide
PX4 v1.16Bidirectional DShot (eRPM telemetry on the signal wire) documented for PX4PX4 User Guide
13 May 2026PX4 v1.17.0 stable release publishedPX4 GitHub releases
14 October 2026ArduPilot Copter-4.7.2 release tag publishedArduPilot GitHub releases

What is inside a multirotor drone?

A quadcopter has no control surfaces. It flies by changing the speed of each rotor hundreds of times per second. Everything inside exists to measure attitude and position, decide what each motor should do, and deliver that power.

SubsystemPartsWhat it doesTypical failure that matters
FrameArms, centre plates, landing gear, standoffsHolds everything at fixed geometry; sets resonant frequenciesLoose arms or flexing plates inject vibration into the IMU
PropulsionBrushless outrunner motors, propellersConverts electrical power to thrustBearing wear or a chipped prop raises vibration and current
ESCsMOSFET bridges, gate drivers, MCUCommutates the motor at the commanded speedOverheating, desync on a sudden throttle change
Flight controllerMCU, IMU (accelerometer and gyro), barometer, often a magnetometer, logging storageRuns estimation and control; logs everythingVibration, temperature drift, brownout
NavigationGNSS receiver and antenna, external compassProvides position, velocity, time and headingMagnetic interference, poor sky view, loss of fix
Radio linksRC receiver, telemetry radio, sometimes LTE or IP meshPilot commands, MAVLink telemetry, videoLink loss, which triggers a failsafe
PayloadCamera, gimbal, sprayer, sensorThe job the drone exists to doPayload software talking to the autopilot unauthenticated
PowerBattery pack, power module or smart battery, BEC regulatorsSupplies the motors and avionics; measures voltage and currentVoltage sag under load, cell imbalance, swelling
IdentificationBuilt in Remote ID or a broadcast moduleBroadcasts identity and location as US rules requireSelf test failure blocks take off on a standard Remote ID drone

Consumer, enterprise and hobby builds

The same eight subsystems show up in every class. What changes is who integrates them and who controls the firmware.

AspectConsumer camera droneEnterprise or industrial droneHobby or open source build
IntegrationOne maker designs everything; sealed bodyOne maker or an integrator; modular payload baysThe builder buys frame, motors, ESCs, flight controller and radios separately
Flight softwareClosed firmware, updated through the maker's appOften an open source autopilot underneath, or a closed one with an SDKPX4, ArduPilot or a racing firmware chosen by the builder
ESC protocolInternal, usually not exposedDShot or CAN bus (DroneCAN) commonDShot on most current builds; PWM on older ones
BatteriesSmart packs with a fuel gauge and their own firmwareSmart packs, sometimes hot swappablePlain LiPo or Li-ion packs with balance leads
Remote IDUsually standard Remote ID built inStandard Remote ID built in or integrated moduleBroadcast module, standard Remote ID through a declared product, or flight inside a FRIA
Update controlMaker pushes updates; user acceptsOperator often pins versions and tests before rolloutBuilder decides entirely; easy to fall behind
Main software riskTrusting a vendor app and cloudFleet tools, companion computers and integrationsUnpinned forks, unsigned links, outdated firmware

The table is a description of categories, not a ranking. A hobby build can be more transparent than a consumer drone because every line of the autopilot is public; it can also be far less maintained.

How is a flight controller board designed and made?

The flight controller is a small, dense embedded computer. It has to sample inertial sensors at kilohertz rates, run an estimator and several nested control loops, write logs, and keep doing all of that while the motors shake it.

Choosing the MCU or SoC

Current open hardware for PX4 and ArduPilot clusters around a few microcontroller families. PX4's documentation for bidirectional DShot lists STM32H7 and NXP i.MX RT (the V6X-RT and Tropic boards) as supported processors, because the feature needs DMA capable timers. The Pixhawk open hardware standards, maintained publicly on GitHub, define reference designs and connector layouts so that boards from different makers accept the same peripherals. A designer chooses the MCU on four things: floating point throughput for the estimator, enough timers with DMA for motor outputs, memory for logging and features, and long term availability, since a flight controller design may be built for many years.

Larger enterprise drones add an application processor running Linux. PX4's architecture documentation describes this split: the flight controller runs the real time flight stack, and a companion computer handles computer vision, networking and mission logic, linked to the flight controller over MAVLink or over the uXRCE-DDS bridge to ROS 2.

Sensors and sensor fusion

The core sensor set is an IMU (three axis accelerometer and three axis gyroscope), a barometer for altitude change, and a magnetometer for heading. Many boards carry two or three IMUs of different models so that a fault or vibration issue in one can be detected by comparing them. GNSS adds absolute position and velocity. The autopilot's state estimator fuses all of this into attitude, velocity and position estimates, and rejects sensors that disagree with the rest.

Two physical effects dominate the design:

  • Vibration. PX4's documentation says boards with built in accelerometers or gyros are sensitive to vibration, and that high vibration reduces flight performance and flight time and increases wear. In extreme cases it can cause loss of control. ArduPilot's vibration damping page explains the goal: reduce high and medium frequency vibration while still letting the board follow the real, low frequency motion of the airframe. That is why many boards mount the IMU on a separately suspended sub board, and why builders mount the whole controller on foam or gel.
  • Temperature. MEMS sensor bias drifts with temperature. PX4 stores thermal compensation in TC_* parameters, and ArduPilot stores IMU temperature calibration in its own parameters. Some boards also heat the IMU to a fixed temperature so the bias stays put.

SMT assembly, calibration and test

Board assembly follows the normal surface mount flow covered in our PCB post: solder paste printing, pick and place, reflow, automated optical inspection, and X-ray for leadless packages. After that come the steps specific to a flight controller:

  1. Bootloader flash. A bootloader is written over the SWD debug port. PX4's bootloader documentation shows this route with a debug probe and also a parameter driven route (SYS_BL_UPDATE) for updating the bootloader from running firmware on Pixhawk series boards.
  2. Sensor self test. The firmware reads each sensor's identity register and checks it is present and in range.
  3. Factory temperature calibration. Boards are cycled through a temperature range and the bias curve is stored. PX4 and ArduPilot both document this as an optional, often factory, step.
  4. Functional test. Outputs are toggled, the power monitor is checked against a reference load, and logging is verified.
  5. Conformal coating where the design specifies it, after test, with connectors masked.

The output of this stage is a board with a known bootloader, known sensor calibration and a serial number that will later be recorded against the aircraft.

What do ESCs do, and how are brushless motors made?

ESCs: from throttle command to three phase current

A brushless DC motor has no brushes to switch current between windings, so an ESC does it electronically. It drives three half bridges of MOSFETs, energising the stator windings in sequence so that the magnetic field leads the rotor's magnets. Two families of control are common:

  • Trapezoidal (six step) commutation. Two phases are driven at a time and the third is watched for back EMF to know where the rotor is. Most small multirotor ESC firmware works this way because it is simple and fast.
  • Field oriented control (FOC). The ESC measures phase currents, transforms them into a rotating reference frame aligned with the rotor, and controls torque producing current directly with sinusoidal drive. It is smoother and quieter, at the cost of more computation and current sensing, and it is more common on larger motors and CAN connected ESCs.

The command from the flight controller travels over one of several protocols. PX4 lists PWM, OneShot, DShot, DroneCAN, PCA9685 over I2C, and some UART ESCs.

ProtocolSignal typeCalibration neededTelemetryNotes from project docs
PWMAnalogue pulse width, classically 1000 to 2000 microsecondsYes, ESC throttle range calibrationNo (separate wire on some ESCs)Universal and slow
OneShotShorter analogue pulsesYesNoLower latency than PWM
DShot150, DShot300, DShot600Digital frames with a checksum; number is kbit/sNoOptional serial telemetry wirePX4: reduced latency, a checksum that catches corrupted frames, no calibration, spin direction by command
Bidirectional DShotDigital, ESC answers on the same wireNoeRPM on the signal wire; with Extended DShot Telemetry also temperature, voltage and currentPX4 v1.16 and later; needs DMA capable timers
DroneCANCAN bus messagesNoRich telemetryUsed on larger and enterprise aircraft; each ESC is a node on the bus

ArduPilot's DShot page adds practical advice on rates: it recommends DShot150 for larger aircraft with long signal leads, because lower rates are less susceptible to noise, and notes that DShot600 is by far the most widely used on smaller craft. PX4's DShot page also says what DShot telemetry contains: temperature, voltage, current, accumulated current consumption and RPM. That data is what lets the autopilot run dynamic notch filters that track motor noise. ESC firmware is its own software supply chain. AM32, for example, is open source firmware for STM32 based ESCs; its README lists DShot300 and DShot600, bidirectional DShot, KISS standard telemetry and firmware upgrades through a flight controller passthrough or a single wire serial link.

Worked example: turning eRPM into motor RPM

The ESC reports electrical RPM. One electrical revolution happens per pole pair, so mechanical RPM is eRPM divided by half the pole count. PX4's default for its DSHOT_MOT_POL parameters is 14 poles, typical for 5 inch propeller motors, which is 7 pole pairs.

  • Reported eRPM: 168,000
  • Pole pairs: 14 ÷ 2 = 7
  • Mechanical RPM: 168,000 ÷ 7 = 24,000 RPM
  • Rotation frequency: 24,000 ÷ 60 = 400 Hz

That 400 Hz is the fundamental the notch filter should follow. If the pole count parameter is wrong, say left at 14 on a 12 pole motor, the autopilot would compute 168,000 ÷ 7 = 24,000 RPM instead of the true 168,000 ÷ 6 = 28,000 RPM, and the notch would sit about 67 Hz below the real noise. PX4's DShot page warns that pole count must be set correctly, and on AM32 ESCs also in the AM32 configuration.

How brushless motors are wound and balanced

Small drone motors are outrunners: the stator with its copper windings sits in the middle, and a bell carrying permanent magnets spins around it. The build steps are:

  1. Stator stack. Thin laminations of electrical steel are stamped, insulated from each other to limit eddy currents, stacked and bonded, then coated with an insulating layer so the winding cannot short to the steel.
  2. Winding. Enamelled copper wire is wound around each stator tooth in a pattern that forms three phases, usually by machine. The number of turns sets the motor's KV (RPM per volt with no load): fewer turns of thicker wire give higher KV and higher current; more turns give lower KV and more torque per amp. The phases are terminated in a star (wye) or delta connection.
  3. Magnets and bell. Curved neodymium magnets are bonded into the bell with alternating polarity. Their count sets the pole count the ESC firmware needs to know.
  4. Shaft and bearings. The shaft is pressed into the bell, bearings into the base, and a retaining clip fitted.
  5. Balancing. The rotor is spun on a balancing machine and material is removed or small weights added until vibration is within the maker's limit. Propellers get the same treatment separately.
  6. Test. Phase resistance, insulation resistance at high voltage, and a run test that measures KV and no-load current.

Worked example: what KV tells you

KV is defined as no-load RPM per volt. A 2,300 KV motor on a 4S pack at the nominal 3.7 V per cell sees about 14.8 V:

  • No-load RPM ≈ 2,300 × 14.8 = 34,040 RPM

Under a propeller the motor runs slower because of load and voltage sag. A 900 KV motor on a 6S pack (22.2 V nominal) gives about 900 × 22.2 = 19,980 RPM unloaded and swings a larger propeller. Neither number is a performance promise; it is a way to match motor, propeller and battery so the ESC and pack are not pushed past their current limits.

How do GNSS and the compass fit in?

GNSS gives the autopilot position, velocity and a precise time source. Receivers on drones typically track several constellations at once. For centimetre level work, an RTK setup adds a base station or correction service. The compass gives heading at hover, when velocity alone cannot tell the estimator which way the aircraft is pointing.

Placement matters more than model choice. Builders and makers put the GNSS and compass on a mast, away from the power distribution and ESC wiring, because current flowing in those wires bends the local magnetic field. Both PX4 and ArduPilot run compass calibration routines and check for interference that changes with throttle. On larger aircraft the GNSS module is a DroneCAN node, which lets one cable carry GNSS, compass, a status LED and sometimes a safety switch.

GNSS also feeds Remote ID. Part 89 sets accuracy requirements for the broadcast position of a standard Remote ID drone: within 100 feet of the true position and, for the aircraft, altitude within 150 feet, each with 95 percent probability, and the position must be broadcast no later than 1.0 second after it was measured. Loss of GNSS is also one of the failsafes our PX4 failsafes post covers. The defensive point for builders is simple: test what your aircraft does when the fix degrades, on the bench in simulation and in the field at low altitude, before you rely on it.

What firmware runs on a drone?

A drone runs several separate pieces of firmware, each with its own update path.

ComponentTypical softwareWhere it comes fromHow it is updated
Flight controllerPX4 on NuttX, ArduPilot, or a maker's closed stackOpen source repository or the makerGround station over USB or MAVLink; bootloader on the board
Flight controller bootloaderProject bootloaderSame projectDebug probe at the factory, or a parameter triggered update
ESCsAM32, other open ESC firmware, or the maker's ownESC project or makerPassthrough through the flight controller, or a direct serial link
GNSS receiverReceiver vendor firmwareModule makerVendor tool, rarely done in the field
RadiosTelemetry radio and RC link firmwareRadio maker or open projectConfigurator tools
Remote IDTransmitter firmwareModule or drone makerMaker's tool; tied to the Declaration of Compliance
Companion computerLinux distribution, ROS 2, vision code, containersYour team and upstream distributionsPackage manager, image rebuilds, containers
Ground stationDesktop or tablet applicationOpen source project or makerApp store or installer

PX4

PX4 is one of the projects of the Dronecode Foundation, a Linux Foundation collaborative project whose project list also includes Pixhawk, MAVLink, QGroundControl and MAVSDK. PX4 runs on NuttX, an Apache project whose documentation describes it as a real time OS scalable from 8 bit to 64 bit microcontrollers and governed primarily by POSIX and ANSI standards. Inside PX4, modules talk to each other over a publish and subscribe bus called uORB, and the MAVLink module connects the vehicle to ground stations and companion computers. Builds are named by target and configuration: make px4_fmu-v5_default builds the default configuration for the FMUv5 hardware family, and the output is a .px4 file. PX4's documentation listed v1.17 as stable and v1.18 as beta when we checked, and the v1.17.0 GitHub release was published on 13 May 2026.

ArduPilot

ArduPilot covers copters, planes, rovers and subs from one codebase built with the waf build system: ./waf configure --board BOARDNAME followed by ./waf copter. Its build documentation tells you to clone with --recurse-submodules and never to run waf with sudo. ArduPilot's latest Copter tag when we checked was Copter-4.7.2, published 14 October 2026.

Bootloaders and signed firmware

Both projects ship a bootloader that accepts new firmware over USB. Who may load firmware is the security question.

ArduPilot documents a secure boot option intended for vendors who need strong tamper resistance, including for Remote ID. The bootloader holds up to 10 public keys and refuses to boot firmware whose signature does not match one of them. Keys are generated with a script in Tools/scripts/signing, the bootloader is rebuilt with --signing-key, the firmware is configured with --signed-fw and signed with make_secure_fw.py. By default the secure bootloader also carries the three ArduPilot project keys, so the core team can help users who make mistakes, unless you build with --omit-ardupilot-keys. A secure bootloader announces itself with a USB product string containing "Secure". ArduPilot warns that the board can be rendered inoperative if the procedure is not followed exactly.

PX4's security hardening guide covers a different layer: it points out that debug ports (SWD and JTAG), if exposed, allow full firmware reflash and bypass all software security. For a production aircraft that means the physical design (sealing or disabling debug access) is part of firmware security, whichever autopilot you use.

Companion computers

A Linux companion computer is where most of a modern drone's third party code lives: a distribution, Python and C++ libraries, ROS 2 packages, vision models, container images and a connection to a fleet back end. This is ordinary software supply chain territory. It gets the same treatment as a server: pin versions, keep an SBOM, rebuild images when dependencies change, and limit what the companion can send to the autopilot.

How does MAVLink connect a drone to a ground station?

MAVLink is a lightweight binary messaging protocol. Each packet carries a system ID and component ID, a message ID, a payload and a checksum. A ground station, the autopilot, a companion computer, a camera and a gimbal are all MAVLink components. The protocol defines microservices on top of messages: heartbeat, parameters, missions, commands, file transfer, camera and gimbal control, and Open Drone ID.

MAVLink 2 added extensions such as larger message ID space and, importantly, message signing.

What MAVLink 2 signing protects

From the MAVLink Developer Guide:

  • A signed packet sets bit 0x01 of the incompatibility flags and appends 13 bytes: an 8 bit link ID, a 48 bit timestamp in 10 microsecond units since 1 January 2015, and a 48 bit signature.
  • The signature is the first 48 bits of SHA-256 over the 32 byte secret key followed by the header, payload, CRC, link ID and timestamp.
  • Receivers reject a signed packet if its timestamp is older than the previous one on the same logical stream (system ID, component ID, link ID), if the signature does not match, or if the timestamp is more than one minute behind local time.
  • A library that does not understand signing must drop signed packets, because the flag is an incompatibility flag.
  • The key is shared with the SETUP_SIGNING message, which should only be sent over a secure link such as USB or wired Ethernet, never broadcast, never forwarded, and omitted from logs.

So signing gives authentication, integrity and replay protection. It does not give confidentiality.

How PX4 and ArduPilot implement it

The two projects differ in ways that matter for a deployment.

AspectPX4 (per PX4 User Guide)ArduPilot (per Mission Planner docs)
Where the key lives/mavlink/mavlink-signing-key.bin on the SD card, not a parameterStored by the autopilot; managed from Mission Planner or another GCS
USBSigned messages required on all links, including USB, once a key existsUSB connections are unaffected, so a user can always erase or change the key over USB
Unsigned exceptionsHEARTBEAT, RADIO_STATUS, ADSB_VEHICLE and COLLISION always acceptedLinks still receive telemetry without signing; commands need the key
Changing the keySETUP_SIGNING signed with the current key; rejected while armedThrough the GCS signing dialog over a connection
Lost keyRemove the SD card and delete the key file, or reflash over SWD; no software only recoveryUse USB, which ignores signing
EncryptionNone; PX4 states that messages are still plaintextNone; the docs state that signing does not encrypt the data

PX4's documentation is unusually candid about the limits. Its list of what signing does not protect against includes eavesdropping, extraction of the key from the SD card, spoofed messages from the unsigned allowlist, and in-flight key changes (which are blocked by design). Its hardening guide adds one more: until a key is provisioned there is nothing to authenticate against, so any peer that can reach a link can provision the first key. The defensive fix is to provision your key early, over USB, before the aircraft is ever on a shared radio network. PX4 also notes that if the link is carried over an encrypted radio, a VPN or IPsec, that layer gives confidentiality and authentication for everything on it.

The key is symmetric. Every device that holds it can sign as any system and component, so signing proves "a device with the key sent this", not "the ground station sent this". Keep the number of holders small.

What does FAA Remote ID require, and what does a drone broadcast?

Remote ID is covered in depth in our Remote ID explainer. Here is the build side: what a maker must design in.

The three ways to comply

14 CFR 89.105 says that after 16 September 2023, except as otherwise authorized or as provided in 89.120, no person may operate an unmanned aircraft in US airspace unless the operation meets 89.110 or 89.115. The FAA's Remote ID page summarises the options for drone pilots:

  1. Fly a standard Remote ID drone, built with Remote ID broadcast capability, which broadcasts identification and location of both the drone and the control station.
  2. Fit a Remote ID broadcast module, which broadcasts identification and location of the drone and its take off location. Pilots using a module must be able to see the drone at all times.
  3. Fly inside an FAA Recognized Identification Area (FRIA), within visual line of sight, without Remote ID equipment.

Registration ties the hardware to a person: the FAA page says recreational flyers list each standard Remote ID drone or module serial number in their inventory, and Part 107 pilots register each device separately. The FAA also runs a Declaration of Compliance system where you can check whether a drone or module is FAA accepted.

What a standard Remote ID drone broadcasts

14 CFR 89.305 lists the minimum message elements:

ElementStandard Remote ID drone (89.305)Broadcast module (89.315)
IdentitySerial number assigned by the producer, or a session IDSerial number of the module
Aircraft latitude and longitudeYesYes
Aircraft geometric altitudeYesYes
Aircraft velocityYesYes
Control station latitude, longitude and geometric altitudeYesNo
Take off location latitude, longitude and geometric altitudeNoYes
UTC time markYesYes
Emergency statusYesNo

The FAA page adds that in the future, operators of standard Remote ID drones may be able to choose between broadcasting the serial number or a session ID.

Design requirements a maker must meet

89.310 turns the broadcast into engineering requirements. The ones that shape a build:

  • Self test and monitoring. Before take off the aircraft must test Remote ID automatically and tell the pilot the result. It must not be able to take off if Remote ID is not functional, and it must monitor Remote ID from take off to shutdown and warn the pilot of a malfunction.
  • Tamper resistance. The aircraft must be designed and produced to reduce a person's ability to tamper with Remote ID. This is one reason ArduPilot's secure boot exists.
  • Error correction in the broadcast.
  • Broadcast over a non-proprietary specification on spectrum compatible with personal wireless devices under 47 CFR Part 15, at a rate of at least one message per second.
  • Accuracy: position within 100 feet; control station altitude within 15 feet; aircraft altitude within 150 feet; each at 95 percent probability; latency no more than 1.0 second.
  • Serial numbers that comply with ANSI/CTA-2063 (89.505).

The industry consensus standard most products declare against is ASTM F3411, the Standard Specification for Remote ID and Tracking (current edition F3411-22a on ASTM's site). MAVLink's Open Drone ID page maps the ASTM messages to MAVLink messages (Basic ID, Location, Authentication, Self-ID, System, Operator ID and Message Pack) and lists the broadcast transports: Bluetooth 4 legacy advertising, Bluetooth 5 long range with extended advertising, Wi-Fi Neighbor Awareness Networking and Wi-Fi beacon. It also defines OPEN_DRONE_ID_ARM_STATUS, which a Remote ID transmitter sends to say it is ready, and which the flight stack should use as an arming condition. That is how open autopilots implement the "cannot take off without Remote ID" rule.

PX4's Remote ID support is marked experimental in its documentation. It works with modules targeting the FAA standard Remote ID rules over MAVLink (from v1.14) and over CAN on newer builds. ArduPilot's Remote ID page separates devices integrated into maker supplied systems from add-on beacons for home built and existing aircraft, and notes that add-on devices either carry their own GPS or take position from the autopilot over MAVLink using Open Drone ID compliant firmware. If you build a commercial product on either, the Declaration of Compliance, not the autopilot, is what makes it a standard Remote ID aircraft.

We do not cover, and will not cover, ways to disable, spoof or bypass Remote ID or geofencing. Those controls exist for airspace safety and are legal requirements.

How are LiPo and Li-ion flight batteries built and rated?

Construction

Most hobby and many professional multirotors use lithium polymer (LiPo) pouch cells: flat, light and able to deliver high current. Long endurance builds increasingly use cylindrical lithium ion cells (for example 18650 or 21700 sizes), which hold more energy per gram but deliver less peak current. Both have a nominal voltage of 3.7 V per cell, as PX4's battery documentation states, and packs are described by the number of cells in series: 4S is four cells, about 14.8 V nominal; 6S is six cells, about 22.2 V. A pack is built by matching cells by capacity and internal resistance, connecting them with welded tabs or nickel strip, adding a balance lead to every cell junction so a charger can see each cell, wrapping the pack, and fitting a main power connector. Smart batteries add a battery management board with a fuel gauge, temperature sensing, protection and their own firmware, which reports state to the aircraft.

PX4 notes that there is no single "empty" voltage: too low and you damage the pack and risk a crash, too high and you waste flight time. QGroundControl's default "full" cell voltage in PX4's battery settings is 4.05 V, below the absolute charge limit, because voltage under load sags.

C rating and capacity

The C rating is a maker's statement of continuous discharge current as a multiple of capacity. It is a marketing convention, not a regulated number, so treat it as an upper bound and plan well below it.

Worked example: current and energy

A 4S 5,000 mAh pack labelled 50C:

  • Claimed maximum continuous current: 5.0 Ah × 50 = 250 A
  • Energy: 14.8 V × 5.0 Ah = 74 Wh

A quadcopter whose four motors each draw 20 A in a climb pulls 80 A, which is 80 ÷ 5.0 = 16C, comfortably inside the label. A 6S 10,000 mAh pack holds 22.2 V × 10 Ah = 222 Wh.

Safety in charging and transport

Charging rules are practical and widely documented by battery makers: balance charge on a charger set to the right chemistry and cell count, never leave a charging pack unattended, charge on a non-flammable surface or in a fire resistant container, retire packs that are swollen or damaged, and store packs partly charged rather than full.

Transport has hard rules. Under 49 CFR 173.185, each lithium cell or battery must be of a type proven to meet UN Manual of Tests and Criteria Part III, sub-section 38.3, and manufacturers and distributors of cells and batteries made on or after 1 January 2008 must make a test summary available. Packs must be protected against short circuits. Damaged, defective or recalled batteries face strict limits.

For air passengers, the FAA's PackSafe page says spare lithium ion batteries go in carry-on baggage only, are limited to 100 Wh per battery, and that with airline approval a passenger may carry up to two spare larger batteries between 101 and 160 Wh. Terminals must be protected from short circuit. Applying that to the examples: the 74 Wh 4S pack is under 100 Wh; the 222 Wh 6S pack is above the largest spare size that guidance describes for passengers, so check with the carrier and shipping rules before travelling with it.

Step by step: build PX4 from source, verify it, flash it and enable MAVLink signing

This walkthrough is for a test airframe on the bench. Remove all propellers before you connect a battery. PX4's DShot page gives the same warning for changing ESC configuration. Use a controller you are prepared to reflash, and do not fly it until you have repeated the full calibration.

1. Prepare the host

Install the PX4 developer toolchain for your operating system as the PX4 docs describe (Ubuntu is the primary supported host). Alternatively, PX4 documents building inside its px4-dev Docker container with ./Tools/docker_run.sh, which keeps the toolchain off your machine.

2. Clone and pin a release

git clone https://github.com/PX4/PX4-Autopilot.git --recursive
cd PX4-Autopilot
git fetch --tags
git checkout v1.17.0
git submodule update --init --recursive

Pin to a release tag, not main. Record the exact commit you are building:

git rev-parse HEAD
git describe --tags --always

3. Verify the release before you trust it

When we checked, GitHub's API showed v1.17.0 as an annotated tag carrying a PGP signature that GitHub marked as verified, created on 13 May 2026 and pointing at commit d6f12ad1c4f70ad3230afd7d86e971421e02fef4. Check that your checkout resolves to the same commit, and that the tag object is the one you expect:

git rev-parse 'v1.17.0^{commit}'   # expect d6f12ad1c4f70ad3230afd7d86e971421e02fef4
git cat-file -t v1.17.0            # expect: tag (annotated), not commit

To check the signature yourself you need the signer's public key in your keyring, obtained from a source you trust. With it imported:

git tag -v v1.17.0

If you cannot get the key through a trusted channel, the commit hash match against the release page is your minimum check. Write down which check you did.

Read the release notes for parameter or behaviour changes that affect your airframe. Then check that submodules are at the commits the tag expects, with nothing modified locally:

git submodule status --recursive | grep -v '^ ' || echo "all submodules match the recorded commits"
git status --porcelain

A leading + or - in git submodule status means a submodule is not at the recorded commit or not initialised.

4. Build for your board

List the available targets, then build the one that matches your flight controller:

make list_config_targets
make px4_fmu-v5_default

The build writes build/px4_fmu-v5_default/px4_fmu-v5_default.px4. Record its hash next to the commit:

shasum -a 256 build/px4_fmu-v5_default/px4_fmu-v5_default.px4 | tee firmware-sha256.txt

To check the build is reproducible on your own machines, run the same build in a second clean checkout or the Docker container and compare. If the hashes differ, find out why (timestamps, toolchain version, local changes) before you ship.

5. Flash it

Warning: flashing replaces the firmware on the connected board. Check which device you are about to write to before you run the upload. Disconnect any other flight controller from the host.

# Check that exactly one flight controller is connected, and which port it uses
ls /dev/serial/by-id/ 2>/dev/null || ls /dev/tty.usbmodem* 2>/dev/null

Confirm the listed device is the test board. Then build and upload over USB, as PX4 documents:

make px4_fmu-v5_default upload

Alternatively, load the .px4 file through QGroundControl's custom firmware option. After the upload, connect a ground station and check that the reported firmware version and git hash match what you built.

6. Provision a MAVLink signing key over USB

PX4 accepts the first SETUP_SIGNING on any link, so do this over USB before the aircraft ever joins a radio network. Generate a 32 byte key on the ground station machine and store it as you would any credential, for example in your operating system keychain or a secrets manager, never in the repository:

python3 -c "import secrets; print(secrets.token_hex(32))" > signing-key.hex
chmod 600 signing-key.hex

The pymavlink library supports signing when using MAVLink 2: you give it the secret key and an initial timestamp, and it signs outgoing messages and checks incoming ones. A minimal provisioning script, run with the board on USB and the vehicle disarmed:

# provision_signing.py: bench use only, vehicle disarmed, props off
import os, time
os.environ["MAVLINK20"] = "1"
from pymavlink import mavutil

key = bytes.fromhex(open("signing-key.hex").read().strip())
# MAVLink signing timestamp: 10 microsecond units since 1 Jan 2015 (Unix 1420070400)
ts = int((time.time() - 1420070400) * 100000)

m = mavutil.mavlink_connection("/dev/serial/by-id/REPLACE_WITH_YOUR_BOARD", baud=115200)
m.wait_heartbeat()
m.mav.setup_signing_send(m.target_system, m.target_component, key, ts)
m.setup_signing(key, sign_outgoing=True, initial_timestamp=ts)
print("SETUP_SIGNING sent to system", m.target_system)

Replace the device path with the one you confirmed in step 5. PX4 writes the key to /mavlink/mavlink-signing-key.bin on the SD card and activates signing on all links, including USB.

For ArduPilot, the Mission Planner documentation describes the same task in the GUI: SETUP, Advanced, "Mavlink Signing", ADD a key, then USE it while connected. Remember that ArduPilot leaves USB unaffected by design.

7. Verify that signing is enforced

  • Connect your ground station with the key configured and confirm parameters download and commands are acknowledged.
  • Connect a second ground station without the key over the telemetry link. On PX4 it should see heartbeats (allowlisted) but its commands and parameter writes should be rejected.
  • Try to change the key while armed (props still off) and confirm PX4 rejects it.
  • Record in your build log: firmware hash, commit, key ID (not the key), date and who provisioned it.

8. Scan the code you maintain around the autopilot

If you fork PX4 or ArduPilot, or write companion computer code and ground tools around them, run a dependency scan from the repository root. With the Safeguard CLI:

safeguard scan --dir .

Results land as JSON under ./output. Be realistic about coverage: a scan reads the package manifests and lockfiles it recognises (for example Python requirements used by build tools, or the dependencies of a companion computer service), and it is not a review of the C++ flight code or of vendored submodules that have no manifest. For a companion computer container, scan the image you actually deploy:

safeguard scan --image your-registry/companion:2026-10-24

Common mistakes

  • Flying a build from main. Development branches change behaviour without notice. Pin a release tag and record the commit and firmware hash for every aircraft.
  • Leaving the first signing key unclaimed. PX4's hardening guide notes that until a key is provisioned, any peer that can reach a link can set one. Provision over USB before the aircraft joins a shared network.
  • Treating signing as encryption. MAVLink signing authenticates; telemetry, missions and parameters are still readable on the link. Use an encrypted radio or VPN where confidentiality matters.
  • Sharing one key across a whole fleet without a plan. The key is symmetric. One leaked key lets anyone sign as any component on every aircraft that shares it. Rotate deliberately; PX4 has no automatic rotation.
  • Ignoring the SD card and debug port. On PX4 the key lives on the SD card. Exposed SWD or JTAG allows a full reflash. Physical access is part of the threat model.
  • Wrong motor pole count. It skews RPM telemetry and the dynamic notch filter.
  • Calibrating ESCs that use DShot. DShot needs no throttle calibration; PWM ESCs do. Mixing up the procedure wastes time and can spin motors unexpectedly. Props off, always.
  • Mounting the compass next to the power distribution. Heading errors that grow with throttle are the classic symptom.
  • Trusting a C rating. It is a maker's claim. Plan for well under it and watch pack temperature.
  • Flashing the wrong board. With two controllers connected, an upload can hit the wrong one. Check the device path every time.
  • Assuming Remote ID is someone else's problem. On a home build it is the builder's job to fit a broadcast module, use a standard Remote ID product, or fly in a FRIA.

FAQ

What parts do you need to build a drone?

A frame, four or more brushless motors with matched propellers, an ESC per motor or a 4 in 1 ESC board, a flight controller, a GNSS and compass module, an RC receiver and transmitter, a telemetry radio if you want a ground station link, a power module, a battery and charger, and in the US a Remote ID solution unless you only fly inside a FRIA.

What does an ESC do on a drone?

It switches battery current through the motor's three phases in the right sequence and at the right rate to hold the speed the flight controller asks for. Modern ESCs also report RPM, temperature, voltage and current back to the flight controller.

What is the difference between PWM and DShot?

PWM is an analogue pulse width signal that needs the ESC to learn the throttle range. DShot is a digital protocol with a checksum, needs no calibration, has lower latency, supports commands such as reversing spin direction, and in its bidirectional form returns RPM on the same wire.

What does KV mean on a brushless motor?

RPM per volt with no load. A 2,300 KV motor on 14.8 V would spin about 34,000 RPM with no propeller. Higher KV suits small propellers and lower voltage; lower KV suits large propellers and higher voltage.

What firmware do drones run?

Consumer drones run closed firmware from their maker. Many enterprise and almost all open builds run PX4 (on NuttX) or ArduPilot on the flight controller, separate firmware on ESCs, radios and Remote ID modules, and often Linux on a companion computer.

Is MAVLink encrypted?

No. MAVLink 2 supports message signing, which authenticates messages and blocks replays, but content is sent in plaintext. Use an encrypted radio link or VPN for confidentiality.

Does my home built drone need Remote ID?

If it must be registered and you fly it in the US outside a FRIA, yes: since 16 September 2023 Part 89 requires either a standard Remote ID aircraft or a broadcast module. Check the FAA Remote ID pages for your situation, including the registration steps for each module or drone serial number.

What does a Remote ID broadcast module send?

The module's serial number, the drone's latitude, longitude, geometric altitude and velocity, the take off location and altitude, and a UTC time mark, as listed in 14 CFR 89.315.

How many watt hours can I take on a plane for my drone battery?

FAA PackSafe guidance allows spare lithium ion batteries up to 100 Wh in carry-on baggage, and with airline approval up to two spares between 101 and 160 Wh. Spares must not go in checked bags. Airlines can be stricter, so check with yours.

Can I lock my flight controller to my own firmware?

ArduPilot documents a secure bootloader that only boots firmware signed with keys it holds. Follow the procedure exactly, test on a spare board, and keep your private key offline; ArduPilot warns that mistakes can render the board inoperative.

Where Safeguard fits, honestly

Safeguard does not build, inspect or certify drones. It does not analyse flight controller boards, ESC firmware images, radios or Remote ID modules, and it does not do device management for aircraft. Its fit is the software your team writes and ships around the drone: a fork of an open source autopilot with its build tooling, the companion computer's Linux image and Python or C++ services, container images for fleet and ground services, and the web and mobile apps operators use. For those, Safeguard scans repositories, container images and SBOM files, matches components against vulnerability data, shows which projects contain a given component and version, applies policy gates, and can open fix pull requests (remediation is off by default until you turn it on). The Safeguard CLI's assistant can edit code and run commands with your approval, which suits a developer who maintains a companion service and needs a dependency fixed and tested before the next field test.

A drone's flight controller code is only part of what flies. The companion computer image, the ground station tooling and the fleet services pull open source packages on every rebuild, and those are where a known vulnerable version most often slips back in unnoticed.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session asked to fix a lodash CVE: it reads the finding and advisory, asks before each command, edits package.json, runs npm install and npm test with approval, and pushes nothing. The same flow fits a ground station web dashboard or a fleet telemetry service your team maintains around the aircraft.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code and scans from the terminal. That suits a team that builds autopilot forks and companion computer images on its own build hosts and wants scans to run next to that toolchain.

Click through it at your own pace, or open it full screen.

The third demo is a real Android session: send work to a computer running the CLI and approve each command on the phone with Allow once, Allow for turn or Deny. An engineer at a test field can approve a dependency fix in the companion service repository without anything running unattended.

Click through it at your own pace, or open it full screen.

To try it on your own repositories, download Safeguard and follow the CLI documentation.

Quick check

Does MAVLink 2 message signing stop someone reading your telemetry?

No. Signing adds a truncated SHA-256 signature and a timestamp so the receiver can reject forged, modified or replayed messages, but the message content is still sent in plaintext. Confidentiality needs an encrypted link underneath, such as an encrypted radio or a VPN.

What must a standard Remote ID drone do if its Remote ID is not working before take off?

Refuse to take off. 14 CFR 89.310 requires an automatic pre-flight self test, notification to the pilot, and that the aircraft cannot take off if Remote ID is not functional.

Sources

Last reviewed: 24 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.