Skip to content Link Search Menu Expand Document
ModalAI DOCS
Store

VTX Air Unit Software Guide

Configure video, OSD, and link settings on the VTX air unit.

Table of contents

  1. VOXL SDK Support
    1. SDK Versions
    2. Core Services
  2. voxl-vtx Service
    1. voxl-configure-vtx
    2. Configuration File Reference
      1. Wireless
      2. Forward Error Correction
      3. Video Profiles
      4. Adaptive Link
      5. Zoom
      6. Telemetry & Link Behavior
      7. UDP Mode (IP networks)
      8. RF / IP Automatic Fallback
      9. System
      10. AR Waypoints
    3. Supported Frequencies
    4. TX Power
    5. Encryption Key / Binding
    6. Live Control & Inspection
  3. voxl-osd Service
    1. voxl-configure-osd
    2. Configuration File Reference
    3. OSD Menu
  4. Using External Flight Controller (MSP DisplayPort)
    1. Betaflight Note (Rotor Riot F7)
  5. ADB Access
  6. Using VTX as Standard WiFi Modem
    1. WiFi Dongle Modes
    2. VTX WiFi Limitation
    3. Practical Implications

VOXL SDK Support

SDK Versions

VOXL SDK 1.8.0 is the current release (downloads); the VTX is supported from SDK 1.6.0. Stinger ships with SDK 1.8.0.

Run the same SDK version on the VTX and the VRX Ground Unit. voxl-vtx 3.3 (SDK 1.8.0) requires voxl-osd 1.2.0 or newer on the drone, and an SDK 1.8.0 drone needs VRX SDK 1.8.0. This page describes SDK 1.8.0; on SDK 1.6 and older the profile list, adaptive link, zoom, and AR waypoint settings below do not exist.

Core Services

The VTX runs the standard VOXL SDK. The services below do the video work:

ServiceConfig fileRole
voxl-camera-server/etc/modalai/voxl-camera-server.confPublishes camera pipes, including the encoded video streams
voxl-osd/etc/modalai/voxl-osd.confRenders the on-screen display over the video
voxl-vtx/etc/modalai/voxl-vtx.confTransmits video + telemetry over the digital link

voxl-vtx Service

voxl-vtx is the digital video transmitter service. It pulls encoded video from a camera pipe, applies forward error correction, and transmits it over the RF link (or UDP over an IP network). It runs as the systemd service voxl-vtx.service (starts after voxl-camera-server, restarts automatically).

The service is not enabled by simply installing the package — use voxl-configure-vtx:

voxl-configure-vtx --enable            # load the VTX kernel module and enable the service
voxl-configure-vtx --disable           # restore the standard WiFi driver and disable the service

The VTX radio and standard WiFi share the same hardware. To use WiFi, disable the VTX first — see Using VTX as Standard WiFi Modem.

voxl-configure-vtx

voxl-configure-vtx manages /etc/modalai/voxl-vtx.conf and can push settings live to a running service:

OptionMeaning
-h, --helpShow the help message
-l, --listShow the current configuration
-F, --frequency <MHz>Set the center frequency
-a, --active_profile_idx <n>Set the active video profile
-m, --mcs <n>Set the MCS index of the active profile
-s, --source <pipe>Set the video pipe of the active profile
-p, --power <idx>Set TX power by index for the active profile (not saved)
-P, --power-mw <mW>Set TX power in mW for the active profile
-t, --toggleToggle between VTX mode and SoftAP (WiFi) mode
-e, --enableLoad the VTX kernel module and enable voxl-vtx
-d, --disableRestore the standard WiFi driver and disable voxl-vtx
-f, --factory_enableEnable and write the default configuration
-L, --factory_enable_ltePreset for LTE
-I, --factory_enable_fiberPreset for fiber
-D, --factory_enable_doodlePreset for Doodle Labs radios
--factory_enable_dtcPreset for DTC radios
--factory_enable_silvusPreset for Silvus radios (SDK 1.8.0+)
--d0013Preset for Stinger (D0013)
--lepton_enableAdd a Lepton thermal profile
--tracking_stereoUse Tracking Left in place of Tracking Front for stereo tracking setups (SDK 1.8.0+)
--enable_ip_fallbackEnable RF / IP automatic fallback
--enable_rc_deadmanEnable the RC dead man’s switch (rc_deadman_en)
-A, --add_udp_receiver <ip:port>Add a UDP receiver
-R, --remove_udp_receiver <ip:port>Remove a UDP receiver
-C 1, --clear_udp_receivers 1Remove all UDP receivers (the option takes a value)
--ar_waypoints enable\|disableTurn AR waypoint rendering on or off
-w, --wizardStart the interactive wizard

Useful behaviors:

  • Running with a missing config file writes factory defaults first.
  • --wizard walks every setting interactively, including a video-profile editor.
  • Live changes (frequency, MCS, power, profile) are pushed to the running service via its control pipe — no restart needed.
  • The radio presets (-L, -I, -D, --factory_enable_dtc, --factory_enable_silvus) and vehicle presets (--d0013) write a complete configuration. --lepton_enable and --tracking_stereo change the camera profiles and can be combined with a preset.

Configuration File Reference

/etc/modalai/voxl-vtx.conf (JSON). Created with defaults on first run. The VRX must match frequency, bandwidth, and the FEC settings.

Wireless

FieldDefaultMeaning
frequency5805Center frequency in MHz (VRX must match)
bandwidth20Channel bandwidth in MHz: 20 or 40 (VRX must match)
card"wlan0"Radio interface name
enable_pcaptrueEnable the RF transmit path
enable_pittruePIT mode: reduced TX power for bench testing
enable_stbc0Space-Time Block Coding (spatial streams); off by default in SDK 1.8.0
regulatory_mode"off""off" or "fcc" — when set, DFS frequencies are blocked and power is limited where required

Forward Error Correction

FieldDefaultMeaning
enable_fectrueEnable FEC (VRX must match)
fec_percent-1FEC overhead %: -1 = auto (min 75%), 0 = headers only, >0 = explicit
fec_block_size30Fragments per FEC block (larger = more compute)

Video Profiles

profiles is an array of video stream profiles, selected by active_profile_idx, an RC switch, joystick buttons, or the OSD menu. In SDK 1.8.0, voxl-configure-vtx builds the list in this order:

ProfileSource pipeAdded whenMCSMTUPower (mW)
Adaptive (default, index 0)hires_default_misp_encodedAlways010001000
Bosonboson_misp_encodedA Boson camera is configured013411000
Tracking Fronttracking_front_misp_encodedA tracking_front camera is configured010001000
Tracking Lefttracking_left_misp_encoded--tracking_stereo (replaces Tracking Front)010001000
Tracking Downtracking_down_misp_encodedA tracking_down camera is configured010001000
Leptonlepton0_encoded--lepton_enable013411000
Long Rangehires_long_range_misp_encodedAlways07501000
Low Latencyhires_low_latency_misp_encodedAlways31341750

Camera profiles are detected from /etc/modalai/voxl-camera-server.conf when a vehicle preset, a radio preset, --lepton_enable, or --tracking_stereo is used. The Adaptive profile replaces the old Default profile and has the adaptive link enabled.

With a vehicle preset such as --d0013, the RC switch reaches only the camera profiles (Adaptive, Boson, Tracking, Lepton; at most five), and Long Range and Low Latency are selected from the OSD menu. The --d0013 preset sets rc_toggle to channel 11. Without a vehicle preset the RC switch reaches every profile except Long Range, again at most five.

FieldDefaultMeaning
active_profile_idx0Index of the active profile
rc_toggle-1RC channel that cycles profiles (-1 = off)
rc_switch_profiles[]Profile indices reachable from the RC switch (written by the presets as described above)
osd_rc_toggle-1RC channel for OSD on/off (LOW = on, HIGH = off)
osd_joystick_toggle-1Joystick button for OSD on/off
led_joystick_button_off3Joystick button that selects LEDs off when pressed alone (-1 = off)
led_joystick_button_ir4Joystick button that selects IR LEDs when pressed alone (-1 = off). Neither pressed = overt LEDs on

Each profile entry:

FieldMeaning
nameProfile name shown in the OSD menu
sourceMPA pipe carrying encoded video (e.g. hires_default_misp_encoded)
mcsModulation/Coding Scheme 0-7 (higher = faster, less robust)
mtuPayload size in bytes (1341 max for H.265, 1342 for H.264)
powerTX power in mW, 0-1000; -1 = maximum
udp_camera_bitrate_bpsRequested camera bitrate when streaming over UDP
invert_toggleRC channel for white/black hot (Boson profiles only, -1 = off; the Boson profile uses 12)
joystick_toggleJoystick button that selects this profile (-1 = none)
ai_detection_enableSend AI detections to the VRX for this profile
ai_detection_sourceDetection pipe (default object_tracker_meta)
ai_detection_qtyMax detected objects sent to the VRX
ai_detection_thresholdDetection confidence threshold 0.0-1.0
enable_adaptive_link and adaptive_link_*Per-profile adaptive link settings, see Adaptive Link

New in SDK 1.8.0. With enable_adaptive_link set on a profile, the VTX adjusts the MCS index and the camera bitrate and frame rate from the SNR and packet loss the VRX reports, so the video holds up as range changes. Only the Adaptive profile has it enabled by default. It needs a VRX that sends link-quality responses (enable_lq_resp, which voxl-configure-vrx turns on). With two VRX units on one VTX, turn it off on the observer’s VRX from the VRX SETTINGS menu so only the pilot’s VRX drives the adaptive link.

FieldDefaultMeaning
enable_adaptive_linktrue (Adaptive profile)Enable adaptive link for this profile
adaptive_link_timeout_ms800Time without link stats from the VRX before dropping to the most robust level
adaptive_link_up_hold_count2Consecutive SNR readings above snr_up needed before stepping to a better level
adaptive_link_loss_down_pct10Smoothed VRX packet loss (%) at or above which the VTX steps down even when SNR is good (0 = off)
adaptive_link_loss_down_hold_ms500Time the smoothed loss must stay above adaptive_link_loss_down_pct before stepping down
adaptive_link_loss_up_max_pct5Smoothed loss must be at or below this to step up (-1 = no gate)
adaptive_link_levelssee belowLevels ordered best to worst

Each level sets mcs, bitrate_mbps, fps, num_p_frames (-1 = leave the encoder GOP alone), snr_down (step to the next worse level below this SNR, -1 = never), and snr_up (step to the next better level above this SNR, -1 = never). The Adaptive profile defaults:

LevelMCSBitrateFPSsnr_downsnr_up
125 Mbps6022-1
212.5 Mbps601526
301.5 Mbps30-120

Set adaptive_link_log to "on" or "arm" to record the controller’s inputs and decisions to a CSV in /data/mvx/vtx/logs/.

Zoom

FieldDefaultMeaning
zoom_ch12RC channel that controls digital zoom on the hires stream
zoom_max4.0Maximum zoom factor
zoom_ch_deadband10Deadband on the zoom channel
zoom_joystick_buttons[14, 15, 16, 17, 18, 19]Joystick buttons for zoom presets, evenly spaced from 1.0x to zoom_max. Buttons 0-15 come from MAVLink MANUAL_CONTROL.buttons, 16-31 from buttons2. [] turns them off; works alongside zoom_ch

Channel 12 is shared with white/black hot on the Boson profile; SDK 1.8.0 resolves the conflict so the wheel zooms on hires streams and switches white/black hot on the Boson stream. With an external flight controller, zoom and white/black hot are also controlled over MSP (SDK 1.8.0+).

FieldDefaultMeaning
info_rate_hz5Rate VTX info packets are sent to the VRX
mavlink_telem_rate_hz30Rate MAVLink telemetry is forwarded to the VRX
lq_quiet_timeout_ms5After a link-stats request, hold non-video transmissions until the VRX answers or this time passes (0 = off). MAVLink is held only while armed
team_race_en"off"Team race behavior: "off", "on", or "auto" (detect from the ELRS receiver settings)
team_race_tx_timeout_ms0How long to keep transmitting after an ELRS failsafe in team race mode
rc_deadman_enfalseStop all TX when the flight controller stops reporting a healthy RC link (MAVLink SYS_STATUS RC receiver health, or the external FC RC failsafe). TX resumes when RC recovers
rc_deadman_tx_timeout_ms60000How long to keep transmitting after RC loss before stopping

UDP Mode (IP networks)

For streaming over LTE, Doodle Labs, DTC, or wired IP networks instead of (or alongside) the RF link. See the VRX Developer Guide for the full walkthrough.

FieldDefaultMeaning
udpfalseUse UDP instead of RF packet injection
udp_interface_ip""Local IP of the interface to transmit from
udp_interface_rx_port50001Local port to listen on
udp_interface_tx_port-1Local transmit port (-1 = OS assigns)
udp_receiver_configs[]Remote receivers, each {"ip": ..., "port": ...}

RF / IP Automatic Fallback

With both RF and UDP configured, the VTX can move video to IP automatically when the RF link degrades, and back when it recovers. Enable with voxl-configure-vtx --enable_ip_fallback.

FieldDefaultMeaning
enable_ip_fallbackfalseEnable automatic RF/IP switching
snr_low_threshold15Switch RF→IP when RF SNR (dB) sustains below this
snr_high_threshold20Switch IP→RF when RF SNR sustains above this (hysteresis)
link_switch_dwell_ms1000How long the condition must hold before switching
ip_liveness_timeout_ms2000IP counts as available only if a packet arrived this recently
pcap_liveness_timeout_ms2000If RF goes silent this long and IP is up, switch immediately

The VRX shows the current RF/IP source on its OSD.

System

FieldDefaultMeaning
i2c_port0I2C bus for the power/temperature sensor (-1 disables)
perf_modefalsePerformance CPU governor while armed (lower latency)
disable_transmissionsfalseDisable all wireless transmission (test/debug)
debug_log"off"Disk logging: "off", "on", or "arm" (log when armed)
adaptive_link_log"off"Adaptive link CSV logging: "off", "on", or "arm"

AR Waypoints

SDK 1.8.0 adds AR waypoint rendering on the VRX, controlled by ar_waypoints_enabled (default false), ar_home_waypoint_enabled (home position, default true), and ar_location_waypoints_enabled (uploaded mission waypoints, default false), or with voxl-configure-vtx --ar_waypoints enable|disable. AR waypoints are not supported on Stinger (D0013) or the VTX Air Unit; the OSD menu shows UNSUPPORTED VEHICLE SKU there.

Supported Frequencies

voxl-configure-vtx --frequency accepts the following center frequencies (MHz). Default is 5805 (channel 161); bandwidth may be 20 or 40 MHz.

BandFrequencies
2.4 GHz2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484
5 GHz5160, 5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5340, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5720, 5745, 5765, 5785, 5805, 5825, 5845, 5865, 5885

The OSD menu’s CHANNEL list ends at 5865 MHz (channel 173); 5885 MHz can only be set from the command line.

TX Power

  • Per-profile power is set in milliwatts (0-1000); -1 means maximum power.
  • voxl-configure-vtx --power-mw <mW> changes the active profile’s power live and persists it.
  • PIT mode (enable_pit) keeps TX power at a bench-safe minimum; toggle it from the OSD menu when ready to fly.

Encryption Key / Binding

VTX and VRX bind by sharing an encryption key file — there is no over-the-air pairing.

  • Units ship with a default key and will link out of the box.
  • Generate a new key with voxl-vtx-keygen (on target, or any Linux host): -b <bind_phrase> makes the key deterministic from the phrase; without -b a random key is generated. Output is vtx.key.
  • To install a key, copy vtx.key onto a USB flash drive and plug it into the unit — it is detected and installed to /data/modalai/vtx.key automatically. Do this on both the VTX and VRX.
  • The VRX can also generate and provision a new key from its buttons — see the VRX Quick Start Guide.

Live Control & Inspection

A running voxl-vtx accepts commands on its control pipe:

voxl-send-command vtx_latency set_frequency 5805
voxl-send-command vtx_latency set_mcs 3
voxl-send-command vtx_latency set_mw_power 500
voxl-send-command vtx_latency set_profile_idx 1
voxl-send-command vtx_latency set_pit_mode 0

To watch link stats live (latency, throughput, temperature, TX power, FEC):

voxl-inspect-vtx -n

voxl-osd Service

voxl-osd renders the on-screen display: telemetry, flight mode, VIO state, warnings, and more, composited over the FPV video. It never touches pixels directly. It draws a character-cell text canvas and streams it as MSP DisplayPort commands, which voxl-vtx composites into the transmitted video. Alongside the canvas, voxl-osd sends structured MSP messages (190 MSP_VOXL_TELEM, 191 MSP_VOXL_STRINGS, 192 MSP_VOXL_MENU) that the VTX relays to the VRX, where the SDK 1.8.0 VRX draws its own OSD from them. This is why the VRX and drone must run the same SDK; see voxl-osd. The full pipe, config, and menu reference is on the voxl-osd page; source is at voxl-public/voxl-sdk/services/voxl-osd.

By default it consumes PX4 telemetry over MPA (mavlink_onboard), plus VIO quality, VFC state, VTX temperature/power, and CPU stats pipes.

voxl-configure-osd

voxl-configure-osd factory_enable              # reset config to defaults and enable
voxl-configure-osd factory_enable_no_compass   # defaults without the compass tape
voxl-configure-osd external_fc                 # OSD for an external (MSP) flight controller
voxl-configure-osd hdzero                      # output MSP DisplayPort over UART to an HDZero VTX
voxl-configure-osd enable | disable

Configuration File Reference

/etc/modalai/voxl-osd.conf (JSON), created with defaults on first run.

Positioning: every screen element has a *_col / *_row pair — a character cell on the OSD canvas, origin top-left. Set either to -1 to hide that element. Elements include RSSI, armed/disarmed status, flight mode, lat/lon, MGRS grid, velocity, altitude, distance-to-home, crosshair, compass, craft name, VTX temperature/power, and CPU warnings. Battery voltage, per-cell voltage, and current draw are fixed positions.

Key toggles and behavior fields:

FieldDefaultMeaning
show_compass_tapetrueScrolling compass tape at the top of the OSD
show_compass_degreestrueNumeric heading in degrees
show_mgrstrueMGRS grid reference line
mgrs_precision5MGRS digits (0-5)
compass_fov_deg120Compass tape field of view
craft_name""Free-text craft name shown on screen
show_vtx_cpu_mem_usagefalseVTX CPU/memory usage lines
input_protocol11 = MAVLink, 2 = MSP
input_type11 = MPA pipes, 2 = UART
input_port""UART device when input_type is 2 (e.g. /dev/ttyHS1)
output_type10 = none, 1 = MPA (to voxl-vtx), 2 = UART (HDZero), 3 = both
output_port""UART device when output includes UART
resolution1OSD canvas: 0 = SD 30x16, 1 = HD 50x18, 2 = HD 30x16, 3 = HD 53x20

OSD Menu

With the vehicle disarmed, open the on-screen menu with the RC sticks: yaw up + throttle down + roll down + pitch down. The menu sets the VTX channel, profile, and PIT mode, the flight mode, and the ADVANCED options (local recording, MAVLink forwarding, battery cells, logging, AR waypoints, RC channel view, failsafe, ELRS), and opens the VRX SETTINGS menu (SDK 1.8.0+). The full tree is on the voxl-osd page. When flying over IP with voxl-joystick-server instead of RC, the menu responds to the joystick as well.

Using External Flight Controller (MSP DisplayPort)

The VTX can serve as the digital video system for a non-VOXL flight controller speaking MSP over UART:

voxl-configure-osd external_fc

This switches voxl-osd to poll the external FC over the OSD UART (arm state, RC, status) and render the OSD from it — no MAVLink link required. See the VTX Quick Start Guide for wiring and cable options.

Betaflight Note (Rotor Riot F7)

The UART for DVTX had a bug in the 4.5 Betaflight firmware that we tested against, so we fixed it using the 4.5 maintenance branch. Here’s a docker project that can build the FW like we did:

https://gitlab.com/voxl-public/support/betaflight-build-docker

ADB Access

The USB-C port is a standard VOXL 2 Mini USB-C port, with ADB access as needed.

Using VTX as Standard WiFi Modem

The following procedure applies to VTX-enabled sUAS (e.g. D0013 Stinger) or the stand-alone (MVX-T0001).

The VTX radio and standard WiFi are the same hardware. To switch to SoftAP or Station mode, first disable the VTX (this restores the standard WiFi driver), then configure WiFi with voxl-wifi:

voxl-configure-vtx --disable
voxl-wifi softap5              # or your desired voxl-wifi mode

When you are done using WiFi, re-enable the VTX:

voxl-configure-vtx --enable

WiFi Dongle Modes

When using an external USB WiFi dongle, two operation modes are supported:

  • Station Mode: The drone connects to a nearby WiFi access point (such as a router or mobile hotspot). This allows the drone to access the internet through the connected network.

  • SoftAP Mode: The drone creates its own WiFi access point (hotspot). Other devices (such as laptops, tablets, or ground control stations) can connect directly to the drone’s hotspot for communication.

VTX WiFi Limitation

If no external WiFi dongle is used and the VTX’s built-in radio is relied upon, there is an important limitation currently:

  • Station Mode is not available. The VTX cannot directly connect to an external WiFi network for internet access.

  • SoftAP Mode remains available. By running voxl-wifi and selecting the softap5 option, the VTX can still create its own hotspot. This allows ground devices to connect directly to the drone’s WiFi network for data transfer, but does not provide internet connectivity.

Practical Implications

  • Use a WiFi dongle if your application requires the drone to join an existing WiFi network and gain internet access.
  • Use the built-in VTX SoftAP mode (softap5) when you only need a direct peer-to-peer WiFi link between the drone and a controller device, without internet access.