Pages: [1]   Go Down
Author Topic: Strange Mouse/Joystick Behavior  (Read 13630 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I picked up my Esplora about a week ago from my local Radio Shack. Everything seems physically okay with the board. And I am able to upload to it just fine. However whenever I try to use it as a mouse it starts acting up. It always drifts the cursor to the top area of the screen. I was using an unmodified version of the example code Arduino provides at first. But I managed to have a bit more luck with some code that I found online. (Attached) But after a few minutes it started acting up again. Any thoughts as to why this may be? I am using a Mac running Mavericks. I have also tried a different computer and cables.
Code:
/*
  Esplora Calibrated Joystick Mouse
 
 WARNING: this sketch will take over your mouse movement. If you lose control
 of your mouse do the following:
 1) unplug the Esplora.
 2) open the EsploraBlink sketch
 3) hold the reset button down while plugging your Esplora back in
 4) while holding reset, click "Upload"
 5) when you see the message "Done compiling", release the reset button.
 
 This will stop your Esplora from controlling your mouse while you upload a sketch
 that doesn't take control of the mouse.
 
 Made by Michael on 16 May 2013
 */
#include <Esplora.h>
int JoyX;                                        // These Variables are global
int JoyY;
int activate = 0;
void setup()
{
  Esplora.writeRGB(0, 0, 10);                   // Signal Esplora is waiting to calibrate
  int start = Esplora.readButton(SWITCH_3);      // Read First Button
  while(start == HIGH) {                         // Wait until button is pressed
    start = Esplora.readButton(SWITCH_3);
  }
  JoyX = Esplora.readJoystickX();                // Set drift variable X
  JoyY = Esplora.readJoystickY();                // Set drift variable Y
  Esplora.writeRGB(10, 0, 0);                   // Calibration is done, waiting to run
}
void loop()
{
  int xValue = Esplora.readJoystickX();          // read the joystick's X position
  int yValue = Esplora.readJoystickY();          // read the joystick's Y position
  xValue = xValue - JoyX;                        // Remove drift on X position
  yValue = yValue - JoyY;                        // Remove drift on Y position
  int JoyButton = Esplora.readJoystickButton();
  int button1 = Esplora.readButton(SWITCH_1);    // Read Buttons
  int button2 = Esplora.readButton(SWITCH_2);    // Read Buttons
  int button3 = Esplora.readButton(SWITCH_3);    // Read Buttons
  int button4 = Esplora.readButton(SWITCH_4);    // Read Buttons
  int slide = Esplora.readSlider();              // Read Slider Values
  int mousespeed = map(slide, 0, 1023, 10, 0);                  // Max Mouse Speed is Calculated from slider
  int mouseX = map( xValue,-512, 512, mousespeed, -mousespeed);  // map the X value to a range of movement for the mouse X, Changes input range to include new values
  int mouseY = map( yValue,-512, 512, -mousespeed, mousespeed);  // map the Y value to a range of movement for the mouse Y, Changes input range to include new values
  if(button3 == LOW){                          // Check if the Enable/Disable button is pressed
    if(activate == 1) activate = 0;
    else activate = 1;
    delay(500);
  }
  if(activate == 1){                               // Check if mouse is enabled
    Esplora.writeRGB(0 , 10, 0 );                 // Set light to green
    Mouse.begin();                                 // take control of the mouse
    if(JoyButton == LOW || button2 == LOW) Mouse.press(MOUSE_LEFT);       // Test if Left click is activated
    else Mouse.release(MOUSE_LEFT);
    if(button1 == LOW) Mouse.press(MOUSE_MIDDLE);                             // Middle Button   
    else Mouse.release(MOUSE_MIDDLE);
    if(button4 == LOW)  Mouse.press(MOUSE_RIGHT);      // Right Button
    else Mouse.release(MOUSE_RIGHT);
    Mouse.move(mouseX, mouseY, 0);                 // move the mouse
  }
  else {
    Mouse.end();
    Esplora.writeRGB(255, 0, 0 );
  }
 
  delay(10);                                  // a short delay before moving again
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I also recently picked up an Esplora. I tried uploading that code you found online to my Esplora. It's a highly modified version of the Esplora Joystick Mouse code. When I pressed switch 3 I was able to move my joystick/mouse but at a very slow pace. Moving the linear pot will adjust the mouse speed. Other switches including joystick switch would be a mouse click. There wasn't any drift in that new code. But I digress.

I was also looking into why my Esplora would drift to the top right corner of my screen and was able to find a different solution. Here's my code.

Code:
/*
 Esplora Joystick Mouse
 
 This  sketch shows you how to read the joystick and use it to control the movement
 of the cursor on your computer.  You're making your Esplora into a mouse!
 
 WARNING: this sketch will take over your mouse movement. If you lose control
 of your mouse do the following:
 1) unplug the Esplora.
 2) open the EsploraBlink sketch
 3) hold the reset button down while plugging your Esplora back in
 4) while holding reset, click "Upload"
 5) when you see the message "Done compiling", release the reset button.
 
 This will stop your Esplora from controlling your mouse while you upload a sketch
 that doesn't take control of the mouse.
 
 Created on 22 Dec 2012
 by Tom Igoe
 
 This example is in the public domain.
 */

#include <Esplora.h>

int xDrift = map(Esplora.readJoystickX(), -512, 512, 10, -10);
int yDrift = map(Esplora.readJoystickY(), -512, 512, -10, 10);

void setup()
{
  Serial.begin(9600);       // initialize serial communication with your computer
  Mouse.begin();            // take control of the mouse
}

void loop()
{
  int xValue = Esplora.readJoystickX();        // read the joystick's X position
  int yValue = Esplora.readJoystickY();        // read the joystick's Y position
  int button = Esplora.readJoystickSwitch();   // read the joystick pushbutton
  Serial.print("\nJoystick X: ");                // print a label for the X value
  Serial.print(xValue);                        // print the X value
  Serial.print("\tY: ");                       // print a tab character and a label for the Y value
  Serial.print(yValue);                        // print the Y value
  Serial.print("\tButton: ");                  // print a tab character and a label for the button
  Serial.print(button);                        // print the button value
  Serial.print("\txDrift: ");
  Serial.print(xDrift);
  Serial.print("\tyDrift: ");
  Serial.print(yDrift);
  int mouseX = map( xValue,-512, 512, 10, -10);  // map the X value to a range of movement for the mouse X
  int mouseY = map( yValue,-512, 512, -10, 10);  // map the Y value to a range of movement for the mouse Y
  Serial.print("\tmouseX: ");
  Serial.print(mouseX);
  Serial.print("\tmouseY: ");
  Serial.print(mouseY);
  Mouse.move(mouseX-xDrift/10, mouseY-yDrift/10, 0);                 // move the mouse
 
  delay(10);                                  // a short delay before moving again
}

Trying uploading my code and CTRL + SHIFT + M to bring up serial monitor. It would make my explanation a lot easier to digest.

The reason for the drift is that the joysticks is not mechanically calibrated. Ideally the X and Y readings from the joystick should be 0 and 0 when they're not moved. Howver, without even moving the joystick my readings for X is at -8 and Joystick Y is at -9. This is the unmapped reading from the joystick that ranges from -512 to 512. After using the map() function, the x and y readings gets scaled from (-512, 512) to (-10,10). However, the output of the map() function doesn't allow fractions so it gets rounded off to the nearest integer. In my case mouseX = 1 and mouseY = -1 which causes my mouse to slowly move to the top right corner of my screen.

To solve this problem, I introduced xDrift and yDrift to calibrate the mouse. My code would take the X and Y readings from the joystick in their resting position then map (or scale) those readings to a range from (-512, 512) to (-10, 10) only once when the esplora is turned on. During the Mouse.move() function I would subtract the X and Y drift from the X and Y movement so that it would be calibrated.

Although I've gotten this far, there's still something that I can't seem to understand. My xDrift and yDrift value seems to be 10 and -10 after being going through the map() function. Because of this, I divided it by 10 when I'm subtracting it from mouseX and mouseY assuming that its scaled to a factor of 10. However, this is not the real solution to the problem as I could've just subtract 1 and -1 from mouseX and mouseY and still get the same non-drifting result. If anybody could figure this out please let me know. If I can figure it out I'll follow up on this post.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It seems that defining x and yDrift outside the loop sets it to its maximum values of 512 and -512 or 10 and -10 after going through map() function. However, putting it inside the loop will set the correct drift value. The code I put in earlier will not work for everyone. It will only work on my Esplora.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's is the correct code that should work for everybody's Esplora. There's probably some funky things going on in the Esplora.h library that makes the joystick readings to be at their max value when called outside the loop. To get around this, I have a do while loop inside the main loop. The test condition is if only x and y drift does not equal to 0. The do while loop will always work once while inside the main loop so even for those with perfectly mechanically calibrated esploras will find this code also working for them.

Code:
/*
  Esplora Joystick Mouse
 
 This  sketch shows you how to read the joystick and use it to control the movement
 of the cursor on your computer.  You're making your Esplora into a mouse!
 
 WARNING: this sketch will take over your mouse movement. If you lose control
 of your mouse do the following:
 1) unplug the Esplora.
 2) open the EsploraBlink sketch
 3) hold the reset button down while plugging your Esplora back in
 4) while holding reset, click "Upload"
 5) when you see the message "Done compiling", release the reset button.
 
 This will stop your Esplora from controlling your mouse while you upload a sketch
 that doesn't take control of the mouse.
 
 Created on 22 Dec 2012
 by Tom Igoe
 
 This example is in the public domain.
 */

#include <Esplora.h>

void setup()
{
  Serial.begin(9600);       // initialize serial communication with your computer
  Mouse.begin();            // take control of the mouse
  delay(100);
}

void loop()
{
  int xDrift = map(Esplora.readJoystickX(), -512, 512, 10, -10);  // finds the drift value for x and maps it
  int yDrift = map(Esplora.readJoystickY(), -512, 512, -10, 10);  // finds the drift value for y and maps it
  do
  {
    int xValue = Esplora.readJoystickX();        // read the joystick's X position
    int yValue = Esplora.readJoystickY();        // read the joystick's Y position
    int button = Esplora.readJoystickSwitch();   // read the joystick pushbutton
    Serial.print("\nJoystick X: ");                // print a label for the X value
    Serial.print(xValue);                        // print the X value
    Serial.print("\tY: ");                       // print a tab character and a label for the Y value
    Serial.print(yValue);                        // print the Y value
    Serial.print("\tButton: ");                  // print a tab character and a label for the button
    Serial.print(button);                        // print the button value
    Serial.print("\txDrift: ");
    Serial.print(xDrift);
    Serial.print("\tyDrift: ");
    Serial.print(yDrift);
    int mouseX = map( xValue,-512, 512, 10, -10);  // map the X value to a range of movement for the mouse X
    int mouseY = map( yValue,-512, 512, -10, 10);  // map the Y value to a range of movement for the mouse Y
    Mouse.move(mouseX-xDrift, mouseY-yDrift, 0);   // move the mouse
    delay(10);       // a short delay before moving again
  } while(xDrift != 0 || yDrift != 0); // checks for drift
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using your code now Bedhead, But how do you get mouse clicks?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello RadThread
This is the complete code
Enjoy!  smiley-cool

* EsploraJoystickMouseReload.ino (2.66 KB - downloaded 25 times.)
Logged

Pages: [1]   Go Up
Jump to: