VOXL ESC Calibration
Table of contents
- What Calibration Is
- Safety First
- Power Source: Battery, Not Bench Supply
- Prerequisites
- Procedure
- Reading the Plots
- Applying the Results
- Troubleshooting
What Calibration Is
Unlike hobby ESCs, ModalAI ESCs normally run closed-loop RPM control: PX4 commands an RPM, and the ESC holds it regardless of battery sag. To do this well, the ESC needs a feed-forward model of your specific motor + propeller: a quadratic fit of motor voltage versus RPM, stored in the ESC params as pwm_vs_rpm_curve_a0, a1, and a2. Calibration is the procedure that measures that curve.
When you need it:
- You are using a motor/propeller combination that ModalAI does not ship params for, or
- You changed battery cell count (e.g. 4S to 6S) for an existing combination.
When you do NOT need it:
- Stock ModalAI drones and dev kits — correct params are already loaded and available on GitLab.
- Replacing a motor or prop with an identical part. Calibration characterizes the motor/prop type, not the individual unit.
- Installing a new ESC board into an existing vehicle — just load the vehicle’s existing calibrated params onto it.
Safety First
Calibration is the highest-risk ESC operation. It runs the motor in open-loop power mode with fewer safety checks than normal RPM-mode operation, with propellers attached, at up to high power. Bolt the vehicle down rigidly, keep everyone clear of the propellers, and wear safety glasses.
- Propellers must be attached. Calibrating without props produces plausible-looking but wrong coefficients — the motor must be under real load.
- The frame or test stand must be rigidly attached to a solid structure.
- Start with a power-limited pass (
--pwm-max 50) before going to full power. - The tools abort automatically if ESC temperature exceeds 100°C; keep an eye on the live temperature output. Ideal is under 60-70°C, 80°C is acceptable, 90°C is worrying.
Power Source: Battery, Not Bench Supply
Use a battery of the nominal voltage you will fly with, not a bench power supply. Two reasons:
- Current limit. A small supply (for example a 3A wall adapter) hits its current limit as the motor loads up and its voltage sags — the ESC can’t draw the required power, and the resulting calibration is useless. If you see the voltage dropping in the tool output as power steps up, your supply is the problem.
- Regenerative braking. ESCs push energy back into the supply when decelerating. A battery absorbs this; most bench supplies cannot sink current, so the voltage spikes into the ESC’s protection diode and can eventually damage the board. See the regenerative braking explainer.
If you must use a supply: it needs an adequate current rating for your motors, set the brake_to_stop ESC param to 0 (coast to stop), avoid aggressive high-to-low RPM transitions, and step --pwm-max up gradually (40-50 first, then 60, 70, 80, 90 across runs). Calibration itself steps power upward and ends with a coast-down, so it does not produce large regen events — but the current-limit problem still applies.
Prerequisites
Before calibrating, load a params file with correct basic values for your setup — start from a generic board file and set:
num_cycles_per_rev— the motor’s pole pairs (not magnet count; typically 6 or 7 for 5-inch class motors). If this is wrong, every RPM number is wrong.vbat_nominal_mv— nominal battery voltage (e.g. 4S = 15200, 6S = 22200).motor_kv— the motor’s true kV rating (used by the spin-up procedure).spinup_type=1(sinusoidal spin-up — the reliable, recommended mode).
Then confirm basics with a low-power spin test (props on, 10% power) and check rotation direction before calibrating.
On VOXL 2, stop PX4 first and use the installed tools:
systemctl stop voxl-px4
cd /usr/share/modalai/voxl-esc-tools
The SDK-installed tools may lag the latest; for newest fixes use the voxl-esc repo dev branch. Alternatively, connect the ESC directly to a Linux PC with a USB-serial adapter — you get plots instantly and it removes VOXL 2 from the equation.
Procedure
Calibrate one ESC channel (the tool spins one motor at a time by design):
# power-limited first pass
./voxl-esc-calibrate.py --id 0 --pwm-min 10 --pwm-max 50
# full-range pass once the limited pass looks good
./voxl-esc-calibrate.py --id 0
The tool steps open-loop power from --pwm-min to --pwm-max, holds each step half a second, and fits the settled samples. It prints the three coefficients and writes calibration_results.html into the directory you ran it from. Viewing the plot requires internet access (it fetches the plotting library) — on VOXL 2 pull the file to your PC with adb pull and open it there.
On the FPV ESC (M0138), calibrate on ID 2 if you want current shown in the plots — it is the only channel that measures (total board) current. On the Mini ESC (M0129) that channel is ID 3. Current is only a sanity check; it is not used in the calibration math.
Reading the Plots
Judge the calibration by the plots, not the coefficients — a0/a1/a2 are just a curve fit and can look reasonable even when the underlying data is bad.
- Motor voltage vs RPM (the fit itself): should be a smooth shape with a slight quadratic upward trend. An upward curl at the high end means the motor isn’t running optimally — try raising
timing_advancefrom 0 to 20 and re-run. - Current vs time: roughly quadratic as power steps up. Sudden jumps, or current flatlining while voltage sags, mean supply problems or desync.
- RPM vs time: the highlighted samples are the settled ones actually used for the fit. Look for sudden jumps up or down — a jump to a bogus high RPM with low current is a desync signature.
Good reference plots are in the repo’s calibration guide.
Applying the Results
- Copy
pwm_vs_rpm_curve_a0/a1/a2into your params XML with at least 6 decimal places — truncated coefficients bend the curve. - Measure
min_rpm: spin at--power 10and read the RPM. Measuremax_rpm: spin at--power 100 --ramp-time 3.0 --timeout 3.5. - Upload and verify:
./voxl-esc-upload-params.py --params-file my_vehicle.xml
./voxl-esc-verify-params.py
If you calibrated multiple motors and want a single curve: do not average the coefficients — that produces a wrong curve. Refit one polynomial over the pooled data points instead. In practice CW and CCW props produce slightly different curves and either (or the pooled fit) works; the ESC’s PI controller absorbs small deviations.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Voltage sags as power steps up | Power supply current-limited — use a battery |
| Motor won’t even attempt to spin | Supply voltage dipping below the MOSFET driver’s ~4.5V lockout — weak supply or bad wiring |
| Motor squeals, RPM jumps to a bogus value, current low | Desync — use sinusoidal spin-up; for motors under ~800kV see the low-kV tuning guide |
| Tool aborts with overheat error | ESC hit 100°C — let it cool, add airflow, reduce --pwm-max |
| Coefficients look fine but flight is bad | Calibrated without props, wrong num_cycles_per_rev, or prop too large for the motor |
| RPM never settles between steps | Prop too large for the motor |
More depth: the repo’s calibration.md and the ESC FAQ.