rc glider in flight

OpenTx/EdgeTX - Key Concepts

Introduction

EdgeTX and its parent OpenTX are powerful operating systems which are well suited to complex applications like scale and F3X. However, if you've come from another brand like Spektrum or Futaba, the programming will seem very different.

If this strikes a chord, then you've come to the right place! The goals of this page are to (a) describe the key concepts behind these OSs and (b) enable you to design your own setups from scratch. Examples are illustrated with OTX screenshots or as text.

Tip: The menus in EdgeTX and OpenTX look different, but provide the same functionality.

Let's go!

The processing loop

Like all RC operating systems, OpenTX executes a processing loop - a sequence of steps repeated several times a second. During that time it:

Finally the outputs are picked up by the RF module for transmission.

The graphic below illustrates the stages from source to output:

data flows

In the diagram:

Let's now take a tour of each of these elements. A red arrow indicates where we are in the loop.

Sources

Data flow

All computer programs need data to work with. With OpenTX, the data are your sticks, switches, inputs, trims and so on. The general term for these is sources. Each source has a unique ID, for example:

Each source carries a value between −100% and +100% according to its position. Zero represents the centre. Examples:

You can monitor the source values in the Sys->Hardware menu. This is useful for checking that your hardware is correctly calibrated (check that the extremes of movement generate +/-100%).

These source values will be manipulated as they pass through the inputs, mixer and outputs, ending up as PWM values for positioning the servos.

Special sources

Before we leave the topic of sources, I'll mention a couple of special ones:

Note 1: Source IDs may differ between transmitters.
Note 2: Channels, Lua scripts and telemetry can also be used as sources, however they won't be discussed further here.

Mixers

Data flow

Mixers are central to OpenTX. In fact, there's only one kind of mixer and it's very simple to describe:

As you've guessed, there's not much you can do with a single mixer. However, by utilising multiple mixers in combination you can create highly sophisticated setups.

In general, each channel will be served by a stack of several mixers; each mixer makes an additive contribution to the channel. A complete setup may have anything from a couple to several dozens mixers, depending on complexity.

How to create a mix

To create a mix, go to the Mixers screen, select a target channel, and open the mixer editor.

screenshot of mixer editor

The three key fields as follows:

The mixer output is calculated as follows:

mixer_output = (source_value × weight) + offset

The mixer output represents % of available travel on the destination channel. (We'll see how to set available travel when covering the Outputs stage).

Shown as a graph of output v. input, weight is the slope, and offset is the output value for a zero input value:

Mixer processing

Default mixer settings

The default weight and offset are 100% and 0% respectively, so output = input.

Three mixer scenarios

In this section, we'll look at three common mixer idioms which you'll use in your own setups:

one source => one output

The screenshot below shows the simplest possible setup - just a single mix, with the aileron stick driving CH1. You can read the line as: "Channel 1 is affected by the aileron stick, with 100% effect":

Screenshot

Try it - go to the Mixers menu, and create a mix for CH1. Set 'Ail' as the source and leave all the other options at their default values. As you move the aileron stick, the servo should respond. Now adjust the weight and offset, and observe the effect.

One source => multiple outputs (example: dual ailerons)

Most models with ailerons use two servos to control them. That means assigning two channels, each driven by the aileron stick.

In this exampe, the ailerons use CH1 and CH2. To indicate that the ailerons work in opposition, we reverse the sign of weight in one of the mixes.

Mixer

Tip: Using two separate channels is better than a Y-lead, since each channel can be individually adjusted for direction, travel and centring.

Multiple sources => one output (examples: delta, V-tail)

The examples above involve just a single mixer for each channel. Often, however, more than one mixer can drive the same channel.

Take the example of a V-tail. Each surface will have its own servo. Each servo must move in response to (a) the rudder stick and (b) the elevator stick. So two mixes are needed for each servo.

Here's the Mixers menu, showing one of the V-tail channels:

Mixer

The mixer stack

The collection of mixers driving one channel is called the mixer 'stack' for that channel.

There are some simple rules for mixers in a stack:

The order does matter for 'replace' and 'multiply' mixers, however this is an advanced topic we'll come to later. For now, just think of mixers as being additive and in any order.

In the Mixers menu, mixers are displayed in channel order, so what you're looking at is a sequence of stacks. This makes it easy to see what's going on.

Channels

Data flow

So far, we've made only brief mention of channels, so let's now dive a bit deeper. Note that the terms 'channels' and 'outputs' are often used interchangeably.

The Outputs menu is where channels are managed. This is where you give each channel a name, and set the end points and centre.

In the screenshot below, CH1, CH2 and CH3 have been given appropriate names:

Outputs

To the right of the Name column are the Subtrim, Min and Max parameters for setting the centre and end points. That's all we'll say about the Outputs for now - we'll revisit them later.

Designing your own mixing scheme

In this section, I'll describe a 4-step method of designing a mixing scheme. The same method can be used on any model regardless of complexity. Once you've tried it on one or two models, you'll find it easy to do it in your head.

Designing the mixers for a flying wing

We'll use the example of a simple flying wing. These normally have two elevons:

Step 1. Assign channels

The first step is to decide which channel goes with which servo. Then open the Outputs menu and type in the channel names. These names will help you identify the channels in other menus.

Outputs

That's all that you need to do in the Outputs menu for now.

Step 2. Identify stick/servo interactions

Next is a thought exercise! Pretend that you're moving a stick, and make a list all the channels which are affected. Repeat for all the main controls used for this model (you can ignore the trims). Represent each interaction using the format source -> channel:

For our flying wing, the aileron stick ('Ail') has these interactions:

Ail -> CH1

−Ail -> CH2

Note the negative sign in CH2 to denote that the elevons are moving in opposite directions.

And the elevator stick:

Ele -> CH1

Ele -> CH2

No negative sign is needed, since the elevons move in the same direction.

Step 3: Convert interactions into mixer lines

Next, write the interactions in reverse:

CH1 <- Ail

CH2 <- −Ail

CH1 <- Ele

CH2 <- Ele

So now, each line reads as "[channel] is affected by [source]". This corresponds to the way mixers are entered into the Mixer menu.

Step 4: Enter mixer definitions

Finally, go to the Mixer menu. From your list of interactions, create a mix for each one. Set the weights to 100% - we'll see how to adjust this later. Note also that the negative aileron rate translates to a negative weight (−100%).

mixers

That's it, done!

There's just one shortcoming: we have assumed 100% rates for both the aileron and elevator sticks. We could reduce the travel by reducing the mixer weights, however this would require four adjustments: two in the aileron mixes, and two in the elevator mixes.

A much better way is to use inputs. Using inputs, there are just two adjustment points: one for the aileron input, and one for elevator input. We'll see how this is done in the next section.

Inputs

Data flow

Inputs are based on regular sources, but include rates and expo. They are especially useful for dual ailerons, as they provide a single adjustment point for rates and expo. However, they should be used for all the main flight controls (ailerons, elevator and rudder).

Unlike raw sources, inputs are not built in - they must be created first.

The Inputs menu shows a list of all the inputs which have been defined. Note that inputs are displayed with an '[I]' prefix, and raw sources are drawn with a stick icon. Read the first line as 'the rudder input is based on the rudder stick with 100% effect'

inputs menu

To create an input, select a blank line and open the editor. Then set an input name (max 3 characters), a source (stick, slider etc.), a weight, and optionally an expo value. The line name is optional.

inputs menu

AETR and channel order

Did I say you have to create your own inputs? Well conveniently, when you create a new model, OpenTX creates inputs for the main flight controls [I]Ail, [I]Ele, [I]Thr and [I]Rud. It also creates four mixers and populates the outputs. The default channel order is "AETR" ([I]Ail->CH1, [I]Ele->CH2 etc.)

You can change the default order in the Radio Setup menu.

Changing the default channel order only affects models that you create subsequently - existing models are unaffected.

Adding inputs to the flying wing

Using our flying wing example, we'll use the predefined [I]Ail and [I]Ele inputs. We'll assign a weight of 90% to the aileron input, and 30% for the elevator input. We'll set expo to 10% for both inputs.

The Inputs menu will look something like this:

inputs

You can read the first line as meaning: "the aileron input ([I]Ail) is based on the aileron stick (Ail), with 90% effect, and 10% expo (E10)"

Next, we must go back and edit the mixers to use inputs instead of the raw sources we used previously:

mixers

The first line means: "Channel 1 (CH1) is based on the aileron input ([I]Ail) with 100% effect"

Note that I have set the mixer rates to 100%. This means "Use 100% of the rates in the inputs".

Now, in order to alter the aileron rate, we only need to alter one input weight, instead of two mixer weights. Same for the elevator.

Choosing between inputs and sticks.

When choosing the source of a mix, you don't have to use an input. It's only necessary if you need to adjust rates or expo. In other cases, just use the raw sources. Some guidelines:

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

How commands are processed

In this section, you'll learn how your stick commands are processed. A good understanding is useful for troubleshooting your setups.

The first thing to remember is that weights are multiplied cumulatively as data flows from inputs to mixers to outputs.

Let's look at the flow of data with our flying wing. We'll consider just the inputs and mixers:

inputs

mixers

So now let's see how the stick values are processed.

Taking the inputs first, these act on the aileron stick position and apply a weight:

[I]Ail = Ail_Stick x 90%

[I]Ele = Ele_Stick x 30%

Next, the input values are aggregated in the Mixers:

CH1 = [I]Ail + [I]Ele

CH2 = -[I]AIl + [I]Ele

Expanding the input values::

CH1 = (Ail_Stick x 90%) + (Ele_Stick x 30%)

CH2 = (Ail_Stick x -90%) + (Ele_Stick x 30%)

Let's now apply these equations to calculate the channel values:

Sticks Channel values
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

Note that when the stick in the corner (full right/full forward), CH20 is 120% - that's 20% more than the available travel. In fact, channel values saturate at +/-100%. More accurately, channel values outside the range -100% to +100% are clipped on entry to the Output stage. More on that later, when we look at the Outputs stage.

Channel values are clipped only when they reach the outputs. Channel values which are cascaded to mixers are not clipped. Cascading is described here.

The mixers monitor

Once you've designed your setup, you'll want to check the aggregated mixer values for each channel. You can do this using the Mixers monitor, which is available on the transmitter and in Companion.

Tip: Don't confuse the Mixers monitor with the Channels monitor (the latter displays the final outputs). On the X9D you can flip between one and the other by pressing the Enter key.

monitor

The values represent percentages of available travel. The actual travel is set later in the Outputs.

Tip: When designing your mixers, don't be concerned about the linkages or left/right imbalances - these will be dealt with later, when you calibrate the Outputs.

Mixers are the key to mastering OpenTx, and you can read more about them here.

Outputs

Dataflow

The Outputs stage is the final stage of processing prior to transmission. Its job is to generate PWM values ready for transmission.

OpenTX performs two operations:

  1. Clips the aggregated mixer values (per channel) to +/- 100%
  2. Converts the clipped values to PWM commands according to Min/Max and Subtrim

Let's look at each step in more detail:

Clipping

Recall how mixers values are aggregated for each channel. If a channel has several mixers and aggressive stick movements are applied, then the aggregated value could exceed 100%. To prevent this, the mixer values are clipped to +/−100% on entry to the Outputs.

Converting to PWM values

We're almost reached the end! The final step is to convert the aggregated mixer values (in the range -100% to +100%) to PWM values. This is done according to Min, Max and Subtrim which you set in the Outputs menu:

outputs

Min, Max, Subtrim work as follows:

Technically, the outputs stage performs a mapping between the channel value in % units, to servo positions in PWM units (micro-seconds). The mapping is governed by a 3-point curve defined by Min, Max and Subtrim:

mix to PWM graph

Since the incoming channel values have been clipped to +/−100%, Min and Max also represent hard limits - think of these as electronic end stops.

In addition to Min/Max/Subtrim, you can specify an output curve with between 2 and 17 points. This allows finer control over the mixer->output mapping. Min/Max/Subtrim are applied first, then the curve. If using a curve, it's good practice to leave Min, Max and Subtrim at their default 'pass thru' values of −100%, 0% and +100%.

PWM values

In the screenshot above, it'll be seen that Min, Max and Subtrim are shown as percentages, while they actually represent PWM values (yes, it's a little confusing!) The units are related as follows:

Min/Max/Subtrim PWM
-150% 732 μs
−100% 988 μs
0% 1500 μs
100% 2012 μs
150% 2268 μs

PWM values outside the range 988 - 2012 μs are only available if Extended Limits is enabled in the Model menu.

Calibrating servo limits and centres

Calibration is the process of adjusting Min/Max/Subtrim. You can read more about calibration here.

Channels monitor

You can monitor the final outputs using the Channels monitor.

Channel monitor

Advanced topics

Mixer operators

We've seen how mixer line values are aggregated via addition. In fact OpenTx offers a lot more flexibility, by means of Multiply and Replace operators. The operator is specified in the Multiplex parameter:

Mixer editor

 

Okay, so let's see how these operators are applied.

At the start of the processing loop, the channel values for all channels are reset to zero. Next, the mixers are then processed in the order that they appear in the MIXERS menu.

As each mixer is processed, its associated channel is updated as follows:

Note: if a mix is disabled, it's ignored entirely, as if it wasn't there at all.

The following examples illustrate the effect of the various operators. 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.

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.