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

Dynamic Notch and Frame Resonance: What to Filter and What to Fix

A sharp peak in the gyro spectrum can be cut with a notch filter or removed at the source. This guide shows how to tell motor noise from frame resonance in a log, how bbdoctor detects a resonance and why it sometimes refuses to name the frequency, and which notch settings real pilots run in Betaflight 4.2 to 2025.12, INAV 8 and PX4 logs.

Notch vs lowpass vs RPM filter: what each one removes and what it costs

All of these clean the gyro before it reaches the PID controller, and all of them add delay. The difference is what they target:

A notch's delay depends on where it sits and how wide it is. The numbers below are computed for a 4 kHz loop with a Betaflight-style biquad. What matters is the delay at 20–40 Hz, where the quad's actual movement lives.

FilterDelay at 20 HzAt 40 Hz
PT1 250 Hz0.63 ms0.61 ms
PT1 100 Hz1.52 ms1.32 ms
Static notch 160 Hz, cutoff 120 (Q 1.71)0.60 ms0.68 ms
Static notch 469 Hz, cutoff 3280.24 ms0.24 ms
Dynamic notch at 200 Hz, dyn_notch_q 5000.16 ms0.18 ms
Dynamic notch at 100 Hz, dyn_notch_q 5000.36 ms0.52 ms
Dynamic notch at 70 Hz, dyn_notch_q 5000.58 ms1.29 ms
Dynamic notch at 100 Hz, dyn_notch_q 1201.45 ms1.88 ms

Two rules follow. A narrow notch high in the spectrum is nearly free, while a wide or low one costs as much as a decent lowpass. And three notches sitting close together delay the signal three times as much as one.

Motor noise or frame resonance: diagonal vs vertical lines

The clearest view is a throttle heatmap: frequency across, throttle up, brightness for noise level. Motor speed rises with throttle, so motor harmonics draw diagonal lines. A frame resonance is a natural frequency of the structure and doesn't care about throttle, so it draws a vertical line.

Raw gyro roll and pitch heatmaps of a 6S quad on Betaflight 4.5.1: vertical bands near 198 and 186 Hz run from low throttle up to 85 percent
Raw gyro from a 6S quad on Betaflight 4.5.1, logged at 1013 Hz. At hover throttle (20–30%) the motors spin around 192 Hz, and above 80% around 467 Hz. Meanwhile the bands at 198 Hz (roll) and 186 Hz (pitch) stay put at every throttle. They're brightest at 20–40%, where the motors' first harmonic sweeps across them and shakes the frame.

That last point matters: a resonance is almost always brightest where a motor line crosses it. The motor is the source and the frame is the amplifier. A 7-inch quad on Betaflight 4.6 shows this well. Its pilot had already set a static notch at 160 Hz.

Pitch heatmaps of a 7-inch quad: raw gyro on the left with a vertical line near 162 Hz crossed by the motor diagonal, filtered gyro on the right, almost dark on the same scale
7-inch quad, Betaflight 4.6.0, logged at 1980 Hz, same colour scale on both maps. Left, raw gyro: the line near 162 Hz stands 16–22 dB above neighbouring frequencies at 25–40% throttle, where the motors spin at 139–178 Hz, and only 0–8 dB above them at other throttle levels. Right, filtered gyro: at 162 Hz and 30–40% throttle the level drops from +4 to +5 dB before filtering to about −39 dB after.

bbdoctor didn't call this one a resonance: the line clears the threshold in only about half of the throttle bins, and it needs 60%. That's a fair call. A peak like this sits on the border between frame and motors, and the filters already in place handle it. Filtered noise here is 0.66 deg/s, so there's no reason to touch the filters. Raw noise is 7.9 deg/s, though, and bbdoctor rightly points at props, motors and the frame.

How bbdoctor finds a resonance, and why it sometimes won't name the frequency

Knowing how the detector works helps you read the report:

  1. The flight is cut into 256-sample windows with 50% overlap. Each window goes into one of 20 throttle bins by its average throttle. A bin counts if it holds at least 4 windows.
  2. For roll and pitch, each bin gets a spectrum, and the "floor" is a running median over 15 neighbouring frequencies. The grid step is the logging rate divided by 256: about 4 Hz in a 1 kHz log, about 16 Hz at 4 kHz.
  3. A frequency counts as a resonance if its peak is more than 6 dB above the floor in at least 60% of the throttle bins. Anything below 60 Hz or in the top 5% below Nyquist is ignored.
  4. Roll and pitch peaks within 10 Hz of each other are merged into one.

With a logging divider, Betaflight's blackbox writes every Nth sample with no anti-aliasing filter. Anything above half the logging rate folds back, so a peak at 827 Hz in a 1013 Hz log shows up as 186 Hz. The log alone can't undo that, so bbdoctor lists the candidates: f, fs − f and fs + f.

LogLogging / PID loopPeak in the logCandidatesVerdict
BF 4.5.1, 6S, flight 11013 Hz / 4 kHz206 Hz roll, +8 dB, 71% of bins206, 807, 1219no notch suggested
BF 4.5.1, 6S, flight 21013 Hz / 4 kHz186 pitch, 198 roll, +6–7 dB186, 827, 1199 / 198, 815, 1211no notch suggested
BF 4.5.1, 6S, flight 31013 Hz / 4 kHz190 and 226 pitch, 202 roll, +7 dB190, 823, 1203 and so onno notch suggested
INAV 8.0.0, 6S995 Hz / 2 kHz117 Hz pitch, +12 dB, 100% of bins117, 878, 1112no notch suggested
PX4 1.15.4, 6S8013 Hz469 Hz pitch, +6 dBunambiguousstatic notch

The rule in the code: the frequency is unambiguous if the log runs at the PID loop rate, or it's logged at 2 kHz or faster and the peak sits below half the Nyquist frequency. For a 2 kHz log that means below 500 Hz. The three 6S flights are the textbook case. They run blackbox_sample_rate = 1/4, so the real resonance could be at 186 Hz in the arms or at 827 Hz in the stack. That changes both the notch and where you go looking for the problem.

Roll and pitch spectra before and after filtering: the raw gyro shows peaks at 202 Hz on roll and 190 and 226 Hz on pitch, the filtered gyro sits 26 to 28 dB lower
Third flight of the same 6S quad, whole-flight spectrum. Grey is the raw gyro (peaks of −1 to −3 dB at 202 Hz roll, 190 and 226 Hz pitch), blue is after filtering (−28 to −30 dB). The RPM filter, one dynamic notch and the lowpasses take 26–28 dB off these peaks, yet small bumps at the same frequencies survive the filters.

On all three logs bbdoctor reports "Filters: there's headroom, but it's too early to relax them (delay 2.2–2.3 ms)". Filtered noise is 0.5–0.6 deg/s, but the raw gyro reads 4.8–7.4 deg/s and there's a resonance. Raising cutoffs before the hardware is fixed and the frequency is known just lets that peak into the PIDs.

Dynamic notch settings by Betaflight version

The parameter names have changed twice, in 4.2 and in 4.3. Not sure what your firmware has? Type get dyn_notch in the CLI to list every matching parameter.

VersionHow to enableParametersNotes
4.0–4.1feature DYNAMIC_FILTERdyn_notch_range (LOW/MEDIUM/HIGH/AUTO), dyn_notch_width_percent, dyn_notch_q, dyn_notch_min_hzthe upper limit is a preset; defaults AUTO, 8, 120, 150
4.2feature DYNAMIC_FILTERdyn_notch_max_hz replaces range, dyn_notch_min_hz, dyn_notch_width_percent, dyn_notch_q4.2 notes: width 0 and Q 250 with RPM, 8 and 120 without
4.3, 4.4, 4.5, 4.6, 2025.12dyn_notch_count above 0dyn_notch_count (up to 5, up to 7 in 2025.12), dyn_notch_q, dyn_notch_min_hz, dyn_notch_max_hznew SDFT algorithm, width and the feature are gone; defaults 3 notches, Q 300, 150–600 Hz in 4.3, 100–600 Hz in 2025.12

What real logs from our set run (all with bidirectional DShot except the last):

QuadFirmwarecountQmin–max, Hz
6S quad, the three flights above4.5.11500100–600
MASTER5 V24.5.12350120–650
Nazgul F5 V24.4.12500120–600
GEPRC, F4052025.12.5240090–400
REKON 74.6.0350070–400, plus a static notch at 160 Hz
F745, RPM filter inactive (dshot_bidir 0)4.2.8width 8120150–600

How many notches. With a working RPM filter, start with one or two. The 4.3 notes say that more than two or three are rarely needed and often one is enough. Without the RPM filter the notches do its job instead, and the notes suggest three or four with Q around 120–150.

Q. The 4.3 notes call 300–450 a good range for freestyle. Logs with the RPM filter sit at 350–500. A low Q only makes sense without RPM filtering, when the notch has to cover smeared motor noise.

min_hz and max_hz. Find the lowest line on the heatmap you actually want to catch (with the RPM filter that's usually the resonance, without it the motors' 1× at hover) and set dyn_notch_min_hz about 20 Hz below it. The notes say to keep the minimum as high as practical, because that keeps delay down. In the logs above it's 90–120 Hz on the smaller quads and 70 Hz on the 7-inch, whose motors spin at 125–155 Hz at 20–35% throttle. Put dyn_notch_max_hz just above the highest peak you need: a wider range means coarser resolution.

set dyn_notch_count = 1
set dyn_notch_q = 500
set dyn_notch_min_hz = 100
set dyn_notch_max_hz = 600
save

That's the 6S quad's config from the table: a reasonable start on 4.3+ with the RPM filter, not a universal recipe.

A static notch as a stopgap

When the frequency is unambiguous, bbdoctor gives a static notch command: centre on the resonance, lower cutoff at 0.7 times that. Betaflight derives Q from centre and cutoff as Q = f·c / (f² − c²). With c = 0.7f that's Q ≈ 1.37, and the −3 dB band runs from 0.7f to 1.43f. It's wide on purpose. The resonance drifts with screw tension and temperature, and a heatmap of a 4 kHz log only pins it down to half a grid step, about 8 Hz. If a 1/1 log confirms that the 6S quad's resonance really sits at 186 Hz, the command is:

set gyro_notch1_hz = 186
set gyro_notch1_cutoff = 130
save

The 7-inch pilot chose 160/120, which is Q 1.71, a slightly narrower cut. Per the table above it costs about 0.6 ms at 20 Hz, the same as a 250 Hz PT1. That's a fair price for one peak, but no excuse to add a second one "just in case". The 4.3 notes add a useful trade: when the static notch takes over a resonance that sits at one frequency everywhere, drop dyn_notch_count by one.

INAV. INAV has no static gyro notch at all (only acc_notch_hz for the accelerometer), so bbdoctor gives no command for INAV. What's left is the dynamic notch: dynamic_gyro_notch_enabled, dynamic_gyro_notch_q, dynamic_gyro_notch_min_hz. Our INAV log runs Q 250 with a 126 Hz minimum. If a full-rate log confirms the resonance at 117 Hz, the dynamic notch can't reach it until you lower the minimum to about 100. More in the INAV blackbox guide.

ArduPilot. bbdoctor enables the second harmonic notch in fixed-frequency mode, with a bandwidth of f/2 and 40 dB attenuation. After setting INS_HNTC2_ENABLE = 1, refresh the parameter list so the other INS_HNTC2_* parameters appear. See the ArduPilot log guide.

PX4. From 1.13 it's IMU_GYRO_NF0_FRQ and IMU_GYRO_NF0_BW; in 1.12 and older, IMU_GYRO_NF_FREQ and IMU_GYRO_NF_BW. bbdoctor sets the bandwidth to 0.3 times the frequency. The PX4 1.15.4 log was recorded at 8 kHz, so the 469 Hz peak is unambiguous and the commands are:

param set IMU_GYRO_NF0_FRQ 469
param set IMU_GYRO_NF0_BW 141

The same log has the FFT notch on (IMU_GYRO_FFT_EN = 1), but its range is 30–150 Hz and never reaches 469 Hz. Meanwhile IMU_GYRO_CUTOFF = 40 costs about 5.6 ms of delay, while a 469 Hz notch with a 141 Hz bandwidth costs about 0.1 ms. Even so, bbdoctor says it's too early to relax the filters: raw roll noise is 6.4 deg/s, so the hardware comes first. PX4 specifics are in the ULog guide.

Fix the hardware first: what to check by frequency

bbdoctor splits resonances at 250 Hz and names the likely culprit in its finding:

True frequencyWhat usually ringsWhat to do
60–250 Hzarms and frame, a loose camera, the antenna, a battery on a weak straptighten the arm screws, inspect the arms for cracks and delamination, secure the camera and antenna, tighten the strap and add a grippy pad under the battery
250 Hz and upthe FC and ESC stack on soft mounts, fasteners, standoffs, the top platecheck the grommets (a crushed stack is no longer soft-mounted), the stack nuts, the standoffs and the top plate screws

Unplug the battery and take the props off before working on the frame. Before any repair, fit fresh props and check the motors, because they're what excites the resonance. Finding the culprit motor in a log is covered in the vibration guide, and the overall noise and filter picture in the hot motors guide.

Confirm it with a short full-rate log

  1. Log at the PID loop rate. On Betaflight 4.3+ that's set blackbox_sample_rate = 1/1; on INAV, blackbox_rate_num = 1 and blackbox_rate_denom = 1; on PX4, bits 4 (High rate) and 8 (Raw FIFO high-rate IMU Gyro) in SDLOG_PROFILE; on ArduPilot 4.5+, INS_RAW_LOG_OPT plus the IMU_RAW bit in LOG_BITMASK. The flash fills four times faster than at 1/4.
  2. Make sure the raw gyro is logged. From 4.5 it has its own field; on 4.0–4.4 you need debug_mode = GYRO_SCALED. Details are in the blackbox setup guide.
  3. Fly for a minute: hover, a smooth straight-line climb to 70–80% throttle, and throttle steps held for a few seconds each. The detector needs windows in many throttle bins, not just at hover.
  4. Upload the log to bbdoctor. If the resonance is unambiguous, the finding reads "Resonance at X Hz at any throttle" and comes with notch commands.
  5. Fix the hardware first and fly again. Add the notch only if the peak is still there, then take one more log: the bump at that frequency should be gone from the filtered gyro, and filtered noise shouldn't go up.
  6. Put the logging divider back to normal.
set blackbox_sample_rate = 1/1
save

The most common mistakes

When to leave it alone: bbdoctor sees no resonance, raw noise is under 4 deg/s (its "mechanics are clean" mark), filtered noise is below 1 deg/s, and the motors come down warm rather than hot. A notch won't fix a low-frequency oscillation either. In one PX4 1.17 log bbdoctor found a 42 Hz peak in the error (gyro − setpoint) on pitch only, and the motor phase pointed to P driving it. Its advice is to lower pitch P by 10% and compare the next flight, not to add a filter, and the resonance detector doesn't even look below 60 Hz.

Upload your own log to the analyzer or browse the example report. You can check a config without flying on the diff check page, which catches things like a disabled dynamic notch with no RPM filter.

FAQ

How many dynamic notches do I need with the RPM filter running?

Usually one or two. The RPM filter already removes every motor's harmonics, so the dynamic notch only has to catch what isn't tied to RPM: frame resonance and leftover prop noise. The Betaflight 4.3 tuning notes say more than two or three are rarely needed and often one is enough. Most of our 4.5 logs run dyn_notch_count = 1 at Q 500, a 2025.12 log runs two at Q 400. Every extra notch sitting low in the spectrum adds delay.

Static or dynamic notch for a frame resonance?

Fix the hardware first. If the resonance survives and a full-rate log gives you its exact frequency, use a static notch: it sits exactly on the peak and never wanders off to chase something else. The dynamic notch can handle it if the frequency is inside dyn_notch_min_hz to dyn_notch_max_hz and it has a spare notch, but with a single notch next to the RPM filter it ends up torn between the resonance and leftover motor noise.

What does dyn_notch_q mean?

It's the notch Q multiplied by 100, so dyn_notch_q = 500 means Q = 5. The −3 dB bandwidth is the centre frequency divided by Q: 40 Hz wide at 200 Hz with Q 5. Higher Q means a narrower cut and less delay in the control band, but the notch has to land on the peak more precisely. Without the RPM filter the 4.3 notes suggest Q 120–150; logs with the RPM filter usually run 350–500.

Can a notch filter fix jello in my video?

No. Jello is the camera itself vibrating, and a gyro filter only changes what the PID loop sees, so it won't calm the camera. Look for the mechanical cause: an unbalanced prop, a rough motor, a loose camera mount. A notch helps only indirectly, when the motors feed noise back into the frame. Find the frequency in the log the same way you would for a resonance.

Updated:

More guides