Get optical mouse readings even when mouse is not moving

Hello,

I'm trying to use an optical mouse connected to an Arduino Due (USB) to get the movements of a trackball. I'm using MouseController to get the readings directly from the mouse rather than the movement of the cursor, and so far I can get xy velocity readings when there is optic flow, and I can get a not very precise framerate with delay(), but I need the following: if there is optic flow, return the corresponding velocity values, if there isn't, return zero, at very precise framerates. Could someone help me crack this, basically getting continuous readings from the mouse regardless of optic flow being different than zero?

Thank you in advance!

The mouse is only going to send data when it is moving. I believe the data rate will give you the velocity but delay() is bad, it blocks the program flow.

Thank you for your reply. Is there any way of changing that, perhaps in the MouseController files? Or maybe an if in the IDE for printing in the Serial monitor zeros if no movement, or the actual xy values if there's movement, every x ms?

Ok, so this prints the x,y velocities of the mouse when moving, and 0,0 when not moving:

// Initialize USB Controller
USBHost usb;

// Attach mouse controller to USB
MouseController mouse(usb);

// Initialize variables
int deltaX, deltaY;

// Cancel variables for mouse button press
boolean leftButton = false;
boolean middleButton = false;
boolean rightButton = false;

void setup() {
Serial.begin(9600);
}

void loop() {
usb.Task();
deltaX = mouse.getXChange();
deltaY = mouse.getYChange();
Serial.print(deltaX);
Serial.print(", ");
Serial.println(deltaY);
}

However, it prints the x,y velocities when the mouse is moving at a very fast (and imprecise) framerate, but when it's not moving it prints 0,0 only every ~5 seconds (again not very precise). I would like to have these readings at really precise time intervals, the same when moving and when not moving. Delay() doesn't work for this because it still needs to wait for the reading, and it doesn't change the 5 second interval when the mouse is not moving. Any clue of how to get this?

Thank you again!

PS: I think by default the rate at which these functions read from the port (or print?) depends on the velocity, so the faster it the mouse moves the faster they return values.

1 Like

Can you add a print of millisecond tick before and after each mouse.get call to see where that 5 seconds were spent? I am guessing time is spent in these calls, 2.5 second per call.

I fixed this issue following this link:

After adding the line specified in the link, there is no wait for getting the readings from the USB, so the 5 second interval is not an issue anymore. This means that with the code posted above and that line on hidboot.h we can print the x,y velocities of the mouse when moving and when still, and the framerate does not depend on the velocity of the movement.

The new issue is, I still can't specify the framerate I want. There will always be some delay of waiting for the reading. Furthermore, the readings are not made at a specific framerate either, this varies between readings. The interval between two frames can go from ~0.004 and ~0.008 seconds. Do you have any idea how to change this?

Thank you again for the help!

What frame rate do you want and how much jitter do you allow?
You should use micros() to time such short time interval for better accuracy. I'm not familiar with the DUE board. Can you run a USB_desc example code to print out the information of the attached device? Maybe your mouse has a polling time of 4ms and the host library is just trying its best to keep to that polling time. Try and disable all serial prints. Save the delays in an array and collect say 100 iterations, calculate average and stdev of delay and print out once done. There must be lots of interrupts on DUE each taking some time to do that could make time slip up as well.