bbdoctor
Drone diagnostics from logs: Betaflight, INAV, ArduPilot, PX4
RUENESPTUA

Betaflight Blackbox Setup: Record a Log You Can Actually Diagnose

Blackbox records the gyro, sticks and setpoint, PID terms, motors, RPM, voltage and current. But a log on out-of-the-box settings often shows very little. Real examples from logs we've analysed: a 3.5-inch on Betaflight 4.5.2 logging at 1 kHz while its motors spin up to 644 Hz; a Betaflight 2026.6 log at 247 Hz with no raw gyro and no RPM; a 7-inch on 4.6 logging 2 kHz to an SD card with 182 gaps; an INAV 7.1 log at 58 Hz that says nothing about vibration.

What each check needs

Thresholds come straight from the analyzer's code; below them a check stays silent or flags too little data.

CheckLog fieldsLogging rateWhat to fly
Per-motor vibration: which motor or prop shakesunfiltered gyro + eRPM~250 Hz+; works even above Nyquisthalf a minute of steady flight at varied throttle
Noise, filters, frame resonancesunfiltered and filtered gyro500 Hz+; exact resonance frequency at 1/1 (or 2 kHz+ for resonances below 500 Hz)hover plus a slow throttle sweep to 100%
Motor noise and which PID term carries itmotor, axisP, axisD, axisF500 Hz+any flight
Step response and latencysetpoint + gyro200 Hz+Acro; 10+ usable one-second windows with the stick at 20 deg/s or more, 50 for a “critical” verdict
Propwashsetpoint, throttle200 Hz+3 clean chops minimum, 5 for a confident verdict
Bounce-back after flipssetpoint, axisP/I/D/F200 Hz+6+ sharp stick stops per axis
Punch-out dip (anti-gravity)setpoint, throttle, axisI100 Hz+6+ punch-outs with the other sticks centred
Battery sag and resistancevbat; a current sensor too for resistanceanyfor resistance, 5+ one-second windows with an 8 A+ current swing
Crash analysisaccelerometer, gyro, RSSI/failsafe, eRPM, vbatany—

Under 10 seconds in the air, every tuning finding is downgraded to “info” and loses its CLI commands, and bounce-back and punch-outs aren't measured. If over half the flight was in Angle or Horizon, step response and bounce-back are skipped: there the stick commands an angle, not a rotation rate.

Logging rate and aliasing

Why 1 kHz misleads on small quads

A log recorded at N Hz only shows vibration up to N/2, the Nyquist frequency. Anything faster doesn't vanish; it mirrors back below that limit. A motor at 644 Hz in a 1000 Hz log shows up at 1000 − 644 = 356 Hz. That leaves a tidy spectral peak where nothing is happening: an easy target for a misplaced notch or filter.

Three logs from a VX3.5 on Betaflight 4.5.2 (4 kHz PID loop, 1/4, so 1 kHz) had the motors peaking at 583, 605 and 644 Hz, above 500 Hz every time. The figure shows the same effect on another quad: a 2 kHz log with every fourth frame kept, exactly what blackbox_sample_rate does, skipping frames with no filtering first.

Raw gyro noise versus throttle at 2000 Hz and the same flight at 500 Hz, where the motor line folds back from 250 Hz
Raw roll gyro against throttle. A: the original 2000 Hz log (Betaflight 4.2.5, 4S, GYRO_SCALED). B: the same flight with every fourth frame kept, i.e. 500 Hz. In A the motor line moves right with throttle: 289 Hz at 30%, 398 Hz at 50%, 609 Hz at 90%. In B everything above 250 Hz is mirrored: 289 → 211 Hz, 398 → 102 Hz, 609 → about 109 Hz. “Noise” whose frequency falls as throttle rises is a sure sign of aliasing.

bbdoctor measures per-motor vibration from each motor's rotation phase (eRPM), so it knows where the mirrored copy lands and that check still works at 1 kHz; the noise spectrum and resonances can't be rescued. When peak RPM in a Betaflight log goes above 95% of the Nyquist frequency, the report adds “Logging rate is below the motor frequency” with the right divider as a command.

Picking blackbox_sample_rate

From 4.3 on, the rate is a divider of the PID loop: 1/1, 1/2, 1/4, 1/8 or 1/16, with 1/4 as the default. bbdoctor picks the largest divider that still leaves at least 2 kHz:

PID loopDefault (1/4)SetResult
8 kHz2 kHz1/42 kHz
4 kHz1 kHz1/22 kHz
3.2 kHz (BMI270)800 Hz1/13.2 kHz

Your loop rate is on the Configuration tab. Not every build needs 2 kHz: bbdoctor only asks once the motors outrun the logging rate. A 7-inch 6S in our set never went past 315 Hz, so 1 kHz would have done. A 3 to 3.5 inch on 4S at 1 kHz usually goes over, and not only those: in four 1 kHz logs from a 6S quad on 4.5.1 the motors reached 529–554 Hz. On a BMI270, 1/1 eats flash fastest; if space is tight, 1/2 (1.6 kHz) still covers motors up to about 760 Hz. 1/8 and 1/16 are useless for analysis (500 and 250 Hz on a 4 kHz loop), and the config check flags them.

Flash budget

File sizes in our set: at 1 kHz with all fields, about 34 KB/s without debug fields and 41–43 KB/s with a debug mode on; at 2 kHz, 58–70 KB/s. An 8 MB flash lasts about 3 to 4 minutes at 1 kHz and 2 minutes at 2 kHz. That VX3.5 (debug_mode = GYRO_SCALED) filled its 8 MB to the last byte in 195 seconds at 1 kHz and stopped mid-flight. bbdoctor spots this (a cut-off end, or a file of exactly 2, 4, 8 or 16 MB) and warns alongside the rate advice that recording time will halve.

So erase the flash before testing (Erase flash on the Blackbox tab, or flash_erase in the CLI), fly 1–2 minute test packs and drop fields you don't need. An SD card has room, but a slow one drops frames: the 7-inch on 4.6 logging 2 kHz to SD had 182 gaps. Use a decent, freshly formatted card; if gaps persist, step the rate down.

Betaflight settings by version

4.5 and 2025.12+

For a 4 kHz PID loop (use 1/4 on 8 kHz and 1/1 on 3.2 kHz):

set blackbox_mode = NORMAL
set blackbox_sample_rate = 1/2
set blackbox_disable_gyrounfilt = OFF
set blackbox_disable_rpm = OFF
set blackbox_disable_setpoint = OFF
set blackbox_disable_pids = OFF
set blackbox_disable_motors = OFF
set debug_mode = NONE
save

A Betaflight 2026.6.1 log was recorded at 1/16 (247 Hz on a 4 kHz loop) with raw gyro and RPM off, though bidirectional DShot was running. The report gave both commands to turn them back on. A 4.5.1 log had setpoint off: bbdoctor rebuilds it from sticks and rates, with a rougher PID estimate, and says so.

4.3–4.4

set blackbox_sample_rate = 1/2
set debug_mode = GYRO_SCALED
save

Pick the divider from the table above. There are no unfiltered gyro or RPM fields yet. The gyro goes through debug, and only one debug mode runs at a time, so DSHOT_RPM_TELEMETRY is out (bbdoctor doesn't read RPM from debug anyway). Even with bidirectional DShot working it recommends 4.5, since without RPM it can't name the unbalanced motor. The blackbox_disable_… settings exist from 4.3 (rpm and gyrounfilt from 4.5): check that setpoint isn't off.

4.0–4.2

set blackbox_p_ratio = 64
set debug_mode = GYRO_SCALED
save

These versions use blackbox_p_ratio. The rate is roughly p_ratio × 31.25 Hz: 32 gives about 1 kHz, 64 about 2 kHz, capped at the PID loop rate. A 4.2.11 log in our set was recorded at just 534 Hz and had 36 gaps on top.

Fields you can switch off, and ones you can't

blackbox_disable_gps, blackbox_disable_mag and blackbox_disable_alt (baro) are safe to turn ON unless you analyse navigation. Keep:

RPM in the log

RPM comes from bidirectional DShot: set dshot_bidir = ON, save, with the DShot protocol and ESCs on Bluejay, AM32 or BLHeli_32. Then take the props off, spin the motors with the sliders on the Motors tab and check that RPM shows up with errors near zero. Check motor_poles too: motor frequency is computed from eRPM through the pole count. Most 5-inch motors have 14 poles, some small ones 12; get it wrong and every motor frequency in the log is off. More in the RPM filter and bidirectional DShot guide.

INAV

set blackbox_rate_num = 1
set blackbox_rate_denom = 2
blackbox GYRO_RAW
blackbox MOTORS
save

In INAV the logging rate is the fraction blackbox_rate_num/blackbox_rate_denom of loop cycles. INAV 8 and later default to a 2 kHz loop (looptime = 500), where 1/2 gives 1 kHz; INAV 7 and earlier default to 1 kHz (looptime = 1000), where 1/2 gives 500 Hz. Vibration and filter checks need 500 Hz or more. Three INAV 7.1.2 logs in our set, from a 7-inch and a 5-inch, were recorded at 1/32, or 58–60 Hz: all they can show is motor balance and the battery. An INAV 8.0 log at 1/2 came in at 995 Hz, with noise and filters plain to see.

Details are in the INAV blackbox guide.

ArduPilot and PX4 in brief

ArduPilot. Without the fast bits in LOG_BITMASK (the default has none), ArduCopter logs the gyro at 25 Hz, as in all ten ArduCopter logs in our set, 4.1 to 4.8-dev. For analysis, set bit 0 (ATTITUDE_FAST) and bit 19 (IMU_RAW) in LOG_BITMASK, plus INS_RAW_LOG_OPT = 9 on 4.5+ for the gyro before and after filtering. RPM comes from ESC telemetry or bidirectional DShot (SERVO_BLH_BDMASK). Use the .bin from the SD card (APM/LOGS), not a .tlog. For ArduCopter PIDs the built-in AUTOTUNE is more reliable; the log is for vibration and filters. See the ArduPilot log analysis guide.

PX4. Add bits 4 (High rate) and 8 (Raw FIFO gyro) to SDLOG_PROFILE: from the default of 1 that's 273, or param set SDLOG_PROFILE 273 in the QGroundControl MAVLink Console, then reboot: the profile is read at startup. The .ulg is under Analyze Tools → Log Download. See the PX4 ULog guide.

The test flight

Freestyle hits these events by chance; a 1.5–2 minute test pack collects 6–8 of each on purpose:

  1. Before takeoff. Fresh props, a charged pack, erased flash, BLACKBOX switch on if you use one.
  2. Acro mode. Angle and Horizon rule out step response and bounce-back.
  3. 30 seconds of hover and smooth cruising, then, if there's room, a slow 5-second throttle roll from hover to 100% for the noise-versus-throttle map.
  4. 6–8 flips or rolls per axis, plus yaw spins. Snap the stick back to centre in under 0.2 s and hold it there for half a second. Moves count from 150 deg/s on roll and pitch and 120 deg/s on yaw; a slow return to centre is thrown out.
  5. 6–8 punch-outs from hover (about 30% throttle, always below 70%): more than a quarter of throttle travel in 0.2 s. Don't touch roll and pitch; above 80 deg/s of setpoint the punch doesn't count.
  6. 6–8 straight chops: climb, chop to zero, sticks centred for about a second. A chop counts if throttle was above 35% and fell by more than 25% within 0.15 s. No flips straight after: in one 2 kHz log, 12 of 15 chops went straight into a flip or roll, leaving 3 usable for propwash.
  7. Landing. Land gently, without a chop just above the ground: a chop that ends in an impact is left out of the propwash check.

A big rig doesn't need flips; short, sharp stick tilts at a safe height will do. Length alone guarantees nothing: five minutes of ordinary flying on a 7-inch gave 5 chops (one clean), 1 punch-out and 1 sharp roll stop.

Setpoint and throttle over a whole flight with the detected throttle chops, punch-outs and sharp stick stops marked
A 195-second 3.5-inch flight (Betaflight 4.5.2) as bbdoctor sees it. Top: roll (blue) and pitch (orange) setpoint; ticks above are the stick stops counted for bounce-back: roll 12, pitch 6, yaw 26 (green). Bottom: throttle. Red triangles: 63 chops, 38 clean, 24 followed by a flip or roll, one dropped as an impact or landing. Green triangles: 15 counted punch-outs out of 48 sharp throttle rises; on the rest the sticks were moving. The first ~28 s are a steady hover.

Getting the log off

In Betaflight and INAV, use Save flash to file on the Blackbox tab, or Mass Storage mode so the board mounts as a drive. With an SD card, copy the file. INAV files often end in .TXT, ArduPilot uses .bin, PX4 .ulg.

One file can hold many flights, one per arm; our set includes a Betaflight 2026.6 file with 66. bbdoctor takes the longest by default (number 58 there), and the report lets you pick any other.

Common mistakes

SymptomCauseFix
Empty log, or no flight in itBLACKBOX switch off, blackbox_device = NONE, flash already fullcheck Modes and Blackbox, erase the flash
Log stops mid-flightflash full: the file is exactly 8 or 16 MBerase before flying, 1–2 minute packs
“Gaps in the recording”slow SD card or too high a ratea decent card, otherwise one divider step down
“The setpoint isn't logged”blackbox_disable_setpoint = ONset blackbox_disable_setpoint = OFF
No PID verdictover half the flight in Angle/Horizona test pack in Acro
INAV log at 60 Hzlarge blackbox_rate_denom1/2 for the test flight
INAV: “no motor commands”MOTORS field offblackbox MOTORS
No RPMbidirectional DShot off, Betaflight before 4.5, or blackbox_disable_rpm = ONenable bidirectional DShot, update, turn the field back on
Spectrum peaks no filter change “fixes”motors faster than ~475 Hz in a 1 kHz log: mirrored frequenciesa divider for ~2 kHz (1/2 on a 4 kHz loop) and a new log

Check the log automatically

Drop the file into bbdoctor; it's free and needs no account. First it checks the log itself: flight time, gaps and dropped frames, a cut-off end, raw gyro, RPM and setpoint, the logging rate against peak motor frequency, and time in self-level. Anything missing is named, with commands for your firmware version. See the sample report.

You can check the settings before flying: paste your diff all into the config check. It flags blackbox being off, a 1/8 or 1/16 divider, disabled fields, missing GYRO_SCALED on 4.0–4.4, and a low rate or missing GYRO_RAW on INAV. For the finished log, see how to read a blackbox log.

FAQ

What blackbox logging rate should I use?

About 2 kHz: blackbox_sample_rate = 1/4 on an 8 kHz PID loop, 1/2 on 4 kHz and 1/1 on 3.2 kHz (BMI270 gyro). Big quads whose motors stay under about 450 Hz are fine at 1 kHz, but on a 3 to 3.5 inch 4S quad and many 6S builds a 1 kHz log already shows fake peaks in the spectrum.

Why is my blackbox log empty?

Usually the BLACKBOX mode is on a switch that was off, the flash was already full, or blackbox_device is NONE. Check the Modes and Blackbox tabs, erase the flash before the flight and fly for at least 30 to 60 seconds.

Do I need debug_mode on Betaflight 4.5 or 2025.12?

No. Since 4.5 the unfiltered gyro and motor RPM have their own log fields, and with debug_mode = NONE the debug fields aren't written at all. GYRO_SCALED is only needed on 4.0 to 4.4.

How long does onboard flash last at 2 kHz?

In our logs 1 kHz with all fields comes to 34 KB/s without debug fields and 41–43 KB/s with them, and 2 kHz to 58–70 KB/s. An 8 MB flash fills in about 3 to 4 minutes at 1 kHz and about 2 minutes at 2 kHz; 16 MB lasts twice as long.

Updated:

More guides