Go Down

Topic: [SOLVED]Arcade trackball to usb mouse help (Read 11173 times) previous topic - next topic

hydrolisk1792

Oct 30, 2017, 01:52 am Last Edit: Nov 24, 2017, 04:35 am by hydrolisk1792
Hello all.

I was wondering if there is a way  to use an arduino leonardo as a way for me to get this golden  tee trackball along with about 10 buttons working as a usb gamepad in my windows environment.  How i see it is if someone here can help me with this then i can do the rest as long as it all works as a usb gamepad in windows.  Like somehow make the trackball show up in the windows joystick window as an analog joystick like you would find on a playstation controller.  In doing so the faster the trackball is moved the more acceleration there is. Any help with this? I have the Leonardo.
I make things do what they were never intended to do :P

Riva

This all sounds feasible but you need to supply links/details to the trackball your wanting to use to confirm it can be interfaced with the Leonardo.
For some mad reason the HID library used on the Leonardo does not include joystick descriptions but there are posts outlining the changes needed to the core files to add a joystick that I have used and tested. I cannot remember how many buttons it supported though but can see no reason it should not support at least 8.
Don't PM me for help as I will ignore it.

hydrolisk1792

This all sounds feasible but you need to supply links/details to the trackball your wanting to use to confirm it can be interfaced with the Leonardo.
For some mad reason the HID library used on the Leonardo does not include joystick descriptions but there are posts outlining the changes needed to the core files to add a joystick that I have used and tested. I cannot remember how many buttons it supported though but can see no reason it should not support at least 8.
link to the trackball

https://na.suzohapp.com/products/trackballs/56-5500-11

I make things do what they were never intended to do :P

Riva

I cannot see a schematic on the pinout of the 6 pin connector but (in no particular order) is probably VCC, GND, Y-A, Y-B, X-A & X-B. The trackball output is just like the output from 2x encoders so as long as the voltage matches your Arduino it should be easy to interface.

There are loads of examples of different methods of reading encoders in the link above so just pick one that gives you a suitable feel or write your own code if you prefer.

Interfacing the push buttons to the Arduino is very simple and just requires an Arduino pin connected to ground through the button like below


I cannot find the thread on here that outlines the additions you need to apply to the Leonardo core files to give joystick support but maybe someone else can or you just grab a modified copy from someone/somewhere else.
Don't PM me for help as I will ignore it.

hydrolisk1792

I cannot see a schematic on the pinout of the 6 pin connector but (in no particular order) is probably VCC, GND, Y-A, Y-B, X-A & X-B. The trackball output is just like the output from 2x encoders so as long as the voltage matches your Arduino it should be easy to interface.

There are loads of examples of different methods of reading encoders in the link above so just pick one that gives you a suitable feel or write your own code if you prefer.

Interfacing the push buttons to the Arduino is very simple and just requires an Arduino pin connected to ground through the button like below


I cannot find the thread on here that outlines the additions you need to apply to the Leonardo core files to give joystick support but maybe someone else can or you just grab a modified copy from someone/somewhere else.

The trackball uses two sets of two opts. I hooked it up to 5vdc and put a meter on one of the pins and found out that it spits out 5vdc (about) and 0 volts. It does this on both wires on both axis. So would I need to also come up with a voltage divider so I don't release the smoke from the arduino lol? Maybe to drop it down to 3.3 volts or so?  I have the Leonardo joystick library on my Leonardo but I have no idea how to modify the code that is there. It shows up in windows as a joystick. It has 32 buttons, two POV hats, rudder, throttle and two analog joysticks. All the code does though is a test when pin A5 (I think) is shorted to ground. I'm not really sure how to modify the code or make even the buttons work lol. I'm really new to this but I know a lot about hardware and electronics.
I make things do what they were never intended to do :P

Riva

If your you using a 3.3V Leonardo/ProMicro then try using 3.3V instead of 5v and see if the output still works. If your using a 5V Leonardo/ProMicro then no need of a voltage divider.
Please link to the site where you got the Joystick library from. The site should probably outline how to use the library or supply examples of its use with the library code.
The version I have has helpful info like...
Code: [Select]
// Joystick
//  Usage: Joystick.move(x, y, throttle, buttons)
//  x & y forward/left = 0, centre = 127, back/right = 255
//  throttle max = 0, min = 255
//  8 buttons packed into 1 byte
Don't PM me for help as I will ignore it.

hydrolisk1792

Link to the page.

http://www.instructables.com/id/Arduino-LeonardoMicro-as-Game-ControllerJoystick/?amp_page=true

I don't understand how to use the instructions or how to incorporate the track ball into that code.
I make things do what they were never intended to do :P

Riva

From a quick look at the link I supplied in #3 a suitable library would probably be this as it allegedly works well with 2x encoders like you have in the trackball.
Get the trackball connected and working with the example sketch supplied printing results to the serial monitor and then try incorporating the Joystick element.

I'm not convinced how well a trackball will work as a joystick but each to there own.
Don't PM me for help as I will ignore it.

hydrolisk1792

#8
Nov 02, 2017, 05:17 pm Last Edit: Nov 02, 2017, 05:23 pm by hydrolisk1792
From a quick look at the link I supplied in #3 a suitable library would probably be this as it allegedly works well with 2x encoders like you have in the trackball.
Get the trackball connected and working with the example sketch supplied printing results to the serial monitor and then try incorporating the Joystick element.

I'm not convinced how well a trackball will work as a joystick but each to there own.
Well if the encoders show up in windows as four buttons then I should be able to use a key mapper program to take those four buttons and turn them into the mouse on the PC.  I will try what you supplied when I get home, in at work right now. Oddly enough I work at a vending company and I'm in charge of the amusement machines as a tech lol. This is where I originally got the track ball from :) I get a lot of strange parts from old machines and such. I actually have another post in the displays section of this forum for a 1x16 vfd star burst display but no one has answered it yet. Would you maybe mind going over there and taking a look at it and see if you could sort it out for me?
I make things do what they were never intended to do :P

Riva

Well if the encoders show up in windows as four buttons then I should be able to use a key mapper program to take those four buttons and turn them into the mouse on the PC.
Does this mean you really want to use the trackball as a mouse and not some sort of joystick as you posted in your OP. Maybe you should explain exactly what your hoping to achieve (mouse, joystick or something else).
Converting the trackball output to a mouse should be a lot easier.

Don't PM me for help as I will ignore it.

hydrolisk1792

I need it to show up in windows as a gamepad. From there i can also have the other ten buttons. from there i can set everyrhing up with xpadder for the trackball as the mouse, three buttons for the mouse and the other seven buttons as hotkeys like media controls and such.  this is for an embeded project.
I make things do what they were never intended to do :P

hydrolisk1792

Okay I used that link you suggested and seen it in the serial monitor. So it does see the trackball. Now how would i make this code work as a gamepad with the buttons and such? My apologizes for so many questions. I'm new to this arduino programming thing. thank you for all your help so far.
I make things do what they were never intended to do :P

Riva

You will need to decide how your going to setup the trackball as a mouse but one way might be to note the time difference in readings between each encoder change to determine how fast it is being moved and then map this to a value between -127 and 127 to pass to the joystick axis.
From the joystick and encoder sketches you should be able to glean the correct calls needed to adjust the a joystick axis and do button presses but I have attached a totally untested example below that might start you in the right direction.

Code: [Select]
#include <Encoder.h>
#include <Joystick.h>

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;
 
Encoder axisX(0, 1);
Encoder axisY(2, 3);

void setup() {
  // Initialize 4 Button Pins
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin(false);
}

void loop() {
  Joystick.setXAxis(0);               // Center joystick X
  int newX = axisX.read();            // Read X encoder
  if (newX > 0)                       // Has the value increased since last read
  {
    Joystick.setXAxis(127);           // Set joystick X hard over to right
    axisX.write(0);                   // Zero encoder count for next time
 }
  if (newX < 0)                       // Has encoder decreased since last read
  {
    Joystick.setXAxis(-127);          // Set joystick hard left
    axisX.write(0);                   // Zero encoder count
  }
 
  Joystick.setYAxis(0);               // Center joystick Y
  int newY = axisY.read();
  if (newY > 0)
  {
    Joystick.setYAxis(127);
    axisY.write(0);
  }
  if (newY < 0)
  {
    Joystick.setYAxis(-127);
    axisY.write(0);
  }

  // Read button pin values
  for (byte index = 0; index < 4; index++)
  {
    byte currentButtonState = !digitalRead(index + pinToButtonMap); // Read button state
    Joystick.setButton(index, currentButtonState);                  // Set state in joystick
  }

  Joystick.sendState();               // Send the joystick data
  delay(50);                          // Wait a bit
}


Don't PM me for help as I will ignore it.

hydrolisk1792

#13
Nov 04, 2017, 02:26 am Last Edit: Nov 04, 2017, 02:36 am by hydrolisk1792 Reason: Forgot to add the screen shot of the properties window.
You will need to decide how your going to setup the trackball as a mouse but one way might be to note the time difference in readings between each encoder change to determine how fast it is being moved and then map this to a value between -127 and 127 to pass to the joystick axis.
From the joystick and encoder sketches you should be able to glean the correct calls needed to adjust the a joystick axis and do button presses but I have attached a totally untested example below that might start you in the right direction.

Code: [Select]
#include <Encoder.h>
#include <Joystick.h>

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;
  
Encoder axisX(0, 1);
Encoder axisY(2, 3);

void setup() {
  // Initialize 4 Button Pins
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin(false);
}

void loop() {
  Joystick.setXAxis(0);               // Center joystick X
  int newX = axisX.read();            // Read X encoder
  if (newX > 0)                       // Has the value increased since last read
  {
    Joystick.setXAxis(127);           // Set joystick X hard over to right
    axisX.write(0);                   // Zero encoder count for next time
 }
  if (newX < 0)                       // Has encoder decreased since last read
  {
    Joystick.setXAxis(-127);          // Set joystick hard left
    axisX.write(0);                   // Zero encoder count
  }
  
  Joystick.setYAxis(0);               // Center joystick Y
  int newY = axisY.read();
  if (newY > 0)
  {
    Joystick.setYAxis(127);
    axisY.write(0);
  }
  if (newY < 0)
  {
    Joystick.setYAxis(-127);
    axisY.write(0);
  }

  // Read button pin values
  for (byte index = 0; index < 4; index++)
  {
    byte currentButtonState = !digitalRead(index + pinToButtonMap); // Read button state
    Joystick.setButton(index, currentButtonState);                  // Set state in joystick
  }

  Joystick.sendState();               // Send the joystick data
  delay(50);                          // Wait a bit
}




Okay so I don't know if this matters or not but I have the Pro Micro, but it shows up in the Arduino IDE as a Leonardo...  I tried to add more buttons and such to the code and I'm getting some funny things happening and the track ball is hooked up to A0-A3 (I assume from the code) but it isn't doing anything...  Furthermore in windows game controller properties it shows 32 buttons, a stick, rudder, throttle, POV Hat, and x/y axis.  Is this supposed to happen?  Also some of the buttons show as pressed and I have nothing hooked up to the other pins on the Micro...  The pins are very strange on my board compared to an UNO or something else.  The pin numbers skip around, I assume that all the numbered pins are just the digital pins and the "A" pins are the analog pins?  As you will see in the code I assumed that all the digital pins could be used as buttons?   What does this part of the code mean:

"
// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;
"

I'll post the modified code:

Code: [Select]

#include <Encoder.h>
#include <Joystick.h>

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;
  
Encoder axisX(0, 1);
Encoder axisY(2, 3);

void setup() {
  // Initialize 4 Button Pins
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  
  // Initialize Joystick Library
  Joystick.begin(false);
}

void loop() {
  Joystick.setXAxis(0);               // Center joystick X
  int newX = axisX.read();            // Read X encoder
  if (newX > 0)                       // Has the value increased since last read
  {
    Joystick.setXAxis(127);           // Set joystick X hard over to right
    axisX.write(0);                   // Zero encoder count for next time
 }
  if (newX < 0)                       // Has encoder decreased since last read
  {
    Joystick.setXAxis(-127);          // Set joystick hard left
    axisX.write(0);                   // Zero encoder count
  }
  
  Joystick.setYAxis(0);               // Center joystick Y
  int newY = axisY.read();
  if (newY > 0)
  {
    Joystick.setYAxis(127);
    axisY.write(0);
  }
  if (newY < 0)
  {
    Joystick.setYAxis(-127);
    axisY.write(0);
  }

  // Read button pin values
  for (byte index = 0; index < 12; index++)
  {
    byte currentButtonState = !digitalRead(index + pinToButtonMap); // Read button state
    Joystick.setButton(index, currentButtonState);                  // Set state in joystick
  }

  Joystick.sendState();               // Send the joystick data
  delay(50);                          // Wait a bit
}


I have uploaded a picture of the Properties Window as well so you can take a look.
I make things do what they were never intended to do :P

hydrolisk1792

I also tried the first library I downloaded and tried to modify it with your example and got the same result.  Here is the code from that attempt as well.  The axis don't move when I move the trackball around and some of the buttons are stuck on.

Code: [Select]

// Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// The digital pins 9, 10, 11, and 12 are grounded when they are pressed.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Encoder.h>
#include <Joystick.h>

Encoder axisX(0, 1);
Encoder axisY(2, 3);

void setup() {
  // Initialize Button Pins
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin(true);
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;

// Last state of the button
int lastButtonState[12] = {0,0,0,0,0,0,0,0,0,0,0,0};

void loop()

  Joystick.setXAxis(0);               // Center joystick X
  int newX = axisX.read();            // Read X encoder
  if (newX > 0)                       // Has the value increased since last read
  {
    Joystick.setXAxis(255);           // Set joystick X hard over to right
    axisX.write(0);                   // Zero encoder count for next time
 }
  if (newX < 0)                       // Has encoder decreased since last read
  {
    Joystick.setXAxis(-255);          // Set joystick hard left
    axisX.write(0);                   // Zero encoder count
  }
 
  Joystick.setYAxis(0);               // Center joystick Y
  int newY = axisY.read();
  if (newY > 0)
  {
    Joystick.setYAxis(255);
    axisY.write(0);
  }
  if (newY < 0)
  {
    Joystick.setYAxis(-255);
    axisY.write(0);
  }

{

  // Read pin values
  for (int index = 0; index < 12; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(50);
}
I make things do what they were never intended to do :P

Go Up