My Drone Amputated My Fingerprint, and I Refused to Leave the Data Unanalyzed
TL;DR: My FPV drone injured me. Instead of guessing what happened, I pulled the Blackbox flight data, cracked it open with Python, and let…
My Drone Amputated My Fingerprint, and I Refused to Leave the Data Unanalyzed
TL;DR: My FPV drone injured me. Instead of guessing what happened, I pulled the Blackbox flight data, cracked it open with Python, and let the numbers do the talking. Spoiler: the pilot (me) gave zero commands. The data proved it — and also exposed a sensor calibration issue I didn’t know I had.
I’m a data scientist. When something breaks, I don’t guess — I look at the logs initially using https://blackbox.betaflight.com/.

Image 1 — HIMARS Log in Blackbox of BetaFlight
So when my FPV drone, called HIMARS (hehehe)… was involved in an accident and people started asking “what happened, did you give it throttle?”, my answer wasn’t defensive. It was: let me check the data.

Image 2 — My 7" Inch Drone: HIMARS — Top view
Betaflight — the firmware that runs most FPV drones — has a built-in flight data recorder. It’s called Blackbox, and it logs everything: motor outputs, RC commands, gyroscope readings, PID terms, battery voltage. Everything. At 2,000 frames per second.
The log for the incident was short. Brutally short. 295 milliseconds.
Here’s what I found when I opened it with Python.
The setup: what Betaflight’s Blackbox actually records
The exported CSV isn’t a standard CSV. It has ~142 lines of metadata before the actual data — firmware version, board info, PID configuration, motor range — and then the time-series data starts.
- Board: DAKE F405 (STM32F405).
- Firmware: Betaflight 4.4.3.
- Motor output range: DSHOT 158–2047.
- Loop time: 125µs (8kHz PID loop), logging every 4th frame = 2kHz Blackbox rate.
591 frames. 295ms. That’s the entire incident, start to finish.
Question 1: Did the pilot give any commands?
This was the first thing I needed to verify. Three independent channels to check:
Three layers of confirmation. rcCommand[3] was locked at 1000 — the absolute minimum — for all 591 frames. The RC signal was healthy the entire time (so it wasn't a "lost signal made it do something"). No failsafe phase was triggered. The flight controller was not trying to execute any rotation or thrust.

Image 3 — Forensic Report
The pilot gave zero commands. The data is unambiguous.
The last graph (F. RC Throttle — Constant at 1000 (absolute minimum) for 295ms) of the report shows that I didn’t gave any command.
Question 2: But the motors were spinning. Why?
Here’s where it gets interesting — and where a lot of people misunderstand how Betaflight works.

Image 4 — Motor output
When you arm a Betaflight drone, motors always start spinning. That’s by design. They idle at a configured minimum — in this case, 5.5% throttle — to stay responsive. Think of it like a car in neutral with the engine running.
What’s not normal is a 144 DSHOT differential between motors when the throttle is at zero.
So what was driving that differential?
Question 3: What was actually moving those motors?
I checked each PID term:

Image 5 — PID
The D-term (derivative — it responds to the rate of change of error, not the error itself) had a 0.847 correlation with the motor differential. The P-term was 0.591. The I-term and F-term were literally zero across all 591 frames.
At the peak motor spike frame:
axisP[0]= -8axisD[0]= -24 ← 3× larger than the P-term
The D-term was the main driver. Not a stuck throttle. Not a failed RC link. Not a ghost command.
Here’s the chain: idle motors create vibration → gyro picks up tiny rotation (max ±6 raw units, essentially nothing) → D-term amplifies the rate of change of that signal → motor differential of up to 144 DSHOT gets generated.
The flight controller was doing exactly what it was programmed to do. The problem was the context it was operating in.
The plot twist: an uncalibrated accelerometer
While digging through the accelerometer data, I found something unexpected.
Pitch (mean): 6.75°
Roll (mean): 2.21°
The drone was sitting on a flat surface. A correctly calibrated accelerometer on a flat surface should read ≈0° in both axes. Mine was reading 6.75° of pitch and 2.21° of roll — a systematic bias that screams “I was never calibrated after the FC was installed.”

Image 6— Gyro data
This matters a lot. In ACRO mode (which this drone was in), the accelerometer doesn’t actively control the motors — so this didn’t directly cause the accident. But here’s the risk:
If this drone ever runs Angle or Horizon mode, the FC will actively try to “correct” a 6.75° tilt that doesn’t exist — pushing motors asymmetrically to level a perfectly flat drone.
That’s a ticking time bomb.
The complete failure chain
Putting it all together:
1. Drone armed → motors start at idle (158 DSHOT / 5.5% throttle)
2. Idle motor vibration → gyro reads ±6 raw units of rotation
3. D-term amplifies the rate of change → motor differential up to 144 DSHOT
4. Individual motors briefly reach 302 DSHOT (12.7% throttle)
5. Spinning props at 5–12% throttle cause the incident
6. Uncalibrated accelerometer (6.75° bias) = additional latent risk
The drone didn’t “fly away”. It didn’t receive a command. It was doing what Betaflight always does when armed: maintaining stability with PID corrections on top of an idle throttle. The problem was having a spinning-prop drone armed near a person.
What the data can’t tell you (but I’ll say it anyway)
The data confirms what didn’t happen: no throttle, no failsafe, no RC glitch, no autonomous behavior.
What the data can’t determine is whether the incident was caused by props at idle (5.5% is still enough to lacerate skin on contact) or by the brief motor surges from the D-term. At that power level, both are plausible.
What I changed after this analysis:
- Calibrated the accelerometer — ran the calibration in Betaflight Configurator with the drone on a level surface
- Set
arm_angle = 25— Betaflight won't arm if the drone is tilted more than 25° - Added a pre-arm switch — double-switch sequence before arming
- Treat an armed drone like a loaded weapon — it goes on the ground, props away from people, before arming
The takeaway for data people
Betaflight Blackbox is a structured time-series dataset logged at 2kHz with 50+ channels. It’s basically a flight data recorder in a €30 microcontroller.
If you work with sensor data, control systems, or embedded hardware, the analysis patterns here are familiar: check the inputs (RC commands), check the outputs (motor values), check the intermediate transformations (PID terms), and look for sensor bias (accelerometer calibration).
The data didn’t just answer “what happened.” It answered “what exactly caused what” — and found a latent risk that wasn’t part of the original question.
That’s what good forensic data analysis does.
Part 2 — Final: https://medium.com/@igorcomune/my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-pt-2-final-7d1b170127d1
Full Python code and the step-by-step Colab notebook available at: link
If you’ve done forensic analysis on unusual datasets, I’d love to hear about it — drop a comment below.
Igor Comune is a Data Scientist building ML/MLOps systems from scratch — and occasionally crash-investigating drones with Python.
메타데이터
- post_id
- 2e11e11e8d4f
- slug
- my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-2e11e11e8d4f
- url
- https://medium.com/@igorcomune/my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-2e11e11e8d4f
- canonical_url
- https://medium.com/@igorcomune/my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-2e11e11e8d4f
- author_url
- https://medium.com/@igorcomune
- status
- ok
- fetched_at
- 2026-08-08 02:33:28