PC joystick to 8ch Tx conversion

3689466544?profile=originalI've been looking at my unused twist grip joystick for a while now thinking about hooking it up to a transmitter via the PPM trainer port.

I might go a step beyond this and get a new 2.4GHz Tx module and add that to the joystick to make it a transmitter.

Fly-Dream make an affordable and reliable 2.4GHz DIY module with three pins for GND,+,PPM in.

I've been able to generate PPM from an Arduino in the past so now it's a matter of hooking the pots in the joystick to the analog pins and the buttons to the digital pins.  The pots move over a portion of the total travel in a joystick so my Vref will need to be a bit above the max voltage the pot will register.  So if the pot only travels between 0 to half way and I feed the pot +5v then the max output voltage will be 2.5V.  

I've also ordered an 8ch 12bit ADC I2C breakout which samples at about 12KHz.  This will give me more leg room at reading resolution of 4095.  The high resolution reading then goes through expo / trim / end point / sample filtering maths and comes out at a resolution of 1024 per channel.  As far as I can tell the PPM output resolution does not need to be any higher than that, nor do I think the timing in an Arduino can get any better than that.

The hat switch can be coded to move the camera tilt servo.  Might even pop out the digital hat switch and put a Wii joystick in there for tilt rate control.  

With the 8 or more buttons on the joystick I should be able to code it to give me all the PWM levels needed for channel 6 modes on the Arducopter.

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • Below is the internal wiring of the PCB.  The black "D" components are 2:1 diodes.  "S" are the buttons. Connector pins are marked 1-5.  GND and +5V are connected as separate pins and are shared by the yaw pot.
    3692459645?profile=original

  • Just remembered that if I use the external I2C ADC I can use the analog pins as extra button inputs.  The V3 Nano I have will give me A0-A3 and A6-A7 (A4/A5 for the I2C to the ADC) as button reading pins. 

  • Button 1 and 2 are on the other side of that PCB photo.

    Connector at the base of the joystick column is an 8 pin 2mm pitch connector.

    Wire colour to Arduino Digital Pin :

    Blue -> D2

    Yellow -> D3

    Green -> D4

    Black -> D5

    Brown -> D6

    Orange -> D7

    Red -> D8

    That leaves D9-D13 (5) for any other buttons you want to use on the base of the Logitec joystick.  The base buttons appear to be mapped 1:1 with the connector pinouts so no tricky coding required.

  • //5 Pin PCB connecter + Yaw pot GND and 5V pins
    //connected to digital pins 2 to 8
    const int C1 = 2;
    const int C2 = 3;
    const int C3 = 4;
    const int C4 = 5;
    const int C5 = 6;
    const int GND = 7; //GND yaw pot
    const int V5 = 8; //+5V yaw pot

    //When the yaw pot requires reading
    //pin 7 should be set to Output Low
    //pin 8 should be set to Output High.
    //Yaw pot is 100k.
    //Code to read yaw pot will be in a
    //separate routine and will read
    //via an external I2C 12bit ADC.

    int S1state = 0;
    int S2state = 0;
    int S3state = 0;
    int S4state = 0;
    int S5state = 0;
    int S6state = 0;
    int S11state = 0;
    int S12state = 0;
    int S13state = 0;
    int S14state = 0;

    void setup() {
      Serial.begin(57600);
    }

    void loop(){

      //Clear button states
      S1state = 0;
      S2state = 0;
      S3state = 0;
      S4state = 0;
      S5state = 0;
      S6state = 0;
      S11state = 0;
      S12state = 0;
      S13state = 0;
      S14state = 0;


      //Switch states are read sequentially.


      //buttonState(Low Pin, High Pin)
      //closing the switch pulls the High Pin Low

      //Switch 1
      if (buttonState(GND,C1)) {
        S1state = 1;
      }

      //Switch 2
      if (buttonState(C5,C3)) {
        S2state = 1;
      }

      //Switch 3
      if (buttonState(C4,C1)) {
        S3state = 1;
      }

      //Switch 4
      if (buttonState(V5,C3)) {
        S4state = 1;
      }

      //Switch 5
      if (buttonState(GND,C3)) {
        S5state = 1;
      }

      //Switch 6
      if (buttonState(C4,C3)) {
        S6state = 1;
      }

      //Switch 11

      if (buttonState(V5,C2)) {
        S11state = 1;
      }

      //Switch 12
      if (buttonState(GND,C2)) {
        S12state = 1;
      }

      //Switch 13
      if (buttonState(C4,C2)) {
        S13state = 1;
      }

      //Switch 14
      if (buttonState(C5,C2)) {
        S14state = 1;
      }

      Serial.print("S1:");
      Serial.print(S1state);
      Serial.print(" ");
      Serial.print("S2:");
      Serial.print(S2state);
      Serial.print(" ");
      Serial.print("S3:");
      Serial.print(S3state);
      Serial.print(" ");
      Serial.print("S4:");
      Serial.print(S4state);
      Serial.print(" ");
      Serial.print("S5:");
      Serial.print(S5state);
      Serial.print(" ");
      Serial.print("S6:");
      Serial.print(S6state);
      Serial.print(" ");
      Serial.print("S11:");
      Serial.print(S11state);
      Serial.print(" ");
      Serial.print("S12:");
      Serial.print(S12state);
      Serial.print(" ");
      Serial.print("S13:");
      Serial.print(S13state);
      Serial.print(" ");
      Serial.print("S14:");
      Serial.print(S14state);

      Serial.println(" ");
    }

    void resetPins(){

      //Pin 1 Output Low (forced GND) (disables buttons 1, 3)
      pinMode(C1, OUTPUT);
      digitalWrite(C1, LOW);
      //Pin 2 Output Low (forced GND) (disables buttons 11, 12, 13, 14)
      pinMode(C2, OUTPUT);
      digitalWrite(C2, LOW);
      //Pin 3 Output Low (forced GND) (disables buttons 2, 4, 5, 6)
      pinMode(C3, OUTPUT);
      digitalWrite(C3, LOW);
      //Pin 4 Input High (disables buttons 3, 6, 13)
      pinMode(C4, INPUT);
      digitalWrite(C4, HIGH);
      //Pin 5 Input High (disables buttons 2, 14)
      pinMode(C5, INPUT);
      digitalWrite(C5, HIGH);
      //V Input High (disables buttons 4, 11)
      pinMode(V5, INPUT);
      digitalWrite(V5, HIGH);
      //GND Input High (disables buttons 1, 5, 12)
      pinMode(GND, INPUT);
      digitalWrite(GND, HIGH);

    }

    bool buttonState(int lowPin, int highPin) {

      resetPins();

      //Low Pin
      pinMode(lowPin, OUTPUT);
      digitalWrite(lowPin, LOW);
      //High Pin to read
      pinMode(highPin, INPUT);
      digitalWrite(highPin, HIGH);
      int pinState = 0;
      pinState = digitalRead(highPin);

      if (pinState==LOW) {
        return true;
      }
      else
      {
        return false;
      }

    }

  • Here is the pinouts for the handle PCB which can be connected directly to an Arduino's digital pins.  Code to read the pins to work out which button is being pressed will be in the next post.
    3692459818?profile=original

  • Went through that thread and could not find a mention of the hat switch pcb pinouts and how he wired it to the Arduino.  Hopefully Ian will respond with some insight on how the hat switch is wired up on that thread.  Starting to wonder if the external 12bit ADC is overkill.  I just remember seeing that the PC reads a full 16bit resolution for each pot and that there were fluctuations in the values (noise).  The idea is that 12bit will be enough resolution (and sample rate is higher with the I2C ADC) for sampling and filtering to get a nice clean and smooth value to work with.

  • Well I'll be, that's very close to what I was thinking of doing.  The only difference is that the TX will be in a small box attached via a 1m cable and the joystick will still look the same as it did when I bought it.  Ultimately I want a setup that feels like the full size controls of a real heli with the collective (throttle only in this case) on the left of the chair.  Slip on the Fat Sharks and go plough the Y6 copter into the ground without the fear of killing myself.  Might also attach an external accelerometer to the Arduino and use that for pitch tilt of the camera.

    I'll go and see the connection diagram now to see how Ian worked out the connections for the logitec buttons.

    Hats off to him for the work he has already done.  You can buy a product already which does something similar and uses the USB connection, however this does work out to be a much cheaper option.

  • Hey John check this out.. It is really similar to what your doing but we use the built in analog to digital. Ian just setup a google code page and should be posting a link to it soon. The just released beta has 8 channels and uses the same logitech hat switch :) I'm using it to build my own custom TX thats a hybrid RC transmitter with a logitech twist grip where the right gimbal used to be. 

     RC Joystick

    a3487178-232-photo.jpg

  • This is a great idea. I too have a joy stick collecting dust and thought of the same thing.

    There are folk who would like to enter the hobby but have trouble transitioning to a two-handed control system. This especially true with full size plane pilots that get the bug to start model flying. If they started with a joystick and built muscle memory with that, a project like this would make the move to models easier.

    After getting my Rover to a stopping point.. I will have to look over that joystick.. now where is it?

  • The thumb buttons on this Logitec joystick do not have a 1 for 1 pinout on the cable that feeds down to the existing control board.  Looks like it feeds out binary info on four or five pins to reflect the 10 button states (four for a hat switch).  Might even be four analog states for the hat switch on one other wire. Could be wrong though.  If I give up working it out I'll just rewire direct to each switch.  The buttons on the base of the joystick are wired 1 for 1 however there are only so many digital inputs on the 328 Arduino board.  I really just need 6 buttons to alternate between the 6 modes on the channel 6 output.

    I'll set up the failsafe on the Fly-Dream module to RTH.

This reply was deleted.