tommyvhb

Space Mouse sketch

Dec 15th, 2020
849
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Author Stefano Sbarra
  2. //April 2020
  3. //FREE FOR ANY NON COMMERCIAL PROJECT
  4.  
  5. /*
  6.  * Modified by Tommy Vanhullebusch
  7.  * December 2020
  8.  *
  9. */
  10.  
  11. //THIS SKETCH MAKES ARDUINO LEONARDO (OR MICRO) WORK AS A SPACE 3D MOUSE FOR INVENTOR AND FUSION 360
  12. //NORMAL JOYSTICK MOVE ACT AS VIEW ROTATION USING F4 KEY
  13. //PRESS AND MOVE ACT AS VIEW ZOOM USING F3 KEY
  14. //QUICK PRESS OF THE JOYSTICK GOES TO HOME VIEW USING F6
  15. //ADDITIONAL FUNCTIONS AND SWITCHES ARE EASY TO IMPLEMENT (EXAMPLE SLICE VIEW)
  16.  
  17. /*
  18.  *
  19.  *  Actions optimised for use with Fusion 360
  20.  *  
  21.  *  Joystick move: Orbit (Shift-Middle Mouse button-Mouse Movement
  22.  *  Joystick move while pressed: Pan (Middel Mouse button-Mouse Movement
  23.  *  Joystick click: Zoom all (F6)
  24.  *  Joystick double-click: not implemented
  25.  *  Button 1: Zoom in (Mouse Scroll down)
  26.  *  Button 2: Zoom out (Mouse Scroll up)
  27.  *  Button 3: New sketch (ctrl-alt-s made a new shortcut for this)
  28.  *  The mouse can be turned ON or OFF by pressing button 3 for 2 seconds
  29.  *  
  30. */
  31.  
  32. #include <Mouse.h>
  33. #include <Keyboard.h>
  34.  
  35. int horzPin = A1;                  // Analog output of horizontal joystick pin
  36. int vertPin = A0;                  // Analog output of vertical joystick pin
  37. int selPin = 10;                   // select button pin of joystick
  38. int b1Pin = 7;                     // button 1
  39. int b2Pin = 8;                     // button 2
  40. int b3Pin = 9;                     // button 3
  41.  
  42. char f6key = KEY_F6;               // zoom to all
  43. char shiftkey = KEY_LEFT_SHIFT;    // Needed for orbit
  44. char ctrlkey = KEY_LEFT_CTRL;      // Needed for custom shortcut
  45. char altkey = KEY_LEFT_ALT;        // Needed for custom shortcut
  46.  
  47. int moved = 0;                     // checks if the joystick has moved
  48. int clicked = 0;                   // is mouse button clicked or not
  49. int pressed = 0;                   // checks if the joystick has been pressed
  50. int mouseOn = 0;                   // flag to signal that the mouse is on or off
  51.  
  52. unsigned long previousMillis = 0;  // Used for slowing down the zoom buttons
  53. const long zoomDelay = 70;         // Delay between two zoom actions
  54.  
  55. int vertZero, horzZero;            // Stores the initial value of each axis, usually around 512
  56. int vertValue, horzValue;          // Stores current analog output of each axis
  57. const int sensitivity = 200;       // Higher sensitivity value = slower mouse, should be <= about 500
  58. int mouseClickFlag = 0;            // another click check
  59. int b1flag = 0;                    // click check
  60. int b2flag = 0;                    // click check
  61. int b3flag = 0;                    // click check
  62.  
  63. //int invertMouse = 1;             // Invert joystick based on orientation
  64. int invertMouse = -1;              // Noninverted joystick based on orientation
  65.  
  66. unsigned long releasetime = 0;     // used to register the releasing time (to select "zoom all" or orbit/pan)
  67. unsigned long presstime = 0;       // as above
  68. unsigned long btn3released = 0;    // used to register the releasing time of button 3
  69. unsigned long btn3pressed = 0;     // as above
  70. unsigned long diff = 0;            // difference between time checks to read quick or long press
  71. unsigned long nextMove = 0;        // time to next move
  72. const long mouseDelay = 10;        // delay to slow down the mouse movements
  73. const long interval = 500;         // interval to establish if quick or long
  74.  
  75. void setup()
  76. {
  77.  
  78.   pinMode(horzPin, INPUT);         // Set both analog pins as inputs
  79.   pinMode(vertPin, INPUT);
  80.   pinMode(selPin, INPUT);          // set button select pin as input
  81.   pinMode(b1Pin, INPUT);           // set button 1 pin as input
  82.   pinMode(b2Pin, INPUT);           // set button 2 pin as input
  83.   pinMode(b3Pin, INPUT);           // set button 3 pin as input
  84.   digitalWrite(selPin, HIGH);      // Pull button select pin high
  85.   digitalWrite(b1Pin, HIGH);       // Pull button 1 pin high
  86.   digitalWrite(b2Pin, HIGH);       // Pull button 2 pin high
  87.   digitalWrite(b3Pin, HIGH);       // Pull button 3 pin high
  88.   delay(1000);                     // short delay to let outputs settle
  89.   vertZero = analogRead(vertPin);  // get the initial values
  90.   horzZero = analogRead(horzPin);  // Joystick should be in neutral position when reading these
  91.  
  92.   Mouse.begin();      // Init mouse emulation
  93.   Keyboard.begin();   // Init keyboard emulation
  94.  
  95. }
  96.  
  97. void loop()
  98. {
  99.  
  100.   unsigned long currentMillis = millis();
  101.  
  102.   vertValue = (analogRead(vertPin) - vertZero) * invertMouse;  // read vertical offset
  103.   horzValue = (analogRead(horzPin) - horzZero) * invertMouse;  // read horizontal offset
  104.  
  105.  
  106. //BUTTON 1
  107.  
  108.     if ((mouseOn == 1) && (digitalRead(b1Pin) == LOW) && (currentMillis > (previousMillis + zoomDelay)))  // if button 1 is pressed
  109.   {
  110.     Mouse.move (0, 0, -1);
  111.     previousMillis = currentMillis;
  112.   }
  113.  
  114.  
  115. //BUTTON 2
  116.  
  117.     if ((mouseOn == 1) && (digitalRead(b2Pin) == LOW) && (currentMillis > (previousMillis + zoomDelay)))  // if button 2 is pressed
  118.   {
  119.     Mouse.move (0, 0, 1);
  120.     previousMillis = currentMillis;
  121.   }
  122.  
  123.  
  124. //BUTTON 3
  125.  
  126.     if ((digitalRead(b3Pin) == LOW) && (!b3flag))  // if button 3 is pressed
  127.   {
  128.     b3flag = 1;
  129.     btn3pressed = currentMillis;
  130.   }
  131.  
  132.   if ((digitalRead(b3Pin) == HIGH) && (b3flag))
  133.   {
  134.     b3flag = 0;
  135.     btn3released = currentMillis;
  136.     diff = btn3released - btn3pressed;
  137.     if (diff > 1000) {
  138.       // Long press to turn the Space mouse ON or OFF
  139.       if (mouseOn == 1) {
  140.         mouseOn = 0;
  141.       }
  142.       else {
  143.         mouseOn = 1;
  144.       }
  145.     }
  146.     else if (mouseOn == 1) {
  147.       Keyboard.press(ctrlkey);
  148.       Keyboard.press(altkey);
  149.       Keyboard.press('s');
  150.       delay(50);
  151.       Keyboard.releaseAll();
  152.     }
  153.     delay(10);
  154.   }
  155.  
  156.  
  157. //JOYSTICK CLICK
  158.  
  159.   if ((digitalRead(selPin) == LOW) && (!mouseClickFlag))  // if the joystick button is pressed
  160.   {
  161.     presstime = currentMillis;
  162.     mouseClickFlag = 1;
  163.     pressed = 1;
  164.   }
  165.  
  166.   if ((digitalRead(selPin) == HIGH) && (mouseClickFlag))  // if the joystick button is not pressed
  167.   {
  168.     releasetime = currentMillis;
  169.     mouseClickFlag = 0;
  170.     pressed = 0;
  171.  
  172.     diff = (releasetime - presstime);  // check if the click was quick or long
  173.  
  174.     if ((mouseOn == 1) && (diff < interval) && (diff > 20)) // if quick call zoom all (F6)
  175.     {
  176.       Keyboard.write(f6key);
  177.     }
  178.   }
  179.  
  180.     if (currentMillis > nextMove) {
  181.       if (((vertValue > 2)||(vertValue < (-2))) && (currentMillis > nextMove)){  // position two instead of 0 cancel the small fluctuation between readings
  182.         moved = 1;
  183.       }
  184.       else {
  185.         vertValue = 0;
  186.       }
  187.    
  188.       if (((horzValue > 2)||(horzValue < (-2))) && (currentMillis > nextMove)){  
  189.         moved = 1;
  190.       }
  191.       else {
  192.         horzValue = 0;
  193.       }
  194.  
  195.       if ((mouseOn == 1) && (clicked == 1) && (vertValue <= 2) && (vertValue >= (-2))  &&  (horzValue <= 2) && (horzValue >= (-2)) ){ // if joystick is in neutral position release all
  196.         clicked = 0;
  197.         Keyboard.releaseAll();
  198.         Mouse.release(MOUSE_MIDDLE);
  199.       }
  200.  
  201.     }
  202.    
  203.     if (moved == 1) { // move mouse with middle mousebutton pressed to orbit/pan view
  204.       moved = 0;
  205.       nextMove = currentMillis + mouseDelay;
  206.       if (mouseOn == 1) {
  207.         if (clicked == 0) {
  208.           clicked = 1;
  209.           if (pressed == 0) { // press shift key to orbit else release it to pan
  210.             Keyboard.press(shiftkey);
  211.             delay(5);
  212.           }
  213.           Mouse.press(MOUSE_MIDDLE);
  214.           delay(5);
  215.         }
  216.         Mouse.move((horzValue / sensitivity), (vertValue / sensitivity), 0);
  217.       }
  218.     }
  219.  
  220.  
  221. }
RAW Paste Data