Leostick Joystick? Yes, and here's how.

A shrunk down Leonardo-compatible board, thumb drive sized with native USB support. [Product info]
drake250
Posts: 19
Joined: Mon May 28, 2012 1:17 pm
Location: Adelaide

Leostick Joystick? Yes, and here's how.

Post by drake250 » Sun Jul 01, 2012 3:02 am

So, I've been playing with my leo for a while, wondering if I could turn it into a USB joystick...
and I did :D

This id for the old v1 bootloader - There's an update for the v2 bootloader and v3.3 board profile later on in this thread!

By modifying the HID descriptor code (inexpertly I might add) I got it appearing as a 4-axis 8 button joystick. Most of the HID stuff came from Helm PCB's USB joystick page (he uses a PIC micro, but the HID stuff and schematics would work fine with a leo)

So, what I did was add another section in HID.cpp to describe a joystick and added a Joystick_::move method based on Mouse.move
USPAPI.h also needed the Joystick stuff and... well it'll be easier if I post my modified files for those who are interested.
leostick joystick.JPG
This little Leo can do it all!
Attachments
USBAPI.h
USB header file from (sketchbook)/hardware/LeoStick/cores/arduino/USBAPI.h
(4.93 KiB) Downloaded 1222 times
HID.cpp
HID code from (sketchbook)/hardware/LeoStick/cores/arduino/HID.cpp
(13.33 KiB) Downloaded 1371 times
Last edited by drake250 on Sat Sep 14, 2013 4:46 am, edited 1 time in total.

Tripod
Posts: 9
Joined: Tue Jul 24, 2012 1:14 pm

Re: Leostick Joystick? Yes, and here's how.

Post by Tripod » Tue Jul 24, 2012 2:26 pm

Hi Drake250, I am interested in these modified joystick files.

I am new to the arduino world & know how to load a sketch but can you explain exactly what to do with these modified files to turn the leostick into a joystick, sorry it is just not clear what to do in your post.

Cheers Tri.

drake250
Posts: 19
Joined: Mon May 28, 2012 1:17 pm
Location: Adelaide

Re: Leostick Joystick? Yes, and here's how.

Post by drake250 » Thu Jul 26, 2012 9:50 am

Well, when you first install the leostick files (using method 2 in the guide) you should have installed the "Freetronics LeoStick" board profile into the sketchbook directory. In there you will find all the leostick-specific source code - this is what gets compiled along with your sketch to make a working program, and it's where the USB interface code is.

The 2 files I modified are from the following location (and are part of the Freetronics leostick board profile):
(sketchbook)/hardware/LeoStick/cores/arduino/

So if you want to give the joystick a try, copy USBAPI.h and HID.cpp into that directory - there should already be the original versions there. To use the joystick in a sketch is then as simple as:

Code: Select all

Joystick.move(throttle, z, x, y, buttons)
Since my first post I have converted an old gameport Logitech Wingman Attack to USB, as well as a "prototype" steering wheel & pedals, and have done quite a bit more work on the HID descriptor - The updated files are below, please note that it is currently set up for a steering wheel with pedals and 6 buttons. An alternate setup is also included but commented out - it's the one I used for the wingman conversion. Have a read through the code - I added a lot of comments to explain it all better. A sample sketch is there too.

Hope this helps!
Attachments
wheel_pedals_demo.zip
Example sketch.
(995 Bytes) Downloaded 1034 times
HID.cpp
HID code from (sketchbook)/hardware/LeoStick/cores/arduino/HID.cpp (v2)
(17.63 KiB) Downloaded 775 times
USBAPI.h
USB API header file from (sketchbook)/hardware/LeoStick/cores/arduino/USBAPI.h (v2)
(5.03 KiB) Downloaded 647 times

Tripod
Posts: 9
Joined: Tue Jul 24, 2012 1:14 pm

Re: Leostick Joystick? Yes, and here's how.

Post by Tripod » Thu Jul 26, 2012 10:36 am

Thanks for the explanation Drake, I will down load these later files and have another play.

I did manage to locate the original files in the locations you mentioned but was not sure what else to do, I will give it a try.

I am currently building a flight simulator, I am after a mother load of switch inputs and I am hoping this may be a rather cheap solution to getting lots of switches, so I am not particularly interested in the axes as I already have sticks for that purpose.

Can you comment on whether the leostick hid files could possibly be adjusted to turn all analog inputs to digital ins, therefore giving us a 20 button controller, also moving on further is it possible to do this with an arduino mega and therefore getting even more button inputs.
I am seriously looking at a couple of hundred inputs, a joystick hid device is the perfect solution as the software natively talks to the standard windows joystick drivers.

Anyhow I will study your commented files and see if I can get my head around it.

Thanks for the info.

Cheers Tri.

drake250
Posts: 19
Joined: Mon May 28, 2012 1:17 pm
Location: Adelaide

Re: Leostick Joystick? Yes, and here's how.

Post by drake250 » Fri Jul 27, 2012 8:11 am

Sounds cool... and I think the leostick will be perfect.

The only trouble with using the leostick as a joystick is that there is no generic setup that will work for everyone - a different number of buttons or axes requires a custom HID descriptor and the code to match, so each project needs to be hand-crafted.

On the software side, I don't see a problem defining a joystick with no axes and just a bucketload of buttons. The descriptor tool let me define buttons 1 to 63, and I repeated it to try for 126 in 2 groups. It seems to work, but I have no idea how many actually work because I just used random output, and windows only shows me 32 buttons before the dialog box runs out of space.

As for wiring up that many buttons, I would suggest some sort of matrix-scan type thing. If you chained a few shift registers together (http://www.freetronics.com/collections/ ... ion-module) you could scan a 16x8 matrix with just 11 digital pins (3 output and 8 input) and 2 shift registers.

As far as I know, keyboard and mouse functionality (and now joystick) is unique to the Leonardo.

drake250
Posts: 19
Joined: Mon May 28, 2012 1:17 pm
Location: Adelaide

Re: Leostick Joystick? Yes, and here's how.

Post by drake250 » Fri Jul 27, 2012 1:23 pm

Just finished testing, and Windows only picks up the first 32 buttons :(
(Win XP sp2, using "Torcs - The Open Racing Car Simulator" 1.1.3 to test)

Tripod
Posts: 9
Joined: Tue Jul 24, 2012 1:14 pm

Re: Leostick Joystick? Yes, and here's how.

Post by Tripod » Sat Jul 28, 2012 1:29 pm

I got it working great with your second post, thanks so much.

Is there any chance you can post the 32 button example, that would be of benefit to me.

I think you are quite right, windows only goes up to 32 buttons per joystick, I don't think I have seen any controllers with more than that available.

Cheers Tri.

drake250
Posts: 19
Joined: Mon May 28, 2012 1:17 pm
Location: Adelaide

Re: Leostick Joystick? Yes, and here's how.

Post by drake250 » Tue Jul 31, 2012 7:10 am

Well, here's a modified copy of HID.cpp and USBAPI.h, along with a test sketch. I removed all the "alternative" configs to make it a bit neater. I didn't use any buttons for testing, just randomly simulated button presses.

One thing I found, Torcs wouldn't pick up the controller until I added an analog axis as well - so I put it in just to be safe. To use, simply put the button values into a 4 byte array and pass it to Joystick.move along with a dummy value for the throttle (zero throttle = 255)

Good luck with the controller.
Attachments
Leostick Buttons.zip
32 button controller (w/ 8 bit throttle) and example sketch
(5.65 KiB) Downloaded 970 times

Tripod
Posts: 9
Joined: Tue Jul 24, 2012 1:14 pm

Re: Leostick Joystick? Yes, and here's how.

Post by Tripod » Thu Aug 16, 2012 11:31 am

Hey Drake250,
Well I finally got some code together & have made good use of your modified firmware, Thankyou so much.

I thought I would post my code for anyone else to use that may be interested.

Could I ask you a favour ?

Is there any chance you could modify the firmware to enable all the Analogue Axis & make them available at 10bit resolution, maintaining the 32 Buttons.
I could certainly make use of the Axis as well.

In this sketch I Have created a Key Matrix Scan of 4 Columns & 8 Rows.
It seems to be working perfectly.

Please note that 1N4148 Diodes are required between the each Column & Row (32 Diodes required) to stop a problem called button ghosting.
Connect the Anode to the Column in series with the button & the Cathode to the Row.

See this link for a good explanation on using button matrix.
http://www.dribin.org/dave/keyboard/one_html/

Anyhow Here is my Code:
I have put in lots of comments cause I am new at this !!

Code: Select all

// Leostick Joystick Controller with 32 Buttons Sketch
// Modified firmware required for the Freetronics Leostick http://www.freetronics.com
// Check the LeoStick Forum section, The Modified Joystick Firmware is Available there.
// Written By Glenn Weston forummail@bigpond.com
//Please note that 1N4148 Diodes are required between the each button & Column (32 Diodes required) to stop a problem called button ghosting. 
//Connect the Anode to the Column in series with the button & the Cathode to the Row.


void setup() {
  //Setup Columns
  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  
  //We should enable the internal pullup resistors so the inputs are not floating & subject to spurious noise.
  //Otherwise external pullup resistors are required, there is no point in buying more components.
  //So Enable internal pullup resistrors.
  digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  
  //Setup Rows
  //I skipped Pin 11 because the Piezo was singing with high scan rates
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(12, OUTPUT);
}

void loop() {
  //this defines an array of variables
  //position 0 defines the value for buttons 1-8
  //position 1 defines the value for buttons 9-16
  //position 2 defines the value for buttons 17-24
  //position 3 defines the value for buttons 25-32
  uint8_t buttons[4]; 0,0,0,0;
  
  //Now we are scanning the Matrix of Rows & Columns to sample which buttons are being pressed.
  
  //set colunm 0 LOW 1 HIGH 2 HIGH 3 HIGH
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(12, HIGH);
  //read status of row1
  int row1 = digitalRead(0) + (digitalRead(1) << 1) + (digitalRead(2) << 2) + (digitalRead(3) << 3) + (digitalRead(4) << 4) + (digitalRead(5) << 5) + (digitalRead(6) << 6) + (digitalRead(7) << 7);
  
  //set colunm 0 HIGH 1 LOW 2 HIGH 3 HIGH
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  digitalWrite(12, HIGH);
  //read status of row2
  int row2 = digitalRead(0) + (digitalRead(1) << 1) + (digitalRead(2) << 2) + (digitalRead(3) << 3) + (digitalRead(4) << 4) + (digitalRead(5) << 5) + (digitalRead(6) << 6) + (digitalRead(7) << 7);
  
  //set colunm 0 HIGH 1 HIGH 2 LOW 3 HIGH
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, LOW);
  digitalWrite(12, HIGH);
  //read status of row3
  int row3 = digitalRead(0) + (digitalRead(1) << 1) + (digitalRead(2) << 2) + (digitalRead(3) << 3) + (digitalRead(4) << 4) + (digitalRead(5) << 5) + (digitalRead(6) << 6) + (digitalRead(7) << 7);
  
  //set colunm 0 HIGH 1 HIGH 2 HIGH 3 LOW
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(12, LOW);
  //read status of row4
  int row4 = digitalRead(0) + (digitalRead(1) << 1) + (digitalRead(2) << 2) + (digitalRead(3) << 3) + (digitalRead(4) << 4) + (digitalRead(5) << 5) + (digitalRead(6) << 6) + (digitalRead(7) << 7);
  
  //valid values for activating the butons in each row of 8 are:
  //0=ALL OFF 1=B1 2=B2 4=B3 8=B4 16=B5 32=B6 64=B7 128=B8 
  //Add up the values for the whole row, so 255=ALL ON
    
  //Here we are inverting the Values, this will show a button active when a switch is in the on position (Contacts Closed)
  //Otherwise the button shows active when the switch is OFF (Contacts OPEN)
  int row1_inv = 255 - row1;
  int row2_inv = 255 - row2;
  int row3_inv = 255 - row3;
  int row4_inv = 255 - row4;
    
  //Here we are passing the final values of each row to the 4 positions in the array.
  buttons[0] = row1_inv;
  buttons[1] = row2_inv;
  buttons[2] = row3_inv;
  buttons[3] = row4_inv;
  
  //Here we are calling Joystick.move with the final values.
  Joystick.move(buttons, 255);
}

Thanks Heaps Drake250 !!

Cheers Tri.
Last edited by Tripod on Tue Aug 21, 2012 12:16 pm, edited 1 time in total.

Tripod
Posts: 9
Joined: Tue Jul 24, 2012 1:14 pm

Re: Leostick Joystick? Yes, and here's how.

Post by Tripod » Sat Aug 18, 2012 1:04 am

One other thing Drake250, I have seen standard windows HID controllers support 32 buttons plus a 8 position hat switch, which is really just another 8 buttons, so 40 in total.

Do you think that can be defined in the HID descriptor as well or is that not possible.

Cheers Tri.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest