Wave Wave Developer Docs

Inputs & Channels

The radio's own raw control state β€” every stick, switch, and pot, plus the mixed channel output computed from them for the current model and flight mode β€” is available to your app the same way it's available to every built-in screen: a handful of root properties, read directly with no prefix. Your app.qml loads into the exact same StackView/QML context as the built-in views (see Getting Started), so there's no separate API for this β€” it's the identical input_ctrl, input_list, and chan_list that InputView.qml, ThrView.qml, and the rest of the built-in Model menus already use.

No properties match your search.

Reading control inputs

The 19 raw, unmixed inputs β€” sticks, switches, pots, and the light sensor β€” as the pilot is physically moving them right now, before any expo/rate/mixing is applied.

input_ctrl var (array)

Replaced wholesale on every telemetry tick with the radio's current raw input state. Indices 0–18 are the 19 named inputs below β€” read whichever one you need directly, no signal/connect dance required, it's just always current:

// raw value of the right stick's vertical axis (Stick RV, index 4)
var throttleRaw = input_ctrl[4]

Each value is in the raw range -16384–16384 β€” see Converting to percent below for turning it into something displayable.

Don't index past 18

The underlying payload input_ctrl is assigned from actually carries more than the 19 inputs internally (a channel count, live channel values, and the current flight-mode index, all packed in past index 18) β€” but that's an implementation detail, not part of the documented input list. Use chan_list to read channel output instead of reaching for input_ctrl past index 18.

input_list ListModel

The display name for each input_ctrl index, exactly as the built-in Model > Inputs screen shows it β€” read one with input_list.get(i).name:

Indexinput_ctrlname
0Sensor XAccelerometer, X axis
1Sensor YAccelerometer, Y axis
2Stick LVLeft stick, vertical
3Stick LHLeft stick, horizontal
4Stick RVRight stick, vertical
5Stick RHRight stick, horizontal
6Switch LDLeft switch, down position
7Switch LULeft switch, up position
8Switch LLLeft switch, left position
9Switch LRLeft switch, right position
10Switch RLRight switch, left position
11Switch RRRight switch, right position
12Switch RDRight switch, down position
13Switch RURight switch, up position
14Pot TLTop-left pot
15Pot TRTop-right pot
16Pot BLBottom-left pot
17Pot BRBottom-right pot
18N/AAmbient light sensor β€” has no friendly name in the built-in UI either.
Which stick to use Note

The pilot's Stick Mode β€” the classic RC-transmitter Mode 1–4 setting β€” is per-pilot configurable, so don't hardcode one physical stick. Read the mode with cfgGet (118) (the same locally-cached cfg_array helper mentioned in Configuration) and pick your app's stick per Wave Studio's own convention: Stick Mode 1 pairs with the left stick, every other mode (2, 3, or 4) pairs with the right stick.

cfgGet (118)Use for your app
1Stick LV / Stick LH (index 2 / 3)
2, 3, or 4Stick RV / Stick RH (index 4 / 5)
var mode = cfgGet (118)

// only Stick LV needs inverting - Stick LH, Stick RV, and Stick RH are all correct as-is
var vertical = (mode == 1) ? -input_ctrl[2] : input_ctrl[4]
var horizontal = (mode == 1) ? input_ctrl[3] : input_ctrl[5]
Only Stick LV reads inverted

input_ctrl[2] (Stick LV) increases as the stick moves in the opposite direction you'd expect β€” pushing up reads as a lower value, not higher. Negate it before using it. Stick LH (index 3), Stick RV (index 4), and Stick RH (index 5) all read correctly as-is and need no inversion.

Reading channel outputs

One entry per configured aircraft channel for the current model and flight mode β€” throttle, ailerons, elevator, rudder, gyro channels, and so on β€” already through expo/rate/mixing, unlike the raw values in input_ctrl.

chan_list ListModel

The channel count is dynamic β€” it depends on the current model's own configuration, not a fixed number β€” so read it with chan_list.count rather than assuming how many there are. Each entry (chan_list.get(i)) has these roles:

RoleMeaning
valueThe live, mixed output for this channel, raw range -16384–16384 β€” updated every telemetry tick. See Converting to percent below.
inputThe input_ctrl/input_list index this channel's control is currently bound to (-1 if unbound) β€” e.g. input_list.get(chan_list.get(i).input).name gives the physical control's name.
typeWhat this channel is, as one of the numeric roles in the table below.
idThis channel's own numeric ID.
revReverse flag.
trimTrim offset.
expoExpo curve amount.
dualrate_0 / dualrate_1Dual-rate percentages for the channel's two rate settings.
limit_0 / limit_1Travel limits, negative and positive direction.
curve_typeWhich curve shape this channel uses.
curve_val_0 … curve_val_8The 9 curve control points β€” the same data qrc:/qml/Item/Curve (see Components) is built to display.
mix_input_0 / mix_input_1 / mix_input_2Up to three channels mixed into this one.
delayServo delay/slew setting.
chan_list.get(i).type int

What role this channel plays:

ValueType
0Unknown
1Throttle
2Gyro value
3Gyro flight mode
4Gyro
5Aileron
6Elevator
7Rudder
8Pitch
9Flap
10Gear
11Brake
12Bank (flight mode)
13Light
14Smoke
15Rescue
16Stabi (Spirit Stabilisation Controller)
17GeoFunc
18Elevon
19Rudvator

Converting to percent

Both input_ctrl[i] and chan_list.get(i).value share the same raw range, -16384–16384, and the built-in UI converts both the same way β€” which formula to use depends on whether what you're displaying is naturally symmetric around center or naturally one-directional.

Symmetric, -100%–100%

The general case, and what almost everything should use β€” sticks, ailerons, elevator, rudder, gyro channels, most pots. Divide by 163.84:

var pct = Math.round (input_ctrl[4] / 163.84)              // -100..100
var pct = Math.round (chan_list.get(0).value / 163.84)   // -100..100

This is exactly what the built-in Model menus already do β€” pot values in the Model > Check screen, gyro sensitivity in Model > Gyro, mix amounts in Model > Mix all read this way.

Unidirectional, 0%–100% Note

A different formula for a control that's meant to read as a one-directional 0–100 gauge rather than a signed one β€” divide by 327.68 and add the offset that recenters it:

var pct = Math.round (50 + (chan_list.get(throttleIdx).value / 327.68))   // 0..100
Throttle specifically uses this formula

The built-in Throttle screens (ThrView.qml, the Spirit Controller's ThrGovView.qml) read the throttle channel's value with exactly 50 + value / 327.68, not the / 163.84 form above β€” because throttle is displayed as a plain 0–100% gauge, not a signed stick position. If you're building your own throttle readout, match this formula rather than the general symmetric one, or your percentage will read roughly half of what the built-in UI shows for the same physical stick position.

The same 327.68 formula (without the + 50, since the source is already one-directional) also shows up for volume-style pot readouts in the built-in Sound settings.