OpenTx - Key Concepts

Mike Shellim 25 July 2014
Last updated 23 November 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 mostly similar between FrSky transmitters, but there are some differences. For example, 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,

These raw values can be monitored in real time in the ANALOG INPUTS menu (You can use this to check that your sticks are correctly calibrated).

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

Mixers

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

OpenTX supports up to 64 mixers. It may sound like a lot, but a mixer in OpenTX is a very simple construct:

The list of mixers is displayed in the MIXER menu. The screenshot below shows that a single mix is defined for channel 1:

The way to read it is: "Channel 1 is affected by the aileron stick, with 100% effect". 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.

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

Channels

On most radios, a channel corresponds to a servo output. However, if you look in the MIXERS menu, you'll see that there are slots for 32 channels. In OpenTX, a 'channel' has a much broader meaning! Here are the key points:

 

Naming the channels

When setting up a model, your very first task will be to assign a name to each servo channel. You'll do this in the OUTPUTS menu.

Here's an example for an RES sailplane where the servos are connected to channels 1, 2 and 3:

Outputs

The columns to the right refer to servo calibration - we'll look in more detail at the OUTPUTS menu later in this article.

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

The simplest scenario is one stick controlling one channel. Here's 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. This is a popular configuration for dual ailerons:

This solution may seem similar to using a Y-lead, however it's more flexible since each channel can be individually adjusted for direction, travel and centring (we'll see how to do this later).

Scenario 3: Multiple sources -> one channel

OpenTX makes it easy to drive a single control surface with more than one control stick. Here's an example of rudder and elevator sticks controlling a V-tail channel:

Note the '+' sign against the Ele line - this indicates that the rudder and elevator inputs are added to produce the output. In other words, each line makes an independent contribution to the movement of the control surface.

When using the add operator, the order of the mixes 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 build a complete working system! The method I will describe can be applied to any model, regardless of complexity.

I'll use the example of a 2-channel flying wing. Control is via the aileron and elevator sticks.

Step 1. List the sources

The first step is to list the sticks used to control the model.

Step 2. Assign channels

The second step is to name the elevon channels. We do this directly in the OUTPUTS menu:

Outputs

Step 3. Identify stick/servo interactions

Next, we identify the interactions from sticks to servos . An interaction is written as source->channel. On our flying wing, the aileron stick will drive both servos. So,

Similarly, for the elevator stick:

Step 4: Convert interactions into mixer lines

Next, swap the left and right sides from Step 3.

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

Step 5: Reorder interactions by channel number

Now, reorder the mixer definitions in channel order

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

Step 6: Enter mixer definitions

Finally, created the mixer definitions in the MIXER menu

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 differences between elevator and aileron inputs. We do his via the weight parameter.

Setting the weight

The mixer weight determines the strength of the mix, between 0 and 100%. The sign determines the direction:

Applying this to our flying wing:

Our first OpenTX setup is complete!

However it can be improved...

INPUTS

Our flying wing example above will work. However, in order to adjust the aileron or elevator sensitivity, we have to make identical adjustment in two different places. Our aim should always be: no duplicate adjustments!

The solution is to use Inputs as the mixer sources. An Input is based on a regular source, except it has weight and expo built in. To adjust the rate or expo, we can simply edit the corresonding input.

Inputs are managed in the INPUTS menu. Inputs are distinguished from regular sources by a leading '[I]'. Using our flying wing example, we'll 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

So now the [I]Ail and [I]Ele inputs have weights of 90% and 30% respectively. Both have 10% expo.

Next, we amend the two mixers to use the inputs that we've just created:

mixers

We have reset the mixer weights to 100%, since the rates are now defined via our new inputs. When using inputs, set the mixer weights to 100%!

Choosing between raw sources and inputs

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 at how mixers are processed. An understanding is useful when debugging.

OpenTX performs two sets of calculations. First, individual mixer line values. Using our flying wing example:

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

Here are 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.

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 about mixers

We've already looked at mixer weight. We'll now investigate offset, expo, diff, functions and curves.

Mixer offsets

The Offset parameter is used to shift the mixer output up or down. Offset is applied after weight:

Mixer line value = (Source * weight) + Offset

example: custom volume control

Suppose you want the rotary knob S1 to generate a value between -50% to +90%. You 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

example: motor-elevator compensation. Offsets are used for compensation mixes. In these mixes, the mix must be zero at one end of stick travel (instead of centre). To achieve this, weight and offset must have equal magnitude. The range of compensation will be twice the magnitude of each.

Here's an example showing a motor compensation mix. As the throttle stick is advanced, a corrective elevator input is applied between zero and 40%:

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.

Diff, expo, functions and curves

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

The first three options can in fact all be represented as curves - think of them as short cuts to particular curve types.

Aileron differential

The 'diff' parameter is available in both the INPUT and MIXER menus. So which should you use to implement aileron diff? 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%

The problem is that diff is applied to the aileron stick, while we want it to be applied to each aileron servo. The correct way is therefore to apply it to the servo 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!

OUTPUTS stage

The OUTPUTS stage is the final stage of processing prior to transmission.

The processing is controlled via the OUTPUTS menuoutputs

Outputs processing

OpenTX performs two main tasks:

  1. Clipping: incoming mixer values are clipped to -100 and +100
  2. Scaling: a scaling and offset are applied

Let's look in more detail:

Clipping

Output clipping is a key concept in understanding OpenTX, and one which is often misunderstood or overlooked. In this section I'll explain what it is, and why it's needed.

Recall how mixer outputs are aggregated from individual mixer lines:

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

If several mixers are active, and aggressive stick movements are applied, then one or more mixer outputs may exceed the mechanical limits of the servo. To prevent this, the OUTPUTS layer clips the value so it lies in the range -100 to +100. Clipping manifests itself as deadband at extremes of stick movement.

Scaling

After clipping, a scaling and offset are applied. The amounts are defined by MIN/MAX/SUBTRIM and an optional curve. MIN and MAX are specified as %ages. MIN is applied to negative mixer values, MAX to positive mixer values. SUBTRIM is an offset.

By setting the output parameters appropriately, you can compensate for differences in the linkages between the left and right sides of the model.

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