OpenTx - Key Concepts

Mike Shellim 25 July 2014
Last updated 3 September 2020

Para nuestros amigos hispano-hablantes: traducción al español en formato PDF. Muchas gracias a Jorge Brun.

Introduction

OpenTx is a uniquely flexible 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.

Background

OpenTx has just eight programming menus, and each is completely generic. Just like Lego, simple elements are used to build powerful solutions!

But before you can use this power, you'll need to know some of the basics. So let's start at the beginning...

OpenTx: the processing loop

The core of OpenTx (as with any RC system) is the processing loop. This is a sequence of operations repeated several times a second - fast enough to provide a smooth response.

With each cycle, the position of all the controls are read, mixing is applied, and the channel values are calculated. At the end of the cycle, the channel values are passed to the RF module for transmission.

flow

The boxes in blue represent the three key processing steps. These are configured in the 'INPUTS', 'MIXERS' and 'OUTPUTS' menus.

 

The starting point: Sources

Like all computer programs, OpenTx needs some data to work with. These come from your transmitter's sticks, trims, knobs and switches. A generic term for these is sources. Each source has a unique identifier, for example,

The naming of sources is broadly similar between different FrSky transmitters, but there are some differences, e.g. knobs are generally S1 and S2, except on the X9E where they are F1 and F2.

Each source carries a value between -100 and 100 according to its position. For sticks, left/down is negative; right/up positive. For switches, up is negative, down is positive. Zero corresponds to centre.

So for example,

Source values can be monitored in real time in the ANALOG INPUTS menu. You can use this menu to check that your sticks are calibated correctly.

Note: channels, Lua scripts and telemetry can also be used as sources, however they will not be considered further in this article.

Channels and outputs

On most radios, a channel corresponds to a servo output. However OpenTx allows you to define up to 32 channels - far more than you're likely to need. In fact, 'channel' has a broader meaning. Here are the key points:

The OUTPUTS menu

Configuration of channels is done in the OUTPUTS menu. This where you:

The screenshot below shows the channels for a simple RES sailplane. The first three have been named 'Rudder', 'Elev' and 'Spoilr'. The travels and centers are at their default values.

Outputs

The OUTPUTS menu doesn't say how each channel is driven. For that, we need to define some mixers...

Mixers

So far we've talked about sources and channels in isolation. In order to do anything useful, we need link the two using mixers.

Mixers act as the 'wiring' from sources and channels; in other words, they define the control logic.

Unlike mixers in other radios, a mixer in OpenTX is a very simple construct:

A typical setup will involve anything from a couple of mixers (for an RE sailplane), to literally dozens of mixers (for a full house F3X ship).

The MIXER menu

The list of mixers (max 64) is displayed in the MIXER menu. Each mix has a source, and various parameters such as weight, offset, and curves.

The screenshot below shows a single mix. The source is the aileron stick, and the output is channel 1:

For simple mixes like these, just three columns are displayed:

A long press on any line takes you to the mixer editor where you can edit the mix parameters. We'll look at these in more detail later.

Three mixing scenarios

In this section we'll examine three key mixing scenarios. These will form the building blocks of your setups.

Scenario 1: One source -> one channel

This is the simplest scenario. We've already looked at an example where the aileron stick drives CH1:

Scenario 2: One source -> multiple channels

In this scenario, a single source drives more than one channel. In the screenshot below, the aileron stick drives both CH1 and CH5. This is a popular configuration for dual ailerons:

This configuration emulates a Y-lead but is more flexible since each channel can be individually adjusted for direction, travel and centring via the OUTPUTS menu.

Scenario 3: Multiple sources -> one channel

A single channel can also be driven by multiple sources. A common example of this is a V-tail - each surface (channel) is driven by both rudder and elevator sticks:

Note the '+' sign against the Ele line - this indicates that the rudder and elevator inputs are added to produce the output. When using the add operator, the order of the mixers doesn't matter. Other operators like multiply and replace can also be used, and the order for these is important (we'll look at those later).

Designing a mixer scheme

Now that we've covered the basics, let's go straight in and build a complete working system!

The method I will describe can be applied to any model, regardless of complexity. As an example, we'll construct a 2-channel flying wing, controlled using the aileron and elevator sticks.

Step 1. List the sources

The first step is to make a list of the sticks and sliders used to control the model. These will be the sources for the mixers.
The sources for a flying wing are:

Step 2. List the servo channels

The second step is to assign the servo channels.

Our flying wing has two elevon servos. We'll assign these to CH1 and CH2. We can do this directly in the OUTPUTS menu:

Outputs

Step 3. Identify interactions

Next, we identify the interactions between sticks and channels. An interaction is written as source->channel.

On a flying wing, the Ail stick must affect both elevon surfaces which we've assigned to channels 1 and 2. So,

Similarly, the interactions for Ele are:

Each line reads as "[source] affects [channel]"

Step 4: Convert interactions into mixer lines

The next step is purely mechanical: simply swap the left and right sides from Step 3.

So now, each line can reads as "[channel] is affected by [source]"

Step 5: Reorder interactions by channel number

Now, group the mixer definitions by channel.

The mixers are now in the form for entering in the MIXER menu.

Step 6: Enter definitions into the MIXER menu

Finally, created the mixer definitions:

mixers

The '+=' means on each line shows that the mixes are additive.

So that's the basics of our flying wing setup. We're not quite finished though, as we haven't taken into account the different effects of the aileron and elevator commands. We do his via the weight parameter.

Setting the mixer weight

The most important mixer parameter is weight. This determines the effect of a mix, between 0 and 100%. The sign determines the direction:

Applying this to our flying wing:

This basic setup will work fine. However it can be improved, using Inputs.

INPUTS

Our flying wing example above has a shortcoming: in order to adjust stick sensitivity, we have to make the same adjustment in two different mixes:

We can avoid both issues by using Inputs (introduced in OpenTx v. 2.0). An input is like a regular source, but with weight and expo built in. Inputs are distinguished from regular sources by a leading '[I]'.

Inputs are managed in the INPUTS menu.

Amending the flying wing to use Inputs

Using our flying wing example, we create a couple of inputs for the Ail and Ele sticks:

  1. Open the INPUTS menu
  2. Name the first input as '[I]Ail' and set source = Ail stick.
  3. Name the second input as '[I]Ele' and set source = Ele stick.
  4. Finally, set weight and expo to the required values

inputs

The [I]Ail and [I]Ele inputs behave exactly like their sources, except they implicitly have 90% weight and 10% expo.

We now amend the mixers to use the new inputs instead of the raw sources:

mixers

Note that we have reset the mixer weights to 100% (since the rates are now set in the inputs). When using inputs, set the mixer weights to 100%!

Choosing between raw sources and inputs

The use of inputs is optional. Sometimes it's better to use the raw source. Here are some guidelines:

More about inputs

Inputs are an important part of OpenTx, and you can read more about them here.

Mixer calculations

In this section we'll look in more detail at mixer processing. An understanding will be come in useful when debugging your setup.

Nomenclature
One of the less fortunate aspects of OpenTX is the hijacking of generic terms 'inputs' and 'outputs' to describe the processing layers - this makes it more difficult to write meaningful documentation. Just to clarify the nomenclature most commonly used:

It may be as clear as mud (!) but I will at least try to consistent in this article.

 

OpenTX performs two sets of calculations. First, individual mixer line values:

Channel 1

mix_line_1 = Ail_stick_value x 90%

mix_line_2 = Ele_stick_value x 30%

 

Channel 2

mix_line_1 = Ail_stick_value x -90%

mix_line_2 = Ele_stick_value x 30%

Next, the mixer line values are aggregated to produce the mixer outputs. These represent the commanded positions for each channel:

CH1 Mixer output = (Ail_stick_val x 90%)+(Ele_stick_val x 30%)
CH2 Mixer output = (Ail_stick_val x -90%)+(Ele_stick_val x 30%)

The following table shows the mixer outputs for our flying wing example:

S T I C K S M I X E R  O U T P U T S
Ail stick Ele stick 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": the mixer output for Channel 1 is 120. In fact, mixer outputs are clipped to +/- 100 in the OUTPUT stage. More on that later.

Mixers monitor

You can see the mixer outputs in real time in the mixers monitor (introduced in OpenTX 2.2). To activate it on the X9D, from the splash screen press {Page} until you get to the channels monitor, then press Enter.

More mixer options

OpenTx offers a number of mixer options. We've already looked at weight. We'll now investigate offset, expo, diff, functions and curves.

The 'offset' parameter

The offset parameter is the most important after weight. Offset is used to shift the mixer output up or down. Using offset in conjunction with weight, you can create mixes whose value varies within defined limits. This is useful for creating volume controls and compensation mixes.

Offset is applied after weight:

Mixer line value = (Source * weight) + Offset

Offset example 1: custom volume control

Suppose you want to create volume control (S1), with output varying from -50 to +90 as S1 is rotated. We can do this as follows (remembering that the value of S1 varies from -100 to +100):

MIXERS menu

CH10 (vol control)

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

Offset example 2: motor-elevator compensation. Offsets are invaluable motor and crow compensation. In these mixes, the mix must be zero at one end of stick travel. To achieve this, weight and offset must have the same magnitude.

The example below shows a typical motor compensation mix. As the throttle stick is advanced, a corrective elevator input is applied up to a maximum of 40% (at full throttle).

MIXERS menu

CH2 (elevator)

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

Note: offsets should be used sparingly! Don't use them to make ad-hoc adjustments to servo centres - use OUTPUTS->Subtrim for that.

The 'diff', 'expo', 'function' and 'curves' parameters

In addition to weight and offset, OpenTx offers one additional parameter from the following list of choices:

The 'Curve' parameter provides the most granularity - it can implement any of the other options, however it requires the most data entry.

How to specify aileron differential

Sailplanes often employ aileron differential in order to reduce the travel of the downgoing aileron.

One source of confusion is the 'diff' parameter, as it's available in both the INPUT and MIXER menus. First, the incorrect way, using INPUTS menu:

INPUTS menu

[I1]Ail

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

 

MIXERS menu

CH1 (right elevon)

Src = [I1], wt=100%

 

CH2 (left elevon)

Src = [I1], wt=-100%

Using the above code , the aileron stick will have a higher rate on one side than the other. This is not what we want! Instead, diff must be applied separately to each aileron mix:

INPUTS menu

[I1]Ail

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

 

MIXERS menu

CH1 (right elevon)

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

 

CH2 (left elevon)

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

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

TIP: Use a GVAR to supply the diff value. That way, you can set diff for both channels with a single adjustment.

Including/excluding trims

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

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

Default mixer settings

When you create a new mix, the initial settings are weight=100% and offset=0, diff/expo=0 and no curve. The source value is therefore passed through unchanged.

Order of processing

When calculating a mix line value, OpenTx first applies the trim value. Then it applies the function (diff, function, curve, expo), followed by weight, and finally adds the offset. Order may be important when combining operations especially where offsets are involved!

The OUTPUTS menu

The OUTPUTS menu controls the final stage of processing

In the Output stage, OpenTX performs the following:

  1. Clips the incoming mixer values so they lie in the range -100 to +100
  2. Applies a scaling and offset

Let's look in more detail:

Clipping

Recall how mixer outputs are aggregated from individual mixer lines:

CHx_MixOutput = SUM (CHx_MixLine1, CHx_MixLine2, ...)

If several mixers are active, the mixer output may exceed the safe limits of the servo. To prevent this, the OUTPUTS layer clips the value so it lies in the range -100 to +100. Any clipping will manifest itself as deadband at extremes of stick movement.

Scaling and offset

After clipping, a scaling and offset are applied. The scaling and offset are defined by MIN/MAX/SUBTRIM and an optional curve. By setting the output parameters appropriately, you can compensate for differences between the left and right sides of the model.

outputs

Notes:

Channels monitor

You can monitor channel outputs in real time, using the Channels monitor.

Where to adjust weights

The three processing layers (Inputs, Mixers, and Outputs) each apply a weight or scaling to their inputs, and these values are cumulative. So final channel output is as follows (ignoring clipping):

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 where should you set them? Good practice is to adjust servo-related adjustments in the OUTPUTS, control rates in the INPUTS, and as little as possible in the MIXERS!

This is the procedure I recommend:

  1. Initialise all weights in MIXERS and INPUTS to 100%.
  2. In the OUTPUTS menu, adjust MIN, MAX and SUBTRIM to achieve the required servo limits and centres.
  3. In the INPUTS menu, adjust the weights to achieve the desired control surface travel.
  4. Any remaining mixer interactions can be adjusted via weights in the MIXERS menu.

More advanced stuff

Mixer operators

We've seen how mixer line values are aggregated to produce mixer outputs. So far, we've only used addition. In fact OpenTx also offers multiplication and replacement operations.

This is very useful. For example, multiplication is key to implementing in-flight adjusters, and 'replace' can be used to implement throttle safety switches.

The operator is specified in the mixers Multiplex parameter, and the options are 'ADD' (the default), 'REPL' and 'MULT'.

When aggregating mixer lines, OpenTx initially assigns a value of zero. Starting at the top line, it steps through each mix, and applying the result according to the multiplex parameter:

Note:

The following examples illustrate the effect of the various multiplex options. Note the importance of mixer order when using 'REPL' and 'MULT'.

Src = I1, op=ADD

Src = I2, op=ADD

result = I1 + I2

Src = I1, op=ADD

Src = I2, op=ADD

Src = I3, op=MULT

result = (I1 + I2) * I3

Src = I1, op=ADD

Src = I2, op=MULT

Src = I3, op=ADD

result = (I1 * I2) + I3

Src = I1, op=ADD

Src = I2, op=MULT (disabled)

Src = I3, op=ADD

result = I1 + I3

Src = I1, op=ADD

Src = I2, op=REPL

Src = I3, op=ADD

result = I2 + I3

Src = I1, op=ADD

Src = I2, op=REPL

Src = I3, op=MULT

result = I2 * I3

Src = I1, op=ADD (disabled)

result = 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.

MIXERS menu

CH7 (motor)

Src = Thr, wt=100%,

Src = MAX, wt=-100%, switch=!SA_down, multiplex = REPL

F3X sailplane mixer scheme

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.

Links

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).