Turning your Arduino Uno R3 into an USB mouse

Tonight I’ve just turned my Arduino Uno R3, which runs the Atmega16U2 chip, into an USB mouse on my Ubuntu 12.04. I thought this guide might be helpful to those who are looking for a solution with similar setup as mine. Basically, this method uses the special USB protocol called Device Firmware Update (DFU) to program the Atmega16U2 chip.

In this demo, we will flash the generic USB HID mouse firmware by Darran. And first of all, you need to download the two firmware files:

  • Arduino-usbserial-uno.hex
  • Arduino-mouse-0.1.hex

from here.

Next step is to install dfu-programmer, the tool to reset the firmware for Atmega16U2, on your system. Download and install the dfu-programmer 0.6.2. (This version is confirmed to support Atmega16U2). Or you can try using apt-get but it did not give me the correct version.

sudo apt-get install dfu-programmer dfu-util

Now to program the firmware for Atmega16U2, we need to follow the procedure below:

  1. Flash Arduino-usbserial-uno.ino bootloader with dfu-programmer (erase/flash/reset)
  2. Plug cycle the Arduino (eg. Unplug the Arduino USB cable; wait 1-2 seconds; and plug it back in)
  3. Flash firmware with your own sketch using Arduino IDE (eg. Upload an Arduino sketch as usual. However, this sketch controls the mouse as you desire)
  4. Plug cycle the Arduino
  5. Flash Arduino-mouse-0.1.hex bootloader with dfu-programmer (erase/flash/reset)
  6. Done! Now plug cycle the Arduino and it should control the mouse as written in the sketch in step (3)

In details:

Step 1: Reset your chip by bridging the reset pin with the ground as guided here.

Bridging reset pin and the ground pin
Bridging reset pin and the ground pin

Then go the the folder where you extracted the firmware files above, and perform erase/flash/reset as following:

sudo dfu-programmer atmega16u2 erase
sudo dfu-programmer atmega16u2 flash --debug 1 Arduino-usbserial-uno.hex
sudo dfu-programmer atmega16u2 reset

Step 2: plug cycle your Arduino.

Step 3: upload the following sketch using Arduino IDE. What the below sketch does is only move the mouse in a small circle in a 1-second interval. This should be the starting sketch, and you should change it later as desired.

An example of what this sketch could do is like the Gyration Air Mouse which reads the values reported from its Inertial Measurement Unit, and moves the mouse on the screen accordingly.

/* Arduino USB Mouse HID demo */

/* Author: Darran Hunt
 * Release into the public domain.
 */

struct {
    uint8_t buttons;
    int8_t x;
    int8_t y;
    int8_t wheel;	/* Not yet implemented */
} mouseReport;

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

void setup();
void loop();

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

/* Move the mouse in a clockwise square every 5 seconds */
void loop()
{
    int ind;
    delay(1000);

    mouseReport.buttons = 0;
    mouseReport.x = 0;
    mouseReport.y = 0;
    mouseReport.wheel = 0;

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

    mouseReport.x = 0;
    mouseReport.y = -2;
    for (ind=0; ind<20; ind++) {
	Serial.write((uint8_t *)&mouseReport, 4);
	Serial.write((uint8_t *)&nullReport, 4);
    }

    mouseReport.x = 2;
    mouseReport.y = 0;
    for (ind=0; ind<20; ind++) {
	Serial.write((uint8_t *)&mouseReport, 4);
	Serial.write((uint8_t *)&nullReport, 4);
    }

    mouseReport.x = 0;
    mouseReport.y = 2;
    for (ind=0; ind<20; ind++) {
	Serial.write((uint8_t *)&mouseReport, 4);
	Serial.write((uint8_t *)&nullReport, 4);
    }
}

Step 4: plug cycle your Arduino.

Step 5: Reset your chip again as in the step 1, and and perform erase/flash/reset as following:

sudo dfu-programmer atmega16u2 erase
sudo dfu-programmer atmega16u2 flash --debug 1 Arduino-mouse-0.1.hex
sudo dfu-programmer atmega16u2 reset

Finally: plug cycle your Arduino, and test your 'new mouse' ! It should move around, and around,.. and around in circle. :)

Cheers,

Anh

22 thoughts on “Turning your Arduino Uno R3 into an USB mouse”

  1. Anh ơi cho em hỏi. anh có thể hướng dẫn cách cập nhật firmware bằng windows được không anh?

    1. Em đọc trên trang arduino.cc thì em thấy họ bảo cần phải hàn 1 con trở 10k vào mạch thì mới làm được. nhưng mà em không thấy anh có bước đó. Vậy là sao anh? Em làm phiền anh nhiều quá :)

      1. Ờ anh cũng đọc trên đó là như vậy nhưng nếu xài Arduino Uno R3 thì ko cần đâu, như hướng dẫn của anh là chạy đc ngay.

  2. dạ, em cám ơn anh nhiều ạ! em muốn làm một con chuột nhận tín hiệu tọa độ từ mpu6050 rồi truyền qua máy tính. Vậy thì làm theo cách của anh có được không ạ?

    1. Uhm kiểu làm 3D mouse hả? Tất nhiên là đc.. USB mouse nó chỉ cần x/y increments thôi.
      Còn mình chuyển từ orientation(pitch/roll/yaw) của MPU6050 sang x/y increments là thuật toán của mình.

  3. cám ơn anh. em làm được rồi. :D mà anh ơi, bây giờ em nạp lại code mới cho arduino thì em có cần phải làm lại từ bước 1 không anh? hay là em chỉ cần nạp thôi

    1. Uhm em phải làm lại từ 1-5.
      Bước 1-3 là để nạp code mới vào.
      Bước 4-5 là để sử dụng code mới nạp đó dưới dạng mouse.

  4. anh oi, doan code nay co nghia la gi vay anh?
    for (ind=0; ind<20; ind++) {
    Serial.write((uint8_t *)&mouseReport, 4);
    Serial.write((uint8_t *)&nullReport, 4);
    }

    1. À đoạn này là để move con trỏ 20 lần. Cái loop để smooth cái movement, chứ ko nhảy độp 1 phát luôn. Vì mouse là relative positioning, mình move con trỏ bao nhiêu units so với vị trí trước đó.

  5. dạ. em cám ơn anh. 2 arguments của hàm Serial.write() nghĩa là gì anh?
    “(uint8_t *)&mouseReport” này anh?

  6. anh oi, khi em lam voi 3D mouse thi firmware Arduino-mouse-0.1.hex co su dung duoc khong anh? hay em phai co 1 firmware khac a? vi em thay nguoi khac lam Arduino keyboard thi ho dung firmware khac. anh giup em duoc khong a

    1. Uh cái firmware này là dành cho mouse đấy. 3D mouse thì thực ra vẫn là con trỏ 2D trên màn hình thôi, nên vẫn dùng cái này.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>