Friday, December 30, 2016

R/C Radio Hack: Adding Head Tracking to 3 Channel Surface Transmitter

When building a SCX10 R/C rock crawler, I purchased a FS-GT3B transmitter from FlyKsy because it was cheap ($38) and I had seen this hack for controlling up to 8 channels.  I wanted to have extra channels to transmit head-tracking for a camera gimbal. At the time there were no surface radios (steering wheel and gun throttle) that could send more than 3 channels that I could find.

1. Axial SCX10 Rock Crawler
As it turns out, the above mentioned hack did not actually explain how to add more channels, so I decided to add the channels by mixing PPM signals.  The FS-GT3B radio normally transmits 3 channels by PPM, which is normally high (3.3V).  The head tracker I used, a Fat Shark Trinity External, transmits 8 channels by PPM, also normally high (3.3V). Only channels 5, 6, and 7 carry the tracking data. See diagram below. I bought a Turnigy 9X8C v2 eight channel receiver, so there is room for extra data. The Trinity came with an 1/8" cable so I added a new jack to my radio:
2. FS-GT3B with Added 1/8" Jack
Here's how the Fat Shark tracker works:

3. Fat Shark Trinity External Tracker Pinout and Cable Diagram
4. Tracker PPM Output

I tried the HKPPM-Mix but did not find it to work. Maybe it requires normally low PPM? This forum mentions a similar setup working, but the tracker is different.

So then I added a Teensy 3.2 and found the totally awesome PulsePosition library by Paul Stroffregen at PJRC, which makes the mixing code very simple:

#include "PulsePosition.h" // blogger won't let me show carats so using quotes

PulsePositionInput RadioIn(FALLING);
PulsePositionInput TrackerIn(FALLING);
PulsePositionOutput MixOut(FALLING);

// Library allowable inputs are pins 5,6,9,10,20,21,22,23

const uint8_t  RADIO_INPUT_PIN   = 22;
const uint8_t  TRACKER_INPUT_PIN = 23;
const uint8_t  MIX_OUT_PIN       = 20;

void setup() {
  RadioIn.begin(RADIO_INPUT_PIN);
  TrackerIn.begin(TRACKER_INPUT_PIN);
  MixOut.begin(MIX_OUT_PIN);
}

void loop() {
  int i, num;
  int j = 0;

  // Check if Radio signals need updating
  num = RadioIn.available();
  if (num > 0) {
    for (i=1; i >= num; i++) {
      float val = RadioIn.read(i);
      MixOut.write(i, val);
    }
  }
  
  // Check if Tracker signals need updating and Map 5,6,7 to 4,5,6
  num = TrackerIn.available();    
  if (num > 0) {
    for (i=1; i >= num; i++) {
      float val = TrackerIn.read(i);
      switch (i) {
        case 5:
          j = 4;
          break;
        case 6:
          j = 5;
          break;
        case 7:
          j = 6;
          break;
        case 8:
          j = 0;
          break;
        default:
          break;
      }
      if (j != 0) {
        MixOut.write(j, val);
      }
    }
  }
}

The RF transmitter inside the FS-GT3B radio is nicely labeled with GND, +5V, and PPM, so it was easy to connect the microcontroller. There is just enough room on the radio PCB to cut the PPM trace, so that it can re-route into the mixer.

5. Schematic for FS-GT3B to Teensy 3.2 with Fat Shark Trinity External Tracker

6. RF Transmitter Connections and Test Point Connection (see schematic)

7. PPM Trace Cut on PCB Top Side

8. Teensy Installed Under Main PCB Near Power Switch

Here's a video of the finished setup working:



I tried using a Teensy LC for lower cost, but wasn't getting any output yet. To be continued...

And up next, build the camera gimbal...