Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: I made a Panther XL

  1. #1

    I made a Panther XL

    I made a Joystick/Trackball game controller based on the old Madcatz PantherXL they stopped making around 1998. I used a little Joystick module as a scroll stick with slow and fast vertical scrolling and slow horizontal scrolling. I had a lot of fun this is my first time coding starting with just the Trackball about a year ago

    Here is a link to a short video of
    https://m.youtube.com/watch?v=eTF1gP4PQRQ&feature=share

    And here is the code





    // ADNS2051.h reads out ADNS-2051 the Optical Navigation Sensor
    // It's used in many cheap optical mice
    //
    // Written by Martijn The -> post [at] martijnthe.nl
    // Tutorial: http://www.martijnthe.nl/optimouse/
    // Based on the sketches by Beno”t Rousseau
    //
    // Panther XL clone (old trackball joystick game controller)
    // Added a switch and if statement to switch between Trackball Only and Panther PXLR
    // Panther Purple XL Reborn
    #include "ADNS2051.h"
    #include <OptiMouse.h>
    #include <Bounce.h> // Create Bounce objects for each button. The Bounce object
    // automatically deals with contact chatter or "bounce", and
    // it makes detecting changes very simple.

    #define SCLK 0 // Serial clock pin on the Arduino
    #define SDIO 1 // Serial data (I/O) pin on the Arduino

    ADNS2051 Optical1 = ADNS2051(SCLK, SDIO); // Create an instance of the ADNS2051 object

    Bounce button2 = Bounce(2, 10); // if a button is too "sensitive" Mouse
    Bounce button3 = Bounce(3, 10); // to rapid touch, you can Left, Right,
    Bounce button4 = Bounce(4, 10); // increase this time. and Middle Click

    Bounce button7 = Bounce(7, 10); // joy trigger
    Bounce button8 = Bounce(8, 10); // joy trigger2
    Bounce button9 = Bounce(9, 10); // joy thumb
    Bounce button10 = Bounce(10, 10); // joy thumb2

    Bounce button11 = Bounce(11, 10); // hat up
    Bounce button12 = Bounce(12, 10); // hat right
    Bounce button13 = Bounce(13, 10); // hat down
    Bounce button14 = Bounce(14, 10); // hat left

    Bounce button15 = Bounce(15, 10); // Top Right Base Button
    Bounce button16 = Bounce(16, 10); // Middle Right Base Button
    Bounce button17 = Bounce(17, 10); // Bottom Right Base Button

    Bounce button20 = Bounce(20, 10); // Tracball Thumb Bottom
    Bounce button21 = Bounce(21, 10); // Tracball Thumb Top

    Bounce button22 = Bounce(22, 10); // Left Base Right
    Bounce button23 = Bounce(23, 10); // Left Base Bottom
    Bounce button24 = Bounce(24, 10); // Left Base Corner

    int scrollDelay = 15; // had to slow down scrolling and set
    // initial value to send data on first loop (first episode of The Count)

    int sH = 512; // Horizontal Scroll Stick Value
    int sV = 512; // Verticall Scroll Stick Value
    // Set initial values at center stick
    // added these variables so Scroll Stick
    // values only need to be read from pin
    // once per loop
    void setup()
    {
    Serial.begin(38400);
    Optical1.begin(); // Resync (not really necessary?)

    Optical1.writeConfig(B000101); // added command. set 800 CPI and always awake
    // (B000100), set 800 CPI and auto sleep
    // Default is 400 CPI and auto sleep

    pinMode(2, INPUT_PULLUP); // Left Mouse Click
    pinMode(3, INPUT_PULLUP); // Middle Mouse Click
    pinMode(4, INPUT_PULLUP); // Right Mouse Click

    pinMode(7, INPUT_PULLUP); // Joy button 1
    pinMode(8, INPUT_PULLUP); // Joy button 4
    pinMode(9, INPUT_PULLUP); // Joy button 2
    pinMode(10, INPUT_PULLUP); // Joy button 3

    pinMode(11, INPUT_PULLUP); // Joy Hat
    pinMode(12, INPUT_PULLUP);
    pinMode(13, INPUT_PULLUP);
    pinMode(14, INPUT_PULLUP);

    pinMode(15, INPUT_PULLUP); // Base and Trackball Thumb Buttons
    pinMode(16, INPUT_PULLUP);
    pinMode(17, INPUT_PULLUP);
    pinMode(20, INPUT_PULLUP);
    pinMode(21, INPUT_PULLUP);
    pinMode(22, INPUT_PULLUP);
    pinMode(23, INPUT_PULLUP);
    pinMode(24, INPUT_PULLUP);

    pinMode(25, INPUT_PULLUP); // Joystick.send_now ON/OFF

    Joystick.useManualSend(true);
    }

    void loop()
    {
    button2.update(); // Read all buttons except Tracball Only mode switch
    button3.update();
    button4.update();
    button7.update();
    button8.update();
    button9.update();
    button10.update();
    button11.update();
    button12.update();
    button13.update();
    button14.update();
    button15.update();
    button16.update();
    button17.update();
    button20.update();
    button21.update();
    button22.update();
    button23.update();
    button24.update();

    // Trackball Loop

    if (button2.fallingEdge()) {
    Mouse.press(MOUSE_LEFT);
    }
    if (button2.risingEdge()) {
    Mouse.release(MOUSE_LEFT);
    }
    if (button3.fallingEdge()) {
    Mouse.press(MOUSE_MIDDLE);
    }
    if (button3.risingEdge()) {
    Mouse.release(MOUSE_MIDDLE);
    }
    if (button4.fallingEdge()) {
    Mouse.press(MOUSE_RIGHT);
    }
    if (button4.risingEdge()) {
    Mouse.release(MOUSE_RIGHT);
    }

    // The status commands are available only for the PAN3101 and the ADNS2051:

    Optical1.updateStatus(); // Get the latest motion status
    // if (Optical1.motion()) // If the 'Motion' status bit is set,
    // {

    Mouse.move((-1.5)*Optical1.dx(), (-1.5)*Optical1.dy());

    // }

    // Added vertical and horizontal mouse scrolling
    // with joystick module input :-)
    sH = (analogRead(4)); // Scroll Stick Horizontal reading
    sV = (analogRead(5)); // Scroll Stick Vertical reading

    int hScroll = 0; // Y axis remapped for mouse scroll commands
    // Scrollstick Y axis is on pin A4 (Horizontal)
    int vScroll = 0; // X axis remapped for mouse scroll commands
    // Scrollstick X axis is on pin A5 (Vertical)
    // initial value and reset to no scroll once per loop
    // before checking Scroll Stick value arguements

    scrollDelay ++; // adding a simple delay in the loop to slow
    // down scrolling is not an option in the
    // case of joystick or mouse operation so
    // So I remeber Sesame Street from my childhood
    // and run an episode of The Count hahahahahahaha
    // add 1 to delay counter each loop

    if (sH < 400) {
    hScroll = 1;
    }

    if (sH > 700) {
    hScroll = -1;
    }

    if (sV < 502) {
    vScroll = 1;
    }
    if (sV > 522) {
    vScroll = -1;
    }

    if (sV > 990) { // 2 speed scrolling on vertical
    scrollDelay = (scrollDelay + 7); // adjust scroll fast here
    }
    if (sV < 22) {
    scrollDelay = (scrollDelay + 7); // and here
    }

    if (scrollDelay > 15) { // adjust scroll speed here. larger number = slower
    scrollDelay = 0;
    Mouse.scroll(vScroll, hScroll);
    }
    // Joystick Loop

    if (button7.fallingEdge()) {
    Joystick.button(1, 1); // Trigger
    }
    if (button8.fallingEdge()) {
    Joystick.button(4, 1); // TopBtn
    }
    if (button9.fallingEdge()) {
    Joystick.button(2, 1); // ThumbBtn
    }
    if (button10.fallingEdge()) {
    Joystick.button(3, 1); // ThumbBtn2
    }
    if (button15.fallingEdge()) {
    Joystick.button(10, 1); // BaseBtn4
    }
    if (button16.fallingEdge()) {
    Joystick.button(11, 1); // BaseBtn5
    }
    if (button17.fallingEdge()) {
    Joystick.button(12, 1); // BaseBtn6
    }
    if (button20.fallingEdge()) {
    Joystick.button(6, 1); // PinkieBtn (Trackball Thumb Bottom)
    }
    if (button21.fallingEdge()) {
    Joystick.button(5, 1); // TopBtn2 (Trackball Thumb Top)
    }
    if (button22.fallingEdge()) {
    Joystick.button(9, 1); // BaseBtn3
    }
    if (button23.fallingEdge()) {
    Joystick.button(7, 1); // BaseBtn1
    }
    if (button24.fallingEdge()) {
    Joystick.button(8, 1); // BaseBtn2
    }

    if (button7.risingEdge()) {
    Joystick.button(1, 0);
    }
    if (button8.risingEdge()) {
    Joystick.button(4, 0);
    }
    if (button9.risingEdge()) {
    Joystick.button(2, 0);
    }
    if (button10.risingEdge()) {
    Joystick.button(3, 0);
    }
    if (button15.risingEdge()) {
    Joystick.button(10, 0);
    }
    if (button16.risingEdge()) {
    Joystick.button(11, 0);
    }
    if (button17.risingEdge()) {
    Joystick.button(12, 0);
    }
    if (button20.risingEdge()) {
    Joystick.button(6, 0);
    }
    if (button21.risingEdge()) {
    Joystick.button(5, 0);
    }
    if (button22.risingEdge()) {
    Joystick.button(9, 0);
    }
    if (button23.risingEdge()) {
    Joystick.button(7, 0);
    }
    if (button24.risingEdge()) {
    Joystick.button(8, 0);
    }

    if (button11.fallingEdge()) {
    Joystick.hat(0);
    }
    if (button11.risingEdge()) {
    Joystick.hat(-1);
    }
    if (button12.fallingEdge()) {
    Joystick.hat(90);
    }
    if (button12.risingEdge()) {
    Joystick.hat(-1);
    }
    if (button13.fallingEdge()) {
    Joystick.hat(180);
    }
    if (button13.risingEdge()) {
    Joystick.hat(-1);
    }
    if (button14.fallingEdge()) {
    Joystick.hat(270);
    }
    if (button14.risingEdge()) {
    Joystick.hat(-1);
    }



    if ((digitalRead(25)) == LOW) { // Added Trackball only mode.
    Joystick.X(analogRead(0)); // Joystick output having nowhere to go can cause interruptions
    Joystick.Y(analogRead(1)); // in the loop/janky trackball operation
    Joystick.Z(analogRead(2)); // pin 25 high is trackball only mode....if pin low
    Joystick.sliderLeft(analogRead(3)); // read Joystick axis and send Joystick data
    Joystick.send_now();

    }

    delay(5); // So this loop ONLY runs 200 times per second?
    }
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	IMG_20181103_195301261.jpg 
Views:	10 
Size:	129.3 KB 
ID:	15126  

  2. #2
    I do have a question about the delay at the end of the loop. I included it because it is in the complete Joystick example sketch.....while 200 time per second seems fast enough to me, is there an industry standard to how often a Joystick or mouse sends data?. What are the pros and cons of removing that delay?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •