Optical Flow Setup Guide — ArduPilot / PX4 / INAV
One guide for the whole MTF family: the MTF-01, MTF-01P, and MTF-02 / MTF-02P all configure identically — wire the sensor to a spare UART, match the sensor's protocol to your firmware, set the parameters below, and your drone hovers indoors without GPS.
Step 0 — match the protocol to your firmware
The sensor speaks four protocols; it must be set to the one your firmware expects:
| Firmware | Sensor protocol |
|---|---|
| ArduPilot | mav_apm |
| PX4 | mav_px4 |
| INAV | msp |
| FMT / custom code | Micolink (protocol reference) |
When ordering from our store you pick the firmware variant and it arrives pre-set. To change it later, use MicoAir's MicoAssistant desktop tool (the MTF-02P can also be hard-set via solder pads).
"Distance shows up but no optical flow data" is almost always a protocol mismatch — an mav_px4 sensor on an ArduPilot board, or vice versa. Check Step 0 before anything else.
ArduPilot (≥ 4.2.0)
Serial and sensor parameters — n is the UART you wired (e.g. SERIAL5):
SERIALn_PROTOCOL = 1 # MAVLink1
SERIALn_BAUD = 115
SERIALn_OPTIONS = 1024 # Don't forward
FLOW_TYPE = 5 # MAVLink optical flow
RNGFND1_TYPE = 10 # MAVLink rangefinder
Reboot (or refresh parameters), then:
RNGFND1_MIN_CM = 1
RNGFND1_ORIENT = 25 # facing down
RNGFND1_MAX_CM = 800 # MTF-01 — use your sensor's real range:
# 1200 (MTF-01P) / 600 (MTF-02P) / 250 (MTF-02)
EKF source — flow-only indoor flight
This is the part most guides skip. Telling the EKF to trust flow velocity instead of GPS:
AHRS_EKF_TYPE = 3
EK3_SRC_OPTIONS = 0
EK3_SRC1_POSXY = 0 # no absolute XY position source
EK3_SRC1_POSZ = 2 # height from rangefinder
EK3_SRC1_VELXY = 5 # XY velocity from optical flow
EK3_SRC1_VELZ = 0
EK3_SRC1_YAW = 1 # compass
EKF source — GPS outdoors, flow indoors (advanced)
Keep GPS as source 1 and configure flow as source 2, switched from the radio. Not recommended as a first setup:
EK3_SRC2_POSXY = 0
EK3_SRC2_POSZ = 2
EK3_SRC2_VELXY = 5
EK3_SRC2_VELZ = 0
EK3_SRC2_YAW = 1
RC6_OPTION = 90 # RC6 3-position switch selects EKF source;
# middle position = source 2 (optical flow)
First confirm firmware ≥ 4.2.0. If the version is fine, your board's firmware was built without optical flow support — common on F405-class boards where flash constraints force feature cuts. Use ArduPilot's custom firmware builder to build with flow enabled, or use a board with more flash such as the H743 V2.
PX4
Sensor protocol: mav_px4. Parameters differ by firmware line:
1.12.x – 1.13.x
MAV_1_CONFIG = TELEM n # reboot after setting
MAV_1_MODE = Normal
SER_TELn_BAUD = 115200 8N1
SENS_FLOW_ROT = No rotation
EKF2_AID_MASK = use optical flow
EKF2_RNG_AID = Range aid enable
EKF2_HGT_MODE = Range sensor
1.14.x – 1.16.x
MAV_1_CONFIG = TELEM n # reboot after setting
MAV_1_MODE = Normal
SER_TELn_BAUD = 115200 8N1
EKF2_OF_CTRL = Enabled
EKF2_RNG_CTRL = Enabled
EKF2_HGT_REF = Range sensor
Reboot again; SENS_FLOW_ROT only appears in QGC after the flow sensor has been detected once (its default "No rotation" is already correct).
1.17.x and later — additionally set MAV_PROTO_VER = 1.
INAV
Sensor protocol: msp. Enable the optical flow and rangefinder sensors in the INAV configurator. Avoid INAV 7.1.1 — a known bug breaks this sensor family; use a newer (or older) release.
Verify before you fly
Connect over USB (not telemetry — see below) and open QGC's MAVLink Inspector (or Mission Planner's equivalent). You should see both DISTANCE_SENSOR and OPTICAL_FLOW_RAD messages arriving:

Message rates shown in the GCS are set by the flight controller's link bandwidth, not by the sensor — don't expect to see 100 Hz there, and don't worry about it.
Troubleshooting
Distance data but no optical flow
Two usual causes: a protocol mismatch (see Step 0), or you're connected via a telemetry radio — on a slow link PX4 selectively drops messages, so OPTICAL_FLOW_RAD may simply not be forwarded to the GCS. Check over USB before suspecting the sensor.
PX4 keeps resetting my position estimate to zero
Normal. Optical flow provides velocity only, no absolute position, so while disarmed PX4 periodically re-zeros the estimated position to bound drift.
Position hold is mushy or drifts
Check the basics the physics demands: ground texture (bare uniform floors are hard to track), light (>60 lux), altitude within the rangefinder's real range, and the sensor lens clean and unobstructed. A printed case keeps fingers and crashes off the optics.
Related guides
- MTF-01 · MTF-01P · MTF-02 / MTF-02P
- Free 3D-printable cases & mounts
- ArduPilot — Telemetry Setup Guide
Written and maintained by the Robofusion engineering team. Parameters cross-checked against MicoAir's Chinese manuals (June 2026) and ArduPilot/PX4 documentation.