Arduino UNO Mouse HID

I've created a Mouse HID driver for the UNO's atmega8u2. It makes the Arduino appear to be a USB mouse device, and lets it move the mouse and send button presses on a host PC.

The driver implements a serial protocol that expects to receive 4 bytes from the UNO's main processor. The format is a follows:
Byte Description
0 Button states: 0 off, 1 on
Bit 0 - Mouse Button 1
Bit 1 - Mouse Button 2
Bit 2 - Mouse Button 3
1 X movement: int8_t range -127 to +128
2 Y movement: int8_t range -127 to +128
3 Wheel movement: Not implemented, will be added soon.

Here's the firmware, source, and an example sketch that moves the mouse in a clockwise square every 5 seconds. See the earlier posts about how to load the firmware using DFU mode, and how to build the firmware.


Download file "Arduino-mouse-0.1.hex"
Download file "Arduino-mouse-0.1-mega2560.hex"
Download file "arduino-mouse-0.1.tar.gz"
Download file "mouse_usb_demo.pde"



Comments

AwakingDragon (unauthenticated)
May 30, 2011

Sorry, a bit of a newbie here. Any chance you can post a demo code on how to command the mouse button clicks? Thanks.

darran
Jun 2, 2011

Hi AwakingDragon,

you can modify the demo sketch to send mouse button presses by setting bits 0, 1, and 2 of the mouseReport.button variable. For example, to send button 1, set mouseReport.button=1, button 2, set mouseReport.button=2, button 3, set mouseReport.button=4, all buttons at once, set mouseReport.button=7 (that's bit 0 + bit 1 + bit 2).

E.g.

/* Send button 1 press */
mouseReport.buttons = 1;
mouseReport.x = 0;
mouseReport.y = 0;
mouseReport.wheel = 0;
Serial.write((uint8_t *)&mouseReport, 4);

/* Send no button presses */
mouseReport.buttons = 0;
Serial.write((uint8_t *)&mouseReport, 4);

Triple Axis Accelerometer Breakout - MMA7361 (unauthenticated)
Oct 18, 2011

how do you think i can use the datas from the accelerometer to move the pointer ?

Re: Triple Axis Accelerometer Breakout - MMA7361 (unauthenticated)
Oct 19, 2011

Sure you can! The only thing you should do is to convert accelerometer's values to mouse ones. It will be something like this:
mouseReport.x = map(accelerometer.x, 0, 1000, -127, 127);
mouseReport.y = map(accelerometer.y, 0, 1000, -127, 127);
assuming that your accelerometer returns values from 0 to 1000.

taipscode (unauthenticated)
Oct 31, 2011

Please ,help me!!!!

First ,i connect usb mouse into Arduino mega ADK
Second ,i upload usb_mouse_demo.pde to Arduino mega ADK.
But result , the led of usb mouse don't light . I don't see anything on serial monitor when i move usb mouse .

Thankyou very much .
Best Regards.

renato gallo (unauthenticated)
Nov 5, 2011

HELP !!!! please !!!! i beg you !!!!!

make

-------- begin --------
avr-gcc (Gentoo 4.5.3-r1 p1.0, pie-0.4.5) 4.5.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling C: Arduino-mouse.c
avr-gcc -c -mmcu=atmega8u2 -I. -gdwarf-2 -DF_CPU=16000000UL -DF_CLOCK=16000000UL -DARDUINO_MODEL_PID=0x0001 -DBOARD=BOARD_USER -D USB_DEVICE_ONLY -D FIXED_CONTROL_ENDPOINT_SIZE=8 -D FIXED_NUM_CONFIGURATIONS=1 -D USE_FLASH_DESCRIPTORS -D DEVICE_STATE_AS_GPIOR=0 -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" -D NO_DEVICE_SELF_POWER -D NO_DEVICE_REMOTE_WAKEUP -D NO_INTERNAL_SERIAL -DAVR_RESET_LINE_PORT="PORTD" -DAVR_RESET_LINE_DDR="DDRD" -DAVR_RESET_LINE_MASK="(1 << 7)" -DTX_RX_LED_PULSE_MS=3 -DPING_PONG_LED_PULSE_MS=100 -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fno-inline-small-functions -fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Wstrict-prototypes -Wa,-adhlns=./Arduino-mouse.lst -I../../ -std=gnu99 -Wundef -MMD -MP -MF .dep/Arduino-mouse.o.d Arduino-mouse.c -o Arduino-mouse.o
In file included from ../../LUFA/Drivers/USB/../../Common/Common.h:68:0,
from ../../LUFA/Drivers/USB/USB.h:362,
from Descriptors.h:40,
from Arduino-mouse.h:45,
from Arduino-mouse.c:62:
../../LUFA/Drivers/USB/../../Common/ArchitectureSpecific.h:66:9: warning: "ARCH" is not defined
../../LUFA/Drivers/USB/../../Common/ArchitectureSpecific.h:66:17: warning: "ARCH_AVR8" is not defined
In file included from ../../LUFA/Drivers/USB/Core/USBController.h:118:0,
from ../../LUFA/Drivers/USB/Core/USBTask.h:47,
from ../../LUFA/Drivers/USB/USB.h:366,
from Descriptors.h:40,
from Arduino-mouse.h:45,
from Arduino-mouse.c:62:
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h:84:5: error: #error F_USB is not defined. You must define F_USB to the frequency of the unprescaled USB controller clock in your project makefile.
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h:87:8: warning: "F_USB" is not defined
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h:99:10: warning: "F_USB" is not defined
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h:114:5: error: #error No PLL prescale value available for chosen F_USB value and AVR model.
In file included from ../../LUFA/Drivers/USB/Core/USBController.h:118:0,
from ../../LUFA/Drivers/USB/Core/USBTask.h:47,
from ../../LUFA/Drivers/USB/USB.h:366,
from Descriptors.h:40,
from Arduino-mouse.h:45,
from Arduino-mouse.c:62:
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h: In function 'USB_PLL_On':
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h:335:14: error: 'USB_PLL_PSC' undeclared (first use in this function)
../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h:335:14: note: each undeclared identifier is reported only once for each function it appears in
In file included from Arduino-mouse.h:45:0,
from Arduino-mouse.c:62:
Descriptors.h: At top level:
Descriptors.h:54:4: error: expected specifier-qualifier-list before 'USB_HID_Descriptor_t'
Descriptors.h:66:12: error: conflicting types for 'CALLBACK_USB_GetDescriptor'
../../LUFA/Drivers/USB/Core/AVR8/../Device.h:133:13: note: previous declaration of 'CALLBACK_USB_GetDescriptor' was here
In file included from ../../LUFA/Drivers/Board/LEDs.h:175:0,
from Arduino-mouse.h:50,
from Arduino-mouse.c:62:
./Board/LEDs.h:48:5: error: #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
make: *** [Arduino-mouse.o] Error 1

frefol (unauthenticated)
Nov 28, 2011

I haven't built this yet but I wanted to make sure of something first. I assume mouseReport.x = 0; and mouseReport.y = 0; tells the mouse cursor how far to move, correct? Also in your demo pde, you have Serial.write((uint8_t *)&nullReport, 4);. Do I need that after every set of actions like in you demo? I am building a standalone Arduino Uno, including the Atmega8u2 and want it to be able to be used for our timeclock system at work. Thanks for the help.

darran
Dec 6, 2011

Hi frefol, its been a while since I've run this code, but yes the null report is needed to cancel the previous report otherwise the 8u2 will continue to provide the report to the host at the poll rate of the USB driver.

Cheers.

Cory (unauthenticated)
Jan 14, 2012

Hey darran, is it possible to implement this on LilyPad Arduino's? It'd be nice to fit this into something smaller to expand what you can do with this. I'm going to try this later today, but it looks great, thanks so much!

darran
Jan 17, 2012

Hi Cory, the LilyPad doesn't have a USB interface so it's not going to work as an HID device. The teensy is pretty small and great for USB HID projects - it might be what you're after.

Cory (unauthenticated)
Jan 21, 2012

I'll look into it, thanks! However, I was planning on using Bluetooth with this... does that matter? Specifically, I was looking at the BlueSMIRF HID Bluetooth Modem from Sparkfun.

random (unauthenticated)
Mar 14, 2012

Hello...I know very little about Arduino. If I download the files and upload your pde will the arduino control my computer's cursor?

Jolly42 (unauthenticated)
Mar 30, 2012

Hi, I have installed the firmware on my Arduino UNO R2 and it's working fine. However I have a few concerns. When running the demo program the mouse seems to be slighty inaccurate. After going around a few times, it jumps slighty to the left, and after a while the mouse has moved several centimeters on the screen which is a problem for the project I'm working on. I've tried selecting/deselecting the "Enhance pointer precision" in the mouse settings, however this does not seem to work. Any thoughts? Another problem I have is that I need the mouse button to be kept pressed in, instead of a single push. Is this possible?

darran
Apr 1, 2012

Hi Jolly42, the mouse accuracy may be due to the polling rate and how often data is sent to the PC. I noticed similar behaviour with the demo sketch. I think some experimenting is in order.

TLE93 (unauthenticated)
Apr 11, 2012

Hi darran, I have succesfully set the Arduino to move the cursor via a variable resistor. It works well but now I need the Arduino to press and hold a button click. At the moment it seems like the button click is released after each loop in the sketch. Any suggestions how to solve this problem?

Amberjack (unauthenticated)
May 15, 2012

Hi darran,
I've just confirmed how it works. Thanks for great hacking.

I'd like to increase the resolution of mouseReport.x/mouseReport.y from 1 byte to 2byte.
Could you give me suggestion where to start from?

Amberjack (unauthenticated)
May 16, 2012

Sorry, I misunderstanded about mouseReport.x/mouseReport.y. It is the difference between previous point and current point. Please forget previous question(^ ^;

Tõnu (unauthenticated)
May 20, 2012

Hi darran,

Can you comment on absolute mouse mode? Would that be possible?

(unauthenticated)
May 21, 2012

Hi tõnu,

I haven't heard of absolute mode before, but a quick google got quite a few hits. Looks like a good research topic.

Tõnu (unauthenticated)
May 22, 2012

well it kind of acts like the drawing tablets. the screen measures are related to the surface of the tablet. touching the left top corner of the tablet would move the mouse simultaneously to the left top corner of the screen.

I'm working on a project where i get a heading from a digital compass and need the mouse to position itself relative to that data. would be a lot easier with absolute mode as with the relative mouse movements (5left, 10 down etc) the script doesn't know where the mouse actually is on the screen. the compass motions are a bit erratic so it could easily go out of sync. absolute mouse positioning would be awesome :)

Tõnu (unauthenticated)
May 22, 2012

also this might be helpful http://arduino.cc/forum/index.php?topic=94140.0

karim (unauthenticated)
May 28, 2012

how can i use the code on windows

David (unauthenticated)
Jul 6, 2012

@darren, Did you start from datasheets and other, similar projects or is this code refined from someone else?

@karim, I assume you mean get the code into an editor and compile it. You should be able to do that using something like MinGW, http://www.mingw.org/, which will provide you with a linux like developement environment

darran
Jul 9, 2012

Hi David,

I used code from Dean Camera LUFA project. He's done an amazing job creating USB drivers for MCUs along with examples for most devices. Take a look at here:http://www.fourwalledcubicle.com/LUFA.php. I used documents from the official USB standards web site, like http://www.usb.org/developers/devclass_docs/Hut1_11.pdf which describes the HID keyboard key maps.

darran
Jul 9, 2012

hi karim,

I'm not sure if you can compile the firmware on Windows, perhaps with the mingw project as David has suggested, or maybe with cygwin. For loading the USB firmware hex files to the atmega8u2 in DFU mode you can use flip from Atmel: http://www.atmel.com/tools/FLIP.aspx .

Anon (unauthenticated)
Aug 4, 2012

Hey darren,

Can you tell me that when using this hack are the serial pins Tx and Rx available for communication with another serial device ?

NoobLevler (unauthenticated)
Oct 20, 2012

will this still work with the 16u2 in the rev 3 Uno?
Thanks

darran
Nov 14, 2012

NoobLevler, it should be fine on the 16u2 also. You may need to patch dfu-programmer to support the 16u2 (if you're using flip it will be fine). I posted a patch and details for getting dfu-programmer working here: http://arduino.cc/forum/index.php/topic,92148.0.html

anotherNoob (unauthenticated)
Feb 10, 2013

First of all good job. The code works perfect :). I just dont get the point of using ((uin8_t *)&mouseReport, 4) can someone post some links or explain it to me. Thanks and sorry for my english :/ (you can send me links/explanation to tim.kambic12@gmail.com )

darran
Mar 3, 2013

Hi anotherNoob, the syntax is called a "C type cast". I should probably replace it with a simpler method, but basically it tells the compiler to treat the mouseReport as an array of bytes (uint8_t is an unsigned 8-bit data type, or byte). This allows you to use Serial.write() to happily send the 4 bytes.

Clem (unauthenticated)
Apr 12, 2013

Hi, For a project, i use a gyro to move the pointer. But now i try to use buttons. But it's not simple...
Help me :
struct {
uint8_t buttons;
int8_t x;
int8_t y;

} mouseReport;

uint8_t nullReport[4] = { 0, 0, 0 };

void setup()
{
Serial.begin(9600) ;
delay (500);

}

void loop()
{

float voltX,voltZ,voltZ_ancien;

voltX = (analogRead(0)* 5.0 / 1024.0)-1.23;
voltZ = (analogRead(1)* 5.0 / 1024.0)-1.23;

int ind; // temps deplacement
if ( voltZ>(voltZ_ancien+0.6)) {
mouseReport.buttons=1;
delay (1000);
}
if ( (voltX < 0.3) && (voltX > -0.3)) {
voltX = 0 ;
}
if (( voltZ < 0.3 ) && (voltZ > -0.3)) {
voltZ = 0 ;
}
if (voltX!=0 || voltZ!=0) {

mouseReport.x = 0;
mouseReport.y = 0;

mouseReport.x = -(45*voltX);
for (ind=0; ind<80; ind++) {
Serial.write((uint8_t *)&mouseReport, 4);
Serial.write((uint8_t *)&nullReport, 4);
}

mouseReport.y = -(45*voltZ);
for (ind=0; ind<80; ind++) {
Serial.write((uint8_t *)&mouseReport, 4);
Serial.write((uint8_t *)&nullReport, 4);

}
}
voltZ_ancien=voltZ;
}

Newbie (unauthenticated)
May 1, 2013

Hi darran, plz i want the wheel implementation.Did you implement it? Kindly tell me how to do this? I really want it urgent.My project completetion date is near to end. Help Plzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

George (unauthenticated)
May 2, 2013

Hi everyone,

does anyone know how to get the Arduino DUE's native USB port to act like a HID mouse or keyboard (or both)? There are plenty of DFU how-to's around for the Uno and Leonardo, but hardly anything for the Due.

MouseMove works fine via native USB port - but ONLY if the PC connected to it has the Arduino drivers installed. I would like to not have to have those drivers installed.

Does anyone have a solution/thoughts/ideas?

Regards,
George

Leon (unauthenticated)
May 8, 2013

Anyone had any success in compiling the source using windows?

ivan (unauthenticated)
Mar 27, 2014

Hi everyone,
i am using trackball to act like a mouse with this firmware. i have aero trackball with ps2 connector and want it to be a mouselike when connected to pc over arduino uno and this firmware. will it work if i connect it on analog input, and can arduino read informations sent over ps2 connection. help with the code would also be nice.

thnx

ivan

Henk (unauthenticated)
Aug 26, 2014

Does it work on Mac?

All seems well... programming works... etc... but no mouse shows up...

Henk (unauthenticated)
Aug 26, 2014

My fault... it does work... the sketch just has a delay... :-) Thnx!