Shop our Airplanes Products Drone Products Sales
Miami Mike's blog View Details
Posted by Miami Mike | Nov 29, 2018 @ 02:19 PM | 1,648 Views
There may be some interest springing up in Germany in the Shepard Tone Vario setup that I developed for OpenTX earlier this year. See my Shepard Tone Vario for OpenTX and Shepard Tone Vario testers wanted posts from February and March of 2018.

Here's the complete package with setup instructions.

Demo video :

Shepard Tone Vario Demo (5 min 54 sec)

Edit: According to this post, the RC Soaring Digest has released its final issue. My Shepard Tone Vario setup was inspired by an article by Helmut Stettmaier in the March 2018 issue of the RC Soaring Digest, titled An Innovative Method for Acoustically Rendering Climb Data for Model Gliders Using Shepard Tones, so if you're interested in reading it download it now, just in case the site goes offline.
Posted by Miami Mike | Aug 19, 2018 @ 08:38 PM | 2,250 Views
When the OpenTX Wizard creates an elevon mix, it looks like this:

I2:Ail Ail Weight(+100%)
I3:Ele Ele Weight(+100%)


CH2 I2:Ail Weight(-50%)
 += I3:Ele Weight(+50%)
CH3 I2:Ail Weight(+50%)
 += I3:Ele Weight(+50%)
The weights are set at 50% so that the combined effect of the mixes for each channel won't exceed 100% and cause clipping. That's important because when a channel mix reaches 100% its control surface is at its limit and any further stick movement away from center won't result in any additional control response from that channel. For a more detailed explanation of this, please see this post, which includes a graphical illustration.

However, a 50% weight for the aileron input and a 50% weight for the elevator input isn't necessarily the best combination for a slope wing. The sum of the two weights should never reach beyond 100%, but that doesn't mean they have to be equal to each other. In the case of my Weasel Trek and generally most other slope wings, the best setup will have a lot more aileron throw than elevator throw. In fact, if the CG is forward of but very close to the neutral point, a wing will require very little elevator throw. On the other hand, slope wings are generally more fun to fly with the quick and snappy rolls you can get with extreme aileron throw.

So here's an alternate OpenTX elevon setup that allows you to adjust elevator throw in flight and get it just right for smooth, stable pitch control, and as you adjust...Continue Reading
Posted by Miami Mike | Aug 06, 2018 @ 03:35 PM | 2,027 Views
  • A link can be a web page URL by itself, such as In that case you can simply enter the URL in your post and tags will be automatically added when previewing or posting (unless you've already added them yourself). They'll look like this:


    It's customary to precede this type of link with a description of where the link will take you.
  • A link can contain text that appears in place of the URL, like this:

    Miami Mike's Blog

    The tags for a link with text look like this:

    [url=]Miami Mike's Blog[/url]
  • It's possible to use an image in place of text in a link:

    ← This is a clickable link.

    The tags for a link that includes an image look like this:

  • Beware of adding a link to your post that includes a page number because posts per page is a configurable option for RCGroups users, so a link with a page number won't necessarily take others to the same place it takes you. This is a problem that Google has when returning a link to an RCGroups post. If you've increased your Number of Posts to Show Per Page in Thread Display Options on your Edit Options page then a link from Google will
...Continue Reading
Posted by Miami Mike | Jul 01, 2018 @ 04:36 PM | 3,611 Views
Here's a Lua script and custom set of WAV files for OpenTX version 2.1 or 2.2 to speak the time of day in a natural-sounding format, such as "twelve o'clock PM" or "nine oh two AM."

The WAV files are in a folder in the root directory named SAYTIME, and saytim.lua is stored in /SCRIPTS/FUNCTIONS/.

On your Special Functions page, set saytim to be played with the Play Script function whenever a hardware or logical switch of your choice is true. For example, this will play the time of day when SA is switched to position SA↑:

Beginning with OpenTX version 2.2.1, saytim.lua can alternately be called with a Global Function.

The script and set of WAV files were revised on July 3, 2018 to allow for times from 12:00 AM to 12:59 AM. The revised script looks like this:
-- Function script saytim.lua by Miami Mike, July 3rd, 2018
local path, lastcall = "/SAYTIME/", 0
local function run_func()
	local newcall = false
	local time = getTime()
	if time > lastcall then
		newcall = true
	lastcall = time + 10
	if newcall then
		local datetime = getDateTime()
		local hour, minute, ampm = datetime.hour, datetime.min, "am"
		if hour >= 12 then
			ampm = "pm"
			if hour >= 13 then
				hour = hour - 12
		playFile(path .. "timeis.wav")
		playFile(path .. hour .. "h.wav")
		playFile(path .. minute .. ".wav")
		playFile(path .. ampm .. ".wav")
return {run=run_func}
Instructions are included in a file named readme.txt. Please post any problems or special requests below.

Posted by Miami Mike | Jun 25, 2018 @ 01:35 PM | 3,748 Views
In November of 2016 I described my SetFail flight mode, which allows you to experimentally determine your best Custom failsafe settings for each of your models, but it's a bit involved and some might consider it adequate to just set the failsafe option to Custom and set all your controls to neutral, except the throttle, which should be fully closed.

I just want to point out that if you decide to do it that way then you shouldn't assume that this will work, because it won't:

It's not as simple as that.

The values you enter on your Setup page for Custom failsafe are the actual values that will be sent to your servos and do not take into account any Subtrim, Min, or Max settings on your Outputs page, or any mixing, or flight mode-specific trim settings, etc. that occur when your sticks are in their neutral positions. To know what those Custom failsafe values really need to be for neutral control surface positions, or whatever positions you want them to take when control is lost, you have to read them from your Channels Monitor.

On a Taranis X9D+, before you begin setting up your model, it looks like this:

But after you've set up the model, with the sticks neutral and the throttle off, it'll probably look more like in this random example:

...Continue Reading
Posted by Miami Mike | May 27, 2018 @ 05:43 PM | 3,062 Views
There's a bug in the trim steps and trim limits in OpenTX that has apparently been around for a long time, and which I reported on Github back in February of 2017.

Briefly, trims have a maximum integer value of 250 instead of 256.

256 is 2^8 or two raised to the eighth power, and would be exactly 1/4 of the maximum integer value of 1024, which is 2^10 or two raised to the tenth power. But 250, which is 2 x 5^3 or two times five raised to the third power, is 24.4140625% of 1024. In the midst of a system neatly based upon powers of two, there's an awkward and illogical value that's the cause of a big mess!

This appears to have been the result of a programmer confusing the percentage value of 25% with the integer value of 250, and in OpenTX version 2.1, one of its consequences is an odd behavior that I described to the developers in an attempt to prove my case:
Here's an oddity that fixing this bug will cure: In any trim step setting beside "Extra Fine" (2 steps per click), the values accessible when you start from zero are interleaved with the values accessible when coming back from maximum or minimum. For example, if your trim setting is "Fine" (4 steps per click) then if you start from zero you can select settings that are multiples of 4, such 4, 8, 12, 16, etc.

But if you go all the way to the current unintended limit of 250 and come back, you can only get to settings that are equal to 250 minus a multiple of four,
...Continue Reading
Posted by Miami Mike | Apr 05, 2018 @ 09:48 AM | 3,369 Views
Because I have several full-house sailplanes that use exactly the same basic setup, I've recently adopted a policy of leaving everything on the Outputs page at default values except for the six curves for the six servo channels. My flaps and ailerons are all controlled by 9-point curves with the flaps adjusted to be
  • at their least common physical upper limit at +100%,
  • 7.5 up at +75%,
  • even with the trailing edge at +50%,
  • 7.5 down at +25%,
  • and from there to their least common physical lower limit in five steps of equal degrees, ending at -100%.
My aileron curves are adjusted to be
  • 30 up at +100%,
  • 22.5 up at +75%,
  • 15 up at +50%,
  • 7.5 up at +25%,
  • even with the trailing edge at +0%,
  • 7.5 down at -25%,
  • 15 down at -50%,
  • 22.5 down at -75%,
  • 30 down at -100%.

To do these settings I use digital helicopter pitch gauges...

... and a 16-point "stair" curve that's part of my Calibration mode.

(Actually, I use different flap/crow elevator compensation curves for each model as well, but aside from those differences the setups are the same.)

The "stair" curve is an expansion of an idea inspired by Mike Shellim.

As an example, here are my two Shadow 2 electric-powered gliders:

...Continue Reading
Posted by Miami Mike | Mar 20, 2018 @ 11:17 PM | 3,579 Views
I need testers for my Shepard Tone Vario. You'll need a glider with an FrSky High Precision Vario or a G-RX8 with its built-in vario, plus an OpenTX radio. Other types of varios might also work as long as they show up on your Telemetry page. I know this works with my Taranis running OpenTX version 2.1.9, and it'll probably work with other types of FrSky radios using OpenTX version 2.2, but I need volunteers to confirm that and to share their overall impression of it.

This video shows how easy it is to install and set up. Watch it and then post below if you're interested in trying it out.

Shepard Tone Vario Demo (5 min 54 sec)

Here are the files you'll need to install the Shepard Tone Vario on your radio or test it with Companion simulator. The package was updated on November 29, 2018 with the "shepard.lua" filename shortened to "sheprd.lua" for compatibility with OpenTX 2.2, and the instructions have been rewritten:
Posted by Miami Mike | Feb 23, 2018 @ 08:12 PM | 4,498 Views
The Shepard Tone Vario is pretty-much ready and will be released after some of my friends have tested it.

Version #1 was an attempt to create Shepard tones using the limited sound capabilities of the playTone() function of OpenTX Lua, but that didn't work out very well. The latest version uses a set of 100 WAV files that I spent many hours creating using a combination of several tools, including Audacity. This will almost certainly undergo further refinement but I believe it's quite functional in its current form.

Credit for the idea goes to Helmut Stettmaier, who describes it in the March 2018 issue of Radio Controlled Soaring Digest. Please read his article for more information.

Shepard Tone Vario Demo (5 min 54 sec)

Some Shepard tone videos:

The sound illusion that makes Dunkirk so intense (3 min 2 sec)
...Continue Reading
Posted by Miami Mike | Feb 01, 2018 @ 04:49 PM | 5,742 Views
Here's a simple improvement to the volume control setup I described in my previous blog post, which is a way to put your volume control on one of your potentiometers and confine its range to within your chosen upper and lower limits. The need to do arithmetic is now gone, plus there's a way to set the detent center position of the control to the "perfect" volume setting that's not too loud and not too soft.

If you haven't already guessed, the solution is to use a 3-point curve.

The first step is to create the curve. In this example I'm using Curve 32 and initially setting the three points to -100%, 0%, +100%:

The Special Function used is the same as in the previous setup:

But you can use a mix instead of an input if you like:

...Continue Reading
Posted by Miami Mike | Dec 21, 2017 @ 10:36 PM | 5,748 Views
If you're controlling your Taranis volume with one of your potentiometers ("sliders") you might be annoyed that the volume can be accidentally adjusted so high that you get bad distortion, or so low that you can't hear it and you miss important alarms and messages. If the maximum is louder than you want, or the minimum is lower than you want, or both, here's how to confine your volume range within upper and lower limits of your choice.

In this example I'll use RS as the volume control, but it could also be LS, S1, or S2.

You probably have your volume set up like this on your Special Functions page:

That's pretty simple, but to restrict the range you'll need to make it slightly more complicated.

Create an input like this:

It'll look like this on your Inputs page:

...Continue Reading
Posted by Miami Mike | Nov 23, 2017 @ 08:18 PM | 8,333 Views
A "fuel gauge" for your telemetry screen to display your LiPo pack's charge state as a percentage of full charge.

For OpenTX Versions 2.1 and 2.2

Update, 11/27/2017: Permission was requested by and granted to Martin Phillips ("thebriars") to include this in the Version 2.2 update of his OpenTX Documentation.


Here's a "fuel gauge" setup for your Taranis to display your flight battery's state of charge as a percentage, beginning at 100% for a fully-charged pack and decreasing as you consume battery power. It requires a current sensor, such as a FrSky SP-40A - Smart Port 40 Amp Sensor or FrSky SP-150A - Smart Port 150 Amp Sensor.

You'll be able to add alarms and voice announcements that trigger at specific charge states, or at regular time intervals, or each time the charge state decreases by a certain amount so that you'll get announcements at, for example, 100%, 90%, 80%, etc. You'll also be able to bring up announcements whenever you like by flipping a switch.

The battery state will be retained between flights even if the radio is turned off, so a switch is provided to reset the charge state to 100% when the battery is replaced or recharged.

This was designed and tested with OpenTX Version 2.1.9 but should be (and reportedly is) compatible with Version 2.2 as well.

If you have questions, suggestions, requests, or problems, please post in the comment section below.

Begin by configuring the sensor on the Telemetry page.

...Continue Reading
Posted by Miami Mike | Apr 14, 2017 @ 08:26 PM | 12,927 Views
An auto-switching aileron-to-rudder mix for the Taranis
For OpenTX version 2.1.9

Aileron-to-rudder mix is useful but there are times when you want rudder control to be completely separated from aileron control. A common solution is to turn the mix on and off with a switch, but here I'll describe a setup that does the switching automatically. It works like this:
  1. When the aileron stick is moved away from center while the rudder stick is centered, aileron-to-rudder mix is active.
  2. If at any time the rudder stick is moved away from center, the mix is automatically cancelled and the rudder stick takes full control of the rudder. The changeover is slowed slightly for a smooth transition.
  3. When the rudder stick and aileron stick are both centered, the mix is reactivated.
In other words, the rudder is controlled by one stick or the other but never both, and the rudder stick has priority.

A simplified eepe file is attached that demonstrates the setup, and if you have glidsim.lua installed in your /SCRIPTS/TELEMETRY folder you'll be able to watch it work. Activate the glidsim screen with the PAGE button. In Companion simulator, use the [Hold X] function to set the aileron stick away from center, then move the rudder stick and watch what happens.

Note: Of course the attached eepe file is not meant to fly a real model. It's only for demonstration purposes.

In this example, GV1 is used to set the amount of aileron-to-rudder mix. The value should be between 0% and 100%. I have it set to...Continue Reading
Posted by Miami Mike | Mar 26, 2017 @ 11:25 AM | 11,729 Views
Taranis: A Volume Control That Doesn't Take Up Any Pots or Switches
for OpenTX version 2.1.9

Like my other scripts so far, volume.lua is implemented like a telemetry script but doesn't actually provide telemetry. (But in this case it could with modification.) What it does is provide a way to adjust volume and store the setting without using any of the switches, knobs, or sliders that are otherwise used to control your model. Instead, the buttons next to the display are used.

The script needs one global variable ("GV"), which you can name "Volume." It can be any one of the nine global variables in each of your model memories and can even be a different GV for each model, although that would require multiple copies of volume.lua with minor changes to each copy and different filenames. I'm using GV1 in my radio and in the examples that follow.

There are installation instructions embedded in the script but I'll post more detailed instructions here.
  • Download volume.txt from the link below, edit it as needed, rename it to volume.lua, and store it in SCRIPTS/TELEMETRY on your SD card. A follow-up post will display the script so that you can copy and paste it into a text editor if you wish.
  • The GV that you use for volume control needs to be set to "Flight mode 0 value" in flight modes FM1 through FM8.

  • On the Inputs page, create an input to read the volume global variable. In this example I use [I7]:
    [I7]Vol MAX Weight(GV1) [Volume]
...Continue Reading
Posted by Miami Mike | Mar 18, 2017 @ 08:11 AM | 11,891 Views
gimbtest.lua is designed to run as a telemetry screen, although it doesn't actually provide telemetry. It checks each of the four stick functions, throttle, aileron, elevator, and rudder, for the 2049 possible stick values recognized by OpenTX, which range from -1024 to +1024. When each stick value is detected the corresponding screen pixel is set, and slow, careful movement of the sticks will eventually produce a display of which positions are detectable and which are not.

Pressing MINUS (-) will clear the screen and restart the test, and long-pressing EXIT will exit the screen.

When gimbtest.lua is run in Companion simulator the result is not impressive because the values obtained from mouse movement by Companion are very coarse compared to the values obtained from the Taranis gimbals:

The vertical lines in the display each consist of four line segments, one for Thr, one for Ail, one for Ele, and one for Rud. The left segments indicates that the value of -1024 was reached, the center segments indicates that zero was reached, and the right segments indicates that +1024 was reached. All other positions are indicated by individual pixels, with the negative values represented on the left side of center and the positive values represented on the right side.

You can see in the image above that when the script was run on Companion simulator the center segment for Thr did not appear, indicating that a zero reading from the throttle stick could not be obtained.

The number...Continue Reading
Posted by Miami Mike | Mar 13, 2017 @ 05:40 PM | 12,176 Views
This is a continuation of What happens when an offset is applied to a stick-controlled channel, where I'll describe how to implement optimizing of offsets to prevent clipping and stopping short. It's also an example of deriving a method with algebra and then translating it into OpenTX code. For another example, I recommend Differential without GVARs, posted today by Mike Shellim.

To recap, the principle of what I'm calling Optimized Outputs is to maintain access to both Min and Max limits even when the center position is offset. It's equivalent to what happens with off-center subtrims on the Outputs page if subtrims are set to "normal", but not if they're set to "linear." The desired behavior is represented by the green line in this graph:

The red line represents an offset that's not optimized, so that if full stick travel is used with 100% weight, the result is clipping at one end and stopping short at the other end.

The blue line represents an input without any offset.

My algorithm is to compute the distance the stick is from the end of its travel and reduce the weight of the offset accordingly, so that by the time the stick has reached the end of its travel the offset has been reduced to zero and the output has arrived exactly at its limit, just as it does when no offset is applied.

For any position (P) that a stick can be in within the range of -100% to +100%, the distance from the nearest endpoint (D) equals one minus the...Continue Reading
Posted by Miami Mike | Mar 09, 2017 @ 12:42 PM | 11,883 Views
If you program a switch to operate a motor you'll find that the way switches work seems upside-down. Using SE as an example, SE↑ = -100% and SE↓ = +100%.

The simplest way to correct that is to read the switch with a mix that has a negative weight, like this:
CH07 (ESC) SE Weight(-100%) [Motor]
But here's the pitfall: Suppose you want the motor to come on slowly but turn off immediately. You would probably expect this to work:
CH07 (ESC) SE Weight(-100%) Slow(u1.0:d0) [Motor]
This looks like it would take one second to slowly increase the throttle to full power when SE is switched to SE↑, but immediately turn the motor off when SE is switched to SE↓. However, it works exactly the opposite way. The mix above causes the throttle to jump to full power immediately with SE↑ but slowly decrease to off over the course of one second with SE↓.

This is what works:
CH07 (ESC) SE Weight(-100%) Slow(u0: d1.0) [Motor]
The reason for this is that, contrary to data flow diagrams that were promised to be corrected over two months ago , the Delay and Slow functions are processed at the beginning of a mix, not at the end.
Posted by Miami Mike | Mar 04, 2017 @ 10:36 PM | 12,175 Views
In a glider setup there are many cases where offsets are applied to stick-controlled channels. The flaps and ailerons are offset upward for reflex and downward for camber. The elevator is offset downward for flap compensation. The rudder is offset left or right when aileron-to-rudder mixing is applied. On top of that, when trim is added to any stick it results in an offset. What happens when an offset is applied?

The control surface moves to the desired offset position when its stick is centered, but when the stick is moved away from center and nears the limit of its travel in either direction, bad things can happen.

When the stick is moved in the same direction that the offset is applied, and the stick input plus the offset reaches or exceeds the -100% to +100% limit, no further movement of the stick in that direction will do anything. As long as you've set up your Outputs screen properly it won't result in any damage or stress, but you still have a region of stick travel that's essentially dead. That's Clipping.

When the stick is moved in the direction opposite the direction the offset is applied, and the stick reaches the limit of its travel, the output will stop short of it's limit and a portion of the output range will be unavailable no matter how you move the stick. That's Stopping Short.

The solution is to handle offsets a little differently by giving stick input priority over them. Compute the distance the stick is from the end of its travel and reduce the...Continue Reading
Posted by Miami Mike | Mar 03, 2017 @ 10:13 AM | 12,441 Views
Mixes are for mixing, inputs are for selecting.

Note: Since I first wrote this, Inputs have also become my preferred choice for applying curves and functions.

It may be that you're performing operations on your Mixes page that could be done instead on your Inputs page. The Inputs page isn't just good for selecting rates and exponential for your sticks, you can move virtually any operation that consist solely of selecting, rather than mixing, to the Inputs page. This can be useful for removing clutter from your Mixes page and more evenly distributing your setup across the two pages, which both limit their number of lines to 64.

Here's an example from my glider setup, where I use TrmT to adjust reflex and camber in four different flight modes. It started out on the Mixes page:

CH10(RfxCam)  TrmT Weight(+50%) Flight mode(Zoom) Offset(50%) [Zoom]
           += TrmT Weight(+25%) Flight mode(Speed) Offset(25%) [Speed]
           += TrmT Weight(+25%) Flight mode(Thermal) Offset(-25%) [Thermal]
           += TrmT Weight(+50%) Flight mode(Launch) Offset(-50%) [Launch]
Channel 10 was being read by the aileron and flap output channels with mix lines similar to this one (this is not exact):

CH01 (RtAil) CH10 Weight(+100%)
This worked fine but my mix lines were starting to run short and I wanted to clean up the page, so I moved the operation to the Inputs page and added a "catchall" at the end to make sure that the input explicitly contributes a value of zero when not in a flight mode that incorporates reflex or camber:

[I4]RxCm TrmT Weight(+50%) Flight mode(Zoom) Offset(50%) [Zoom]
         TrmT Weight(+25%) Flight mode(Speed) Offset(25%) [Speed]
         TrmT Weight(+25%) Flight mode(Thermal) Offset(-25%) [Thermal]
         TrmT Weight(+50%) Flight mode(Launch) Offset(-50%) [Launch]
         MAX Weight(0%) [Default]
Now, on the Mixes page I read the input with lines similar to this:

 [I4]RxCm Weight(+100%)
With this technique I've relocated quite a few of my mix lines to my Inputs page, and now I have plenty of space open for new mixes.