Hello and welcome to our community! Is this your first visit?
View RSS Feed


$15 Transmitter Modification: Replacing AUX or MODE VRs with discrete switch inputs

Rating: 5 votes, 5.00 average.
When developing and debugging new features I often have a need to command the quad in real-time to turn something on or off. Stable mode is a good example. The standard AeroQuad distribution uses the Transmitter's "Mode" input to select stable mode. If the variable resistor on the transmitter is turned up more than half way, stable mode is activated. Similarly, heading hold is activated using the AUX input.

But what if there are other mutually exclusive features that need enabling on the fly, such as auto-hover, auto-land, camera shutter, etc?

Reverse engineering the HK-T6A MODE & AUX Variable Resistors
I started my AeroQuad journey with the inexpensive Hobby King HK-T6A V1 (here is a link to v2). Opening it up I discovered that the MODE and AUX variable resistors were simply a 5K POT between regulated +5V and ground with the tap feeding an analog input pin on the Transmitter's processor thus forming a variable voltage divider. The processor is just reading the voltage and producing a corresponding PWM pulse on the appropriate transmitted time slot. 0V is about 1000, 5V is about 2000.
A binary voltage summation circuit: the magical R-2R resistor ladder
So, how might I replace this POT with a set of discrete switches such that the PWM produced can be decoded on the quad back into the state of each switch? I figured I'd need a binary resistor divider scheme but was'nt quite sure how to construct one. A little googling and I found the R-2R resistor ladder. Perfect and dead simple. All it requires is SPDT switches and and two values of resistors and you have yourself a binary coded voltage divider. Turns out some DAC chips use the R-2R scheme internally to turn parallel binary data into a corresponding output voltage. Here is a schematic of the R-2R ladder.

Name:  R-2R.jpg
Views: 3013
Size:  13.7 KB
How many switches can I use to replace one POT?
Now I needed to figure out how many switches I could support. Using the AeroQuad's serial telemetry "V" command to print out the raw received PWM values I determined that the resolution of the AeroQuad in combination with the HK-T6A is 4, e.g. 1004, 1008, 1012, etc. That means over the range of 1000..2000 there are just 256 discrete steps. I also noticed that there was jitter in the signal. When I set the POT on the transmitter and was receiving, for example, 1532, occasionally the value would jump to 1536, and much less frequently down to 1528. So jitter is +/- 4, therefore the effective resolution is down to 128 discrete steps which is 2^7 or 7 switches, best case. It turns out that unless you use ultra-precise resistors and well matched R-2R pairs there is some variability in voltage steps which introduces error. To accommodate this, I dropped another bit, giving me a theoretical maximum of 6 switches. Since my HK-T6A has 5 nice and tidy little slots on the bottom front of the case, I decided to just use 5 switches with an R-2R ladder to replace the AUX variable resistor. I had some old SPDT switches on hand similar to these and I ordered some 1% 10K and 20K resistors from Digi-Key ($0.15 each), breadboarded it up, desolderd the +/gnd/tap from the AUX variable resistor, connected it to the ladder and voila - it worked!

Modifying the HK-T6A V1 Transmitter
To get started I disassembled my HK-T6A by removing the battery cover, battery and 4 screws on the back cover. Removing a single screw frees the main circuit board on the bottom. As you can see below, there are 5 nice little slots in the front cover - presumably some variant has 5 slide switches for some purpose.
Name:  CIMG6073.jpg
Views: 2771
Size:  44.0 KB

I poked holes through the label covering these slots and temporarily inserted 5 toggle switches through the front. This made it much easier to solder on all the resistors without having to fumble with the soldering iron down inside the back of the case.
Name:  CIMG6078.jpg
Views: 2683
Size:  49.8 KB
The bottom switch lugs are bussed together and tied to +5, the top lugs are bussed together and tied to Ground, the end of the resistor on the top right is the output lead. I must confess that I got lucky. Hooking it up this way meant that when the switches are in the down position, the equivalent "0" is transmitted, and when they are "up" an equivalent "1" is transmitted. When all the soldering was completed I pulled the assembly off the front of the case and inserted it through the back and spun on the retaining nuts on the front. I then soldered the leads removed from the AUX POT: blue center tap to the R-2R ladder output, red/+5V to the bottom switch bus, black/GND to the top switch bus.
Name:  CIMG6083.jpg
Views: 2286
Size:  45.7 KB
I covered the exposed wires/lugs with electrical tape to prevent shorting, reinstalled the main circuit board and reassembled the case.
Name:  CIMG6091.jpg
Views: 2081
Size:  26.7 KB
Unfortunately I was using some really old toggle switches and one of them was bad and had to be replaced. After fixing that the AeroQuad was receiving the predicted PWM values on the AUX channel for various combinations of switch settings.
Decoding PWM back into discrete switch states
Decoding the PWM is pretty simple. Since the ladder produces a binary voltage summation we just have to incrementally determine if the PWM associated with each bits voltage is present. When I switched on the MSB (left most switch) the received PWM was 1501, exactly half the 1000..2000 range, just as expected, so the decoding logic is pretty straight forward. If the MSB (left most switch) is set, the normalized PWM value received will be > 500. If set, we substract 500 from the PWM value and then see if the result is > 250, if so the second left most switch was set. If set, subtract 250 and test for 125. And so on. Here is the simple decode logic. When testing I discovered that the LSB would, on occasion, not decode properly due to errors accumulated in successive subtractions. Subtracting just a little more on the very last bit "- (idx>1?0:5)" solved the problem.

int  AUXSwitches[5] = {0,0,0,0,0};
#define AUXBITS 5         //Num Aux switches minus 1
// Decode AUX switches
    int idx, astep, aval;
    aval = receiverData[AUX]-1000;                         // Start with raw received value, normalize to 0..1000
    for (idx=AUXBITS; idx>0; idx--) {                      // Loop through each of the BITS (5..0), starting with MSB
      astep = (1000 / (2<<(AUXBITS-idx))) - (idx>1?0:5);   // (1000 / 2^idx) determines step value.  Last bit needs a bit more range.
      AUXSwitches[idx-1] = aval > astep;                   // Set bit to 1 in array if current value is > step, otherwise 0
      aval-=AUXSwitches[idx-1] * astep;                    // If bit was set, remove corresponding amount from value for next interation
  case '?':   // Debug print received AUX switch values, X to stop
    int i; 
    for (i=4; i>=0; i--)
      Serial.print (AUXSwitches[i]); Serial.print (" ");
Now, to use these switches in the AeroQuad code I simply assign a function to a switch number and index the AUXSwitches[] array to determine if the switch is on or off. It should be noted that this sketch does decode but it doesn't debounce or do error checking or adjust for transmitter calibration. For example, if the Transmitter is not turned on, the values may be undefined. Transmitter calibration may skew the effective range of PWM values received. Error checking & calibration logic will be incorporated before I use this for any flight critical functions.
Final Thoughts
I suspect that most types of Transmitters use a similar variable-resistor voltage divider scheme to sense and encode auxiliary channels. If so, an R-2R ladder can be used to convert any of these to a digital input. A separate hobby enclosure can be used to hold the switches if you do not wish to modify your case. You can probably press this to 6 or 7 bits/switches if the resolution of your Tx/Rx and AeroQuad PWM RX timing logic supports it. Of course, you could use one bank of switches to replace the MODE VR, and a second bank for the AUX VR if you had lots of functions to control. I may add another switch to the case that switches the processor input between the original AUX variable resistor and the switch bank. This would allow the transmitter to be instantly reverted to its original function for use with other R/C models. In the extreme you could probably use a simple DAC in place of the R-2R and transmit digital data at a very sloooow bit rate from a computer through your TX to the quad - but then Xbee is much better suited for that!


Submit "$15 Transmitter Modification: Replacing AUX or MODE VRs with discrete switch inputs" to Digg Submit "$15 Transmitter Modification: Replacing AUX or MODE VRs with discrete switch inputs" to del.icio.us Submit "$15 Transmitter Modification: Replacing AUX or MODE VRs with discrete switch inputs" to StumbleUpon Submit "$15 Transmitter Modification: Replacing AUX or MODE VRs with discrete switch inputs" to Google

Updated 12-19-2010 at 03:31 PM by wilafau



  1. ala42's Avatar
    The calculation gets a lot easier when you map the input range of 1000-2000 to 0-2^5 for your 5 switches (0-32), e.g.
    halfBit = 1000/32/2;
    aval = ((receiverData[AUX]-1000 + halfBit) * 4) / 125

    Now each bit in aval represents one of your five switches. The shift by halfBit makes sure you hit the range in the middle.
  2. wilafau's Avatar
    ala42 - Very very clever!! Since the receiver value is already binary coded mapped to the range 1000-2000 it is simply a matter of dividing by the mapping factor to turn it back into the original binary code. As you said the halfbit makes sure you hit the middle of the range. Took me a moment to figure out that *4 / 125 is actually the same as dividing by the scale factor 1/(1000 / 2^5) = 1/31.25 = 4/125.

    I'll give it a try and check that I don't still have a little issue with the LSB in practice.

    Now if only the BB codes would get turned back on I'd update the post!
  3. ala42's Avatar
    Right, I should have explained that *4/125 is like *32/1000, it just keeps the numbers smaller. I wanted to be sure that (receiverData[AUX]-1000 + halfBit) * factor stays in 16 bit int range even if receiverdata is a bit larger or smaller than expected, so I reduced the fraction.
  4. vedder's Avatar
    Thats pretty kick ass!