Skip to content

Mouse.move positioning #1417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Davonic opened this issue May 16, 2013 · 15 comments
Closed

Mouse.move positioning #1417

Davonic opened this issue May 16, 2013 · 15 comments
Assignees
Labels
Component: Core Related to the code for the standard Arduino API
Milestone

Comments

@Davonic
Copy link

Davonic commented May 16, 2013

I know the reason for the problem I'm having with multiple move Mouse.move positioning being imprecise is due to Mouse Acceleration and/or Precise Pointer in Windows but my question is whether anyone has found a way to deal with this issue and get precise positioning. I don't consider this an Arduino hardware/software fault although it's possible a workaround could be added to it or even, unknown to me, already exist.

Example (test code section c/w commented actual results)
// 60 40 mouse initial position by movement of physical mouse
Mouse.move(100,100,0); // 160 140 for first movement which is correct
delay(10000);
Mouse.move(100,100,0) ; // 420 401 for second movement which is 260 & 261 (over 2 1/2 times)

Subsequent repeats of the command (w delay) continue to get over 2 1/2 times the desired movement. I've tried inserting other mouse commands including a Mouse.move(-1,-1,0) but none stop the acceleration.

I'm aware that I can adjust Mouse Acceleration & Precise Pointer to reduce the issue but then my regular mouse usage is less convenient.

My thought is that since the Leonardo mouse is a separate device from my regular mouse is that there might be a way, that someone is aware of, to remove Mouse Acceleration from it while leaving it in place for the hardware mouse. Possibly a Registry setting (that applies to Leo not hardware mouse) or some Arduino code that can be inserted before Mouse.move commands to trick Windows into thinking each move is the first (accurate one).

For Arduino hardware/software workarounds, an ability to set the speed that the mouse moves within each Mouse.move should reduce the problem significantly since the current near instant move from position to position is likely a major factor.

My temporary (reasonably successful) workaround is to assume a 2.6x acceleration on all but the first call and adjust the Mouse.move parameters to suit. Note to others who try this that the 2.6 value is for my PC & Windows settings and will probably be a different, though still consistant, value on yours.

Thanks in advance for any insights!

@Davonic
Copy link
Author

Davonic commented May 16, 2013

FYI: My temporary workaround has a major flaw. It's 2.6x for the 100 distance mouse movement but it varies for other distances. I just tried a 10 distance and the factor was 1.3x. This extremely limits the usefulness of the workaround unless a formula can be worked out for mathematically determining the factor based on the distance. I'll wait for a better solution but if none is forthcoming I'll work on the formula.

@lestofante
Copy link

Mouseacceleration and mouse speed is your problem. It is a formula used
from pc side, so you have to work around. Probably this formula is linear,
just take 2 point and use the linear formula y=mx+q where x is your value
and y the final value.
Another work arondo is to send many times a movement of 1, that way
acceleration should not kick in.
Btw moving a mouse that way is unreilable, different screen resolution/os
will respond in different way.
Il giorno 16/mag/2013 05:07, "Davonic" [email protected] ha
scritto:

FYI: My temporary workaround has a major flaw. It's 2.6x for the 100
distance mouse movement but it varies for other distances. I just tried a
10 distance and the factor was 1.3x. This extremely limits the usefulness
of the workaround unless a formula can be worked out for mathematically
determining the factor based on the distance. I'll wait for a better
solution but if none is forthcoming I'll work on the formula.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1417#issuecomment-17978505
.

@Davonic
Copy link
Author

Davonic commented Jun 3, 2013

Thanks Iestofante

I realized it was my problem, I just thought that I might've been unaware of some existing solution in the Arduino itself or in someone else's coding or that someone might know some way to have acceleration turned off for the Arduino mouse while leaving it on for the physical one.

For your first suggestion I've already found the acceleration isn't linear (which would be a velocity) but changes exponentially with the distance moved (along the lines of y=mx*q where q varies from about 1 to 3 with distances in the 1 to 255 range of the Arduino) and is strangely unreliable. I've written a quick code snippet that I'll insert in my program to try your second suggestion but don't have the time for inserting or testing it right now. I'll report back with the results when I do try it.

@nospam2000
Copy link

The Arduino Mouse emulation uses relative positioning. In theory you could change it to use absolute positioning by adding a new HID descriptor (+some code) in HID.cpp so the mouse emulation would work like a touchscreen. Would this help you?

@Davonic
Copy link
Author

Davonic commented Jul 21, 2013

Hi nospam2000.

Actually, Absolute positioning is what I was trying to do except that the Arduino Mouse emulation only had relative positioning available. My workaround was to Move the mouse to the Desktop 0,0 position then use the Arduino Mouse to move it "relatively" to the absolute position I needed. That's when I ran into the acceleration issues.

What you suggest would, therefore, be the perfect solution!

I'm not overly familiar with modifying cpp files properly so I searched for others who might've modified it. I found some but it appears they couldn't get the mouse to go further than about 100 pixels from the top-left corner of the screen.

Can you direct me to a successful HID.cpp modification that allows absolute positioning anywhere on the screen (in my case 1920 x 1080)?

nospam2000 added a commit to nospam2000/Arduino that referenced this issue Jul 21, 2013
… as requested in issue arduino#1417.

all parameters have the range of -32768 to 32767 and must be scaled to screen pixels
some examples:
  x=0, y=0 is the middle of the screen
  x=-32768, y=-32768 is the top left corner
  x=32767, y=-32768 is the top right corner
  x=32767, y=32767 is the bottom right corner
  x=-32768, y=32767 is the bottom left corner
@nospam2000
Copy link

In the patch from my previous posting you can see the changes which need to be done for an absolute mouse. It basically works, but some work has to be done for transforming the logical mouse coordinates (-32768 to 32767) to screen pixel coordinates (0..1920x0..1080).
There are dead borders around the logical area so a simple 'rule of proportion' doesn't give the expected result. I'm still working on this.

@Davonic
Copy link
Author

Davonic commented Jul 22, 2013

It worked perfectly. Much Appreciated Michael.

I thought the following observations were worth passing along:

  1. For anyone using Arduino 1.0.5 the changes are the same to the .h file and almost the same for the cpp file except that you can insert the HID_REPORTID_MOUSE_ABS (5) after four #define RAWHID ... lines rather than the four #define HID_REPORTID... lines (which don't exist in the new HDD.cpp).

  2. If you have multiple monitors the 0,0 position may not be the centre of your monitors (mine was actually the 0,0 of the main monitor (ie. the upper left corner) and the 32767 values reach one monitor's width or height from that point in all 4 directions. This means that any monitor further than that from 0,0 is not accessible. (Note: this was not an issue for my purposes since everything will occur within that range not on the monitors beyond).

  3. When calculating a pixel position it appears that it always rounds down. For example, if you wish to hit pixel position 165 on the X axis you need to find the 32767/ScreenWidth value that is between 165.000 & 165.999. (Note: I'll be implementing it that way although I don't really require that level of accuracy).

@nospam2000
Copy link

The "dead borders" I mentioned are an issue of the default Mac OSX mouse driver. There is always a border of 15% of the screen width and height around the visible area. More information can be found here:

  • [http://lists.apple.com/archives/usb/2010/Aug/msg00033.html]
  • [http://lists.apple.com/archives/usb/2011/Jun/msg00032.html]

The multi-monitor scenario you mentioned is a problem of the default Windows mouse driver. To position the mouse to any other than the first monitor, the flag MOUSE_VIRTUAL_DESKTOP must be set in the mouse driver. To do this, you need a filter driver. See the following links for more information:

  • [http://msdn.microsoft.com/en-us/library/windows/hardware/jj128267%28v=vs.85%29.aspx]
  • [http://www.techtalkz.com/microsoft-device-drivers/475035-can-usb-hid-device-get-mouhid-set-mouse_virtual_desktop.html]

You can see neither Mac OSX nor Windows are perfect :-)

@alexemme
Copy link

alexemme commented Sep 1, 2013

hello , i'm new to this site , and especially to arduino .
I have the same problem with the move function and i tried the new HID.cpp and USBAPI.h posted by nospam2000,
it doesn't work and i don't know why , all seems to be done and correct when i upload the code to the arduino, but mouse doesn't move ....
i'm using arduino 1.05.

can anyone help me ?

@alexemme
Copy link

alexemme commented Sep 2, 2013

i tried the 1.01 IDE and it works fine ... thanks for the code , i really appreciated.

@alexemme
Copy link

alexemme commented Sep 4, 2013

it's really strange , i've done some test sketches and the function worked well ,
then i wrote the final code and when i uploaded it to the board i realized it's not working anymore...

i don't know what happened , what it could be... the basic Mouse.move function is still working well , moveAbs it's not working ....with 1.01 which before worked well...maybe could be a windows 8 problem !??!?!?

:(

i'm using the 1.01 ide with 1.05 usb drivers

@alexemme
Copy link

alexemme commented Sep 4, 2013

here's the test code ,

void setup() {
// take control of the mouse:
Mouse.begin();
while (!Serial); // while not open, do nothing
Serial.begin(9600);
}

void loop() {
while (Serial.available() > 0) { // if at least one char is available
/* CODE */
char a = Serial.read();
if (a=='a'){
Mouse.moveAbs(110,110,0);
}
}
}

@lestofante
Copy link

This is a bigtracer, not a place to request help. Use the forum Arduino.cc
instead
Il giorno 04/set/2013 22:26, "alexemme" [email protected] ha
scritto:

here's the test code ,

void setup() {
// take control of the mouse:
Mouse.begin();
while (!Serial); // while not open, do nothing
Serial.begin(9600);
}

void loop() {
while (Serial.available() > 0) { // if at least one char is available
/* CODE */
char a = Serial.read();
if (a=='a'){
Mouse.moveAbs(110,110,0);
}

}
}


Reply to this email directly or view it on GitHubhttps://github.com//issues/1417#issuecomment-23821124
.

@facchinm
Copy link
Member

Closing with #1803

@ffissore ffissore modified the milestone: Release 1.6.6 Sep 23, 2015
@laith7ussein
Copy link

Hi, I'm working on a Robot project with Arduino and I'm using a mouse as a positioning system to get x and y, the Arduino reads dx and dy not x and y so I add these values in a new variable after each reading. The problem is when the robot moves faster dy or dx become larger, I mean the relative value is obviously depending on the speed of movement.

Is there any way to read dx and dy without speed effect?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Core Related to the code for the standard Arduino API
Projects
None yet
Development

No branches or pull requests

8 participants