OpenTx - Key Concepts

Mike Shellim 25 July 2014
Updated: 21 Sept 2017


OpenTx is a uniquely flexible operating system, and if you've come from a brand like Futaba or Spektrum then you'll find the way of working a little unfamiliar. My aim with this article is to shed some light on how it works, and to enable you to design your own setups with confidence.

I'll cover the following topics:

Examples will be illustrated either with screenshots or as text boxes, as appropriate.


OpenTx is unique. In place of the multiplicity of complex menus on other systems, OpenTx has just seven menus, and each is completely generic. This concept of generic simplicity extends to the mixers.

Don't be fooled though. Rather like Lego, the simple elements at the heart of OpenTx can be used to build powerful solutions, limited only by your imagination.

As with any new system, it pays to do a little homework first. So without further ado, let's learn how OpenTx converts you stick movements into servo commands.

OpenTx: the processing loop

Several times a second, OpenTx executes a 'processing loop'. With each cycle, the position of all the controls are read, any mixing is applied, the channel outputs are calculated. At the end of the cycle, the channel commands are passed to the RF module for onward transmission.


There are three key processing 'layers' which are marked in blue. Each of these has an associated menu ('INPUTS', 'MIXERS' and 'OUTPUTS') where you can alter various parameters. A change in one layer propagates to all lower layers.

The starting point: Sources

Sources is a generic terms for your transmitter's sticks, trims and pots. Sources are used in several of the OpenTx menus. Each source has a unique identifier, for example,

At the start of the processing cycle, OpenTx reads the position of each source, and assigns a value between -100 and 100. A value of zero corresponds to centre; left/down is negative; right/up is positive. So for example,

These values can be monitored in real time in the ANALOG INPUTS menu of your transmitter.

Channels (MIXERS and OUTPUTS menu)

The Taranis can command up to 32 freely assignable channels. The lowest numbered channels are normally assigned to devices such as servos, ESCs, flight controllers etc. A channel which is not assigned to any device may be left unused, or employed as a 'high channel'.

Management of channels is split between the MIXERS and OUTPUTS menus. The OUTPUTS menu is where you give a channel a name, and - if it drives a servo - set the servo centre and limits.

Here's a view of the OUTPUTS menu showing the channel configuration for an 'RES' sailplane. I've named the channels 'Rudder', 'Elev' and 'Spoilr' to describe their function:


Note that this menu doesn't say anything about how each channel is driven - or even that it's driven at all! For that, we need to define some mixers...

Mixers (MIXER menu)

So far we've looked at sources and channels in isolation. We need some way to link them, and that is the job of a mixer. Mixers act as the 'wiring' between sources and channels; they define which channels should respond as you move a control, also how the channels should respond.

Mixers in OpenTx are very simple constructs:

The key to designing a setup is to identify all the interactions.

How to design a setup from scratch

Here's a simple 6-step design method which I use and recommend for all applications, be they simple or complex.

Flying wing example

To illustrate the method, we'll use the example of a 2-channel flying wing. While almost trivially simple, it shows the power and elegance of OpenTx's mixing model.

Our flying wing has a pair of elevons driven by the elevator and aileron sticks:

Step 1. List the sources

The first step is to list all the sources, that is the controls that you'll use to fly the model. For our flying wing example, we use just the elevator and aileron sticks, so:

The trims are included by default, so there is no need to list these separately. You can also ignore switches, flight modes etc.

Step 2. List the servo channels

The second step is to list the channels we'll use. These will correspond to the numbered channels on the receiver. For our flying wing, we'll assign the first two channels, so this what the OUTPUTS menu looks like:


Step 3. Identify interactions

In this key step, identify the interactions between the sources (sticks) and the channels (servos). A formal method is as follows:

For our flying wing, the first source is Ail (aileron stick). When the stick is moved, both servos must respond. The interactions for the first source can therefore be written as:

Similarly, the interactions for the second source (elevator stick) are as follows:

Each interaction will give rise to a mix, so for our flying wing there will be four mixes in total. Later you can selectively disable mixes according to a switch and/or flight mode.

Note that we're not interested in how the channels are affected, just the fact that the interactions exist.

Step 4: Convert interactions into mixer definitions

Next, swap the left and right sides of each interaction so that they read as "channel is affected by source". This form corresponds to data entry in the MIXER menu.

Step 5: Reorder interactions by channel number

That's all the leg work done, just one last task: re-order the mixer definitions so that they're grouped by channel. This corresponds to the order in the MIXER menu.

Step 6: Enter definitions into the MIXER menu

Finally, enter the interactions as mixer definitions:

The '+=' means on each line shows that the mixes are additive.
The '100' on each line indicates that 100% of the source value is passed to the output. By reversing the sign, we can reverse the effect of mix. (For our flying wing example, we should set one of the aileron weights to -100%, more on that later).

Designing for complex setups.

The design approach above can be applied to complex setups. If you're familiar with F3X sailplanes, you may wish to look at interactions and mixes for F3X sailplanes. Such a scheme will normally be optimised by means of Inputs (described later in this article), GVARs and cascading mixers.

Adjusting control surface travel

So far we haven't said anything about control surface travel. Two menus which influence this are INPUTS and MIXERS via their weight parameters. Adjustments in the INPUTS layer propagate through to the MIXERS layer and are cumulative.

Finally, a scaling and offset are applied in the OUTPUTS layer. Typically this will be set to match the servo characteristics and linkage geometry.

In this section, we'll look at the MIXERS menu. Later sections will deal with INPUTS and OUTPUTS.

Setting mixer weights

Continuing with our flying wing example, let's see how to achieve the required control movements by adjusting mixer weights:


CH1 (right elevon)

Src = 'Ail', weight=90%
Src = 'Ele', weight=30%


CH2 (left elevon)

Src = 'Ail', weight=-90%
Src = 'Ele, weight=30%

That's our flying wing setup completed! But hey, it can be improved...

Using Inputs (INPUTS menu)

Our flying wing setup above has some major shortcoming: in order to adjust a control rate, or expo, we must alter mixer weights in two places:


CH1 (right elevon)

Src = 'Ail', weight=90%
Src = 'Ele', weight=30%


CH2 (left elevon)

Src = 'Ail', weight=-90%
Src = 'Ele, weight=30

Wouldn't it be nice if we could make a single adjustment? We can, by using Inputs (introduced in OpenTx v. 2.0).

Think of an Input as a preconditioned source with rates and expo built in. For example, here's an input based on the aileron stick (Ail), with weight 90% and 10% expo.

Inputs are displayed in the menus with a leading 'I' on an inverted background. I'll represent this using '[I]'.

Inputs can be used instead of 'raw' sources in most menus in OpenTx. Later, we'll see later how inputs can be applied to the flying wing example. First let's see how to create and manage inputs in more detail:

Managing inputs

OpenTx provides a maximum of 32 inputs. These are managed in the INPUTS menu.

Each input has an identifier of the form [I1], [I2]. Note that the number is fixed, and unrelated to channel numbers.

By default, inputs are blank. In order to do anything useful, you must:

Source is the underlying physical control - for example Ail, Thr, LS etc.
Weight is the associated rate (0 - 100%)
Diff and Expo: set as required

When you create a new model, OpenTx provides pre-cooked inputs for the main flight controls: [I1]Ail, [I2]Ele, [I3]Thr, [I4]Rud. It also pre-defines four mixers which link these inputs to specific channels (the default order is defined in the Radio Settings menu). However this does not limit you in any way. You can alter the mixers so they link the inputs to different channels. You can also define your inputs, and clear any which are not needed.

The use of inputs is optional; just because they're defined doesn't mean you have to use them - you can still use the raw stick as source where it's more appropriate.

Using inputs (flying wing example)

Let's modify our flying wing example to use inputs as mixer sources. The first task is to define a couple of inputs. Any inputs will do, let's use [I1] and [I2] .

The sources will the aileron and elevator sticks. We'll name the inputs 'Ail' and 'Ele' and set values for weight and expo:


The next task is to modify the mixers. Previously, they used Ail and Ele as sources, we'll change these to [I]Ail and [I]Ele.

Also, since the control movements are now specified in inputs, we reset the mixer weights to 100%.


The OUTPUTS menu remains unchanged:


To alter the movement of both elevons, we only need to make one adjustment (to weight), in the INPUTS menu!

Choosing between Inputs and sticks

We've seen how the source of a mix can be specified either as an Input (for example [I1]Ail), or as a raw source (Ail) . So which to choose? A good rule of thumb is as follows:

It's a good idea to clear unused inputs so they don't clutter up the INPUTS screen.

Mixer and channel outputs

In this section we'll look in more detail how OpenTx converts stick movements into position commands. An understanding will be useful when debugging.

OpenTx performs two stages of calculation, first at the level of the mixers, and then for the channel as a whole.

Mixer output value

For each mix, OpenTx calculates the mixer output according the weight (and other parameters we'll look at later). Taking our flying wing example, at any moment the mixer outputs are as follows:

Channel 1

mix_output_1 = Ail_stick_value x 90%

mix_output_2 = Ele_stick_value x 30%


Channel 2

mix_output_1 = Ail_stick_value x -90%

mix_output_2 = Ele_stick_value x 30%

Channel output value

OpenTx then aggregates the mixer outputs for each channel. The result is the channel output value. This represents the commanded position. Using our flying wing:

ch1_output = (Ail_stick_val x 90%)+(Ele_stick_val x 30%)
ch2_output = (Ail_stick_val x -90%)+(Ele_stick_val x 30%)

Let's enter some numbers. Recall that stick values vary between -100 and +100, with zero in the centre:

Aileron Elevator CH1 CH2
(centre) 0  (centre) 0 0 0
(full  right) 100% (centre) 0 90+0=90 -90+0=-90
(full left) -100%  (centre) 0  -90+0=-90 90+0=90
(centre) 0 (full forward) 100% 0+30=30 0+30=30
(half right) 50% (half forward) 50%  45+15=60 -45+15=-30
(full  right) 100% (full forward) 100% 90+30=120 -90+30=-60

The last line shows the effect of "stick in the corner" - note the commanded position for CH1 is 120. OpenTx automatically clips servo commands to +/- 100, in order to keep servo travel within defined bounds. More on that later.

More about mixers

OpenTx offers a number of mechanisms for conditioning the output of a mix. We've already looked at weight. Other parameters include offset, expo or diff, functions and curves.


The offset parameter adds a positive or negative value after the weight has been applied. The governing equation is:

Output = (Source * weight) + Offset

In the following mixer line, the output varies from -80 to +120 as S1 is rotated.

Src = 'S1', wt=100%, offset=20

When you create a new mix, default are: weight=100% and offset=0 i.e. the source value is passed through unchanged.

Using offsets for throttle, crow and elevator compensation

Throttle, crow brakes and camber differ from the main flight controls in that the idle position is with the control fully forward or back (instead of at centre). When these controls are used as the source of a mix, and using the default mix parameters, the mix will output 100 or -100 in the idle position. This is not normally what's wanted! In order for the mix to generate zero at the idle position, it's necessary to specify a non-zero value for the mix offset.

Example: elevator channel on an electric sailplane.

The elevator channel in an electric mode will typically have two mixes:


CH2 (elevator)

Src=Ele, wt=100%, offset = 0

Src=Thr, wt=20%, offset=20

In the above example, setting wt=offset=20% will vary the mix from 0 to 40 as the throttle stick is moved from the fully back position. To change the idle position to fully forward, change the sign of weight.

Note: offsets should be used sparingly! Never use them to make ad-hoc adjustments to your servo centres - use Subtrim for that.

Diff, expo, functions and curves

In addition to weight & offset, the mixer editor in OpenTx allows you to specify one additional option from the following:

The 'Curve' option provides the most granularity - it can implement all the other options, but requires the most data entry.

How to implement aileron diff

There are one or two gotchas with aileron diff. First, here's the correct way of doing it:



Src=Ail, wt=90%, expo=10, diff=0



Src=Ele, wt=30%, expo=15, diff=0



CH1 (right elevon)

Src = [I1], wt=100%, diff=20%
Src = [I2], wt=100%


CH2 (left elevon)

Src = [I1], wt=-100%, diff=20%
Src = [I2], wt=100%

You will see that we applied diff separately for each aileron mix, and not in the INPUTS. This is because diff in inputs produces an asymmetric stick response. We want the servo response to be asymmetric, so it aileron diff must be specified at the level of each aileron channel.

To summarise: specify diff separately for each aileron channel. Do not specify diff at the Input level.

[Note: to avoid having to enter the same diff value twice, use a GVAR.]

Including/excluding trims

By default, trim values are included in source values. You can exclude trims on a per-mixer basis. You do this by unchecking "Include Trim" in the mixer dialog.

For our flying wing example, both aileron and elevator trims must be active, so we'll use the default settings.

Order of processing

When calculating the output of a mix, OpenTx first applies source trims (if enabled for the mix). Then it applies the function (diff, function, curve, expo), followed by weight, and finally adds the offset. Order may be important when combining operators especially where offsets are involved.

Channel clipping

We've seen how the channel output is calculated as the sum of all these the mixer outputs:

CHxOutput = SUM (CHxMixerOutput1, CHxMixerOutput2, ...)

If a channel has several mixers active, then the commanded position could potentially exceed the safe limits of the servo. This might happen if you apply aggressive control inputs.

To avoid this, OpenTx limits channel values to +/- 100 before passing them to the Outputs. If the sum of the mixer outputs is outside the limits, the channel value is clipped. Clipping manifests itself as deadband at the transmitter control.


[Note: individual mixer outputs are not clipped, only channel values. Also, channel values are only clipped when passed to the Outputs layer, they not clipped when used as mixer sources.]

Channel scaling (OUTPUTS menu)

Here's a screenshot of the Outputs menu:


The key fields are MIN, MAX and SUBTRIM, and CURVE

By setting appropriate end points, you can prevent damage to your linkages from excess servo movement.

Where to adjust weights

At any moment in time, each of the three processing layers (Inputs, Mixers, and Outputs) can be considered to apply a nominal rate to their inputs. These rates are applied cumulatively, so that the final servo command is the product of three rates:

OutputValue = SourceValue x Rateinput x Ratemix x Rateoutput

Clearly there is an infinite combination of rates which will produce the same movement at the servo. So how should you go about making the adjustments? Here's the procedure which I recommend:

  1. Start by calibrating your control surface movements in the OUTPUTS menu (setting up end points, centres and equalising movements). Calibration should be done with inputs and mixer weights at their defaults (100%), and all trims to centre. The aim is to define the widest possible operating range of your control surfaces consistent with left/right and up/down symmetry.
  2. Reduce control surface travel via INPUTS.
  3. Any remaining interactions can be adjusted in the MIXERS menu.


Slight more advanced...

Mixer operators: ADD, REPL, MULT

So far, we've assumed that mixer outputs are always added together in order to calculate the channel output.

In fact OpenTx is a good deal more flexible - it also permits multiplication and replace operations on mixer outputs. These can be extremely useful. For example, multiplication is key to implementing in-flight adjusters, and 'replace' can be used to implement throttle safety switches.

The mixer operation is specified in the mixer's MULTIPLEX parameter. The options are 'ADD' (the default), 'REPL' and 'MULT'. When calculating a channel value, OpenTx steps through the active mixers, starting with the first mix in the channel:


Example: The following mixer lines illustrate the effect of the various MULTIPLEX parameters and the importance of mixer order.

Src = I1, op=ADD

Src = I2, op=ADD

output = I1 + I2

Src = I1, op=ADD

Src = I2, op=ADD

Src = I3, op=MULT

output = (I1 + I2) * I3

Src = I1, op=ADD

Src = I2, op=MULT

Src = I3, op=ADD

output = (I1 * I2) + I3

Src = I1, op=ADD

Src = I2, op=MULT (disabled)

Src = I3, op=ADD

output = I1 + I3

Src = I1, op=ADD

Src = I2, op=REPL

Src = I3, op=ADD

output = I2 + I3

Src = I1, op=ADD

Src = I2, op=REPL

Src = I3, op=MULT

output = I2 * I3

Src = I1, op=ADD (disabled)

output = 0

The 'MAX' source

MAX is a special source which doesn't correspond to a physical control. Instead, MAX supplies a fixed value of +100. In conjunction with weight, it can be used to simulate the effect of a fixed stick position.

Src = MAX, wt =100 -- output = 100%

Src = MAX, wt=50 -- output = 50%

Src = MAX, wt=-100 -- output = -100%

Here's a simple example, showing a crude motor arming system. The motor is armed when SA is down.


CH7 (motor)

Src = MAX, wt=-100%

Src = Thr, wt=100%, switch=SA-DOWN, multiplex = REPL


LapinFou has produced some useful data flow diagrams which describe the internal workings of OpenTx (Note: at the time of writing, there are one or two errors in the order of processing of curves).