{"id":17058754,"url":"https://github.com/denilsonsa/atmega8-magnetometer-usb-mouse","last_synced_at":"2025-04-12T17:51:07.959Z","repository":{"id":136890104,"uuid":"2696660","full_name":"denilsonsa/atmega8-magnetometer-usb-mouse","owner":"denilsonsa","description":"ATmega8 working as USB mouse, by reading movements from a magnetometer (digital compass). [Projeto Final do curso de Bacharelado em Ciência da Computação DCC/UFRJ]","archived":false,"fork":false,"pushed_at":"2023-07-14T19:29:20.000Z","size":4252,"stargazers_count":19,"open_issues_count":0,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-26T12:11:26.357Z","etag":null,"topics":["atmega","atmega8","avr","usb-hid"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/denilsonsa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-11-02T17:31:57.000Z","updated_at":"2023-07-14T13:45:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"134d7829-0b0e-4a3d-b42e-f04cdb1f8cb9","html_url":"https://github.com/denilsonsa/atmega8-magnetometer-usb-mouse","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denilsonsa%2Fatmega8-magnetometer-usb-mouse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denilsonsa%2Fatmega8-magnetometer-usb-mouse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denilsonsa%2Fatmega8-magnetometer-usb-mouse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denilsonsa%2Fatmega8-magnetometer-usb-mouse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denilsonsa","download_url":"https://codeload.github.com/denilsonsa/atmega8-magnetometer-usb-mouse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248610408,"owners_count":21132920,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atmega","atmega8","avr","usb-hid"],"created_at":"2024-10-14T10:30:46.752Z","updated_at":"2025-04-12T17:51:07.952Z","avatar_url":"https://github.com/denilsonsa.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Introduction ##\n\nThis is a USB HID absolute pointing device using an [ATmega8][atmega8] AVR\n8-bit microcontroller and a HMC5883L magnetometer. It allows the user to\ncontrol the mouse pointer by moving the sensor in the air, pointing it at\nthe desired position, somewhat similar to the [Wiimote controller][wiimote]\n(although using a completely different technology).\n\n[atmega8]: http://www.atmel.com/dyn/products/product_card.asp?part_id=2004\n[wiimote]: http://en.wikipedia.org/wiki/Wii_Remote\n\nIt was developed by *Denilson Figueiredo de Sá* (see [blog post][blogpost]) in\nthe year 2011 as the final graduating project in order to obtain Bachelor's\ndegree in Computer Science at [DCC/UFRJ][dcc].\n\n[dcc]: http://www.dcc.ufrj.br/\n[blogpost]: http://denilson.sa.nom.br/blog/2011-12-18/usb-hid-absolute-pointing-device-using-atmega8-and-a-magnetometer/\n\nThis project is mirrored at:\n\n* [https://github.com/denilsonsa/atmega8-magnetometer-usb-mouse][ghmirror]\n\n[ghmirror]: https://github.com/denilsonsa/atmega8-magnetometer-usb-mouse\n\nThe full text of my thesis (written in Portuguese) is available as PDF in\nthe Releases section of [GitHub][ghreleases].\nThe LaTeX source is available in the `monografia/` directory (some minor\ntweaking might be needed in order to compile it).\n\n[ghreleases]: https://github.com/denilsonsa/atmega8-magnetometer-usb-mouse/releases\n\n## Photos and videos ##\n\n* [Photos at Picasa][picasa].\n* Video: [USB Absolute Pointing Device implemented in ATmega8 using\n  Magnetometer][ytprototype] (work-in-progress video)\n* Video: [Dispositivo apontador com interface USB usando magnetômetro][ytusing]\n  (final version, English subtitles available)\n* Video: [Moving the mouse pointer using head movements][ythead] (final version)\n* Video playlist: [Playlist with all videos from this project][ytplaylist]\n  (includes many work-in-progress videos)\n\n[picasa]: https://picasaweb.google.com/denilsonsa/Atmega8MagnetometerUsbMouse\n[ytprototype]: http://www.youtube.com/watch?v=nZLTwfAJmrE\n[ytusing]: http://www.youtube.com/watch?v=lBZV_GAg8yw\n[ythead]: http://www.youtube.com/watch?v=1nuw9zsZtk4\n[ytplaylist]: http://www.youtube.com/playlist?list=PLA37C87EEDE5EC88C\n\nThe schematic diagram of the circuit is available at the `monografia/img/`\nsubdirectory of this repository.\n\n## How it works ##\n\nThe device implements USB HID and should work on any operating system (has\nbeen successfully tested on Linux, Mac OS X and Windows). It identifies\nitself as a keyboard and a mouse (actually, an \"absolute pointing device\").\n\nIt has a physical switch that selects between two modes of operation\n(*configuration mode* and *mouse mode*) and three push-buttons.\n\nUpon plugging the device to the computer, the user should set the switch to\n*configuration mode* and open any simple text editor. In this mode, the\ndevice prints the configuration menu by sending (virtual) keyboard events\nto the computer (maybe it would be more accurate to say that it \"types\" the\nmenu items, instead of printing). Two of the device buttons are used to\nnavigate the menu items (selecting the next or the previous item), and the\nthird button confirms the current selection.\n\nOnce in the *configuration mode*, the user should calibrate the \"zero\" from\nthe sensor, as well as the screen corners. The calibration data is stored\nin the EEPROM memory of the microcontroller, and thus it will be remembered\neven after unplugging the device.\n\nUpon starting the \"zero\" calibration, the device will start printing values\nfrom the sensor, and the user should move the sensor in all possible\ndirections, trying to obtain the maximum and minimum values for each of the\nthree axes (X, Y, Z). The *confirm* button should be pressed to finish the\ncalibration. This calibration is required because the sensor might have a\nbias and thus return values that are not centered on number zero (see\nimages `zerocal_off` and `zerocal_on` from `monografia/img/` subdirectory).\n\nAfter the \"zero\" is correctly calibrated, the user should calibrate each\nscreen corner. The user should navigate the menu items up to `Set topleft`,\npoint the sensor at top-left corner of the screen and then press the\n*confirm* button. This should be repeated for all other corners. For best\nresults, the user should be directly in front of the screen center, and the\nscreen should be facing either to the North or to the South direction.\n\nThe \"zero\" calibration should be needed only once, right after building the\nproject. The corner calibration, on the other hand, is required anytime the\nuser faces a different screen orientation.\n\nAfter completing these two calibrations, the device is ready, and the user\nmay switch to *mouse mode*. In this mode, the mouse pointer will be moved\naccording to the movements of the sensor, and the three buttons work as\nmouse buttons (left, right and middle button).\n\nThe device reads the magnetic field measurements from the sensor as a\n3-axis vector and applies an algorithm to convert that 3D vector into 2D\nscreen coordinates. For details about the algorithm, read the `mouseemu.c`\nsource code.\n\nDue to the limited sensor precision and the amount of captured noise, the\ndevice applies a smoothing filter to the pointer position. This increases\nthe perceived precision, but also introduces a slight delay in the\nmovements.\n\nThe mode switch can also be used to pause the mouse position, as the\npointer is not moved while in the *configuration mode*.\n\nAll the steps mentioned here can be seen in [this video][ytusing].\n\n\n## Possible improvements ##\n\n* Use a microcontroller with more memory. This is needed before\n  implementing any further improvements.\n\n* Use the `DRDY` interrupt signal from the sensor in order to achieve up to\n  160Hz. The currently implemented method uses a 75Hz continuous\n  measurement mode together with polling. It was implemented this way\n  because [the sensor PCB I bought from eBay][fromebay] did not have the\n  `DRDY` line available. [The PCB being sold at Love Electronics][fromle]\n  has that line.\n\n* For best results, the user must be facing to the North or to the South\n  direction. If, instead, the user is facing to the West or to the East,\n  the vertical movement of the pointer is severely degraded. This happens\n  because, in this case, the sensor rotates around the same axis as the\n  magnetic field, and thus gives little to no change in the measurements.\n  A solution for this problem is to attach an accelerometer as a second\n  sensor to this device.\n  \n    * With these two sensors, the magnetometer can be used for horizontal\n      pointer movement and the accelerometer for the vertical pointer\n      movement.\n\n    * These two sensors can be used together to implement a\n      tilt-compensation (similar to [this tutorial from Love\n      Electronics][letilt]).\n\n    * A third sensor, gyroscope, can be added in order to improve precision\n      and reduce the pointer shaking, increasing the responsiveness of the\n      device.\n\n* Try another magnetometer with better precision (if there is such thing).\n\n* Try other algorithms for converting the coordinates.\n\n* Implement wireless communication between the device and the computer.\n\n    * It can be done by using a pair of microcontrollers: one next to the\n      computer, talking to the USB port; and another next to the sensor.\n      The communication between these two microcontrollers can be wireless.\n      This solution has been done before in [two][wishabi] [other][usbwtm]\n      projects.\n\n    * Or it can be done by implementing a Bluetooth HID device.\n\n[fromebay]: http://cgi.ebay.com/HMC5883L-HMC5883-Triple-Axis-Magnetometer-Sensor-board-/260770948278\n[fromle]: https://www.loveelectronics.co.uk/products/140/3-axis-magnetometer---hmc5883-breakout-board\n[letilt]: https://www.loveelectronics.co.uk/Tutorials/13/tilt-compensated-compass-arduino-tutorial\n[wishabi]: http://vusb.wikidot.com/project:wishabi\n[usbwtm]: http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2010/ss868_jfe5/ss868_jfe5/\n\n\n## Requirements ##\n\nIn order to build this project, you need:\n\n* **ATmega8** or any other similar AVR microcontroller. If using a\n  different model, some minor fine-tuning of the firmware might be neded.\n  By the way, if you are going to buy a microcontroller, I highly recommend\n  choosing one with more memory. Although 8KiB was enough, some parts of\n  the firmware had to be disabled in order to fit. If you can, get a device\n  with at least 16KiB of flash memory.\n* **HMC5883L** 3-axis magnetometer. If you use a different sensor, be\n  prepared to rewrite the sensor handling code.\n* Other electronic components. See the circuit schematic at\n  `monografia/img/AVR-magnetometer-usb-mouse`, available in SVG, PNG and\n  PDF formats.\n\nThe required software environment:\n\n* [AVR-GCC][avrgcc] - Developed with version 4.5.3. Different versions\n  require updating a few compiler flags at the `Makefile`, as the available\n  flags change between each major version.\n* [AVR-Libc][avrlibc] - Developed with version 1.7.0.\n* [AVRDUDE][avrdude], or any other tool to write the firmware onto the\n  device.\n* Unix-like system - Developed on Gentoo Linux amd64, should work anywhere\n  with the standard Unix tools.\n\n[avrgcc]: http://gcc.gnu.org/install/specific.html#avr\n[avrlibc]: http://www.nongnu.org/avr-libc/\n[avrdude]: http://www.nongnu.org/avrdude/\n\n\n## Directories in this repository ##\n\nThe main contents of this project are in these three directories:\n\n* `firmware/` - Contains the source-code of the firmware.\n* `projection/` - Python code for studying different algorithms for\n  converting the 3D vectors to 2D screen coordinates.\n* `monografia/` - LaTeX source of the thesis (written in Portuguese).\n* `apresentacao/` - LaTeX source of the presentation (written in Portuguese).\n\nThere are also some extra directories:\n\n* `html_javascript/` - Some HTML pages I used during my presentation.\n* `linux_usbhid_bug/` - Information about a minor bug in Linux USB HID\n  handling.\n* `other_scripts/` - Some scripts to generate a graph of the firmware size\n  over time.\n\n\n## How to build this project ##\n\nAll commands listed here assume you are inside the `firmware` directory (the\none with `Makefile` and `checksize`).\n\nWant a quick list of available *make targets*? Run `make help`.\n\n\n### Preparation ###\n\nThese steps only need to be done once. They are the initial setup of the\nproject.\n\n1. Mount the hardware on your breadboard.\n   You can find a short description at the *Hardware description* comment in\n   `main.c` file and a complete circuit schematic at\n   `monografia/img/AVR-magnetometer-usb-mouse`, available in SVG, PNG and\n   PDF formats.\n\n2. Open `hardwareconfig.h` and check if those definitions are consistent with\n   the hardware. Basically, just check if the USB D- and USB D+ are connected\n   to the correct pins.\n\n3. Open `TWI_Master.h` and check if `TWI_TWBR` value is correct. It should be\n   updated if you use a different clock rate.\n\n4. Open `Makefile`.\n    1. Set `AVRDUDE_PARAMS` according to your AVR programmer, if you use\n       something other than USBasp.\n    2. If you use a clock other than 12MHz, update `F_CPU` setting.\n    3. If you use a microcontroller other than ATmega8, update `GCC_MCU`,\n       `AVRDUDE_MCU`, `BOOTLOADER_ADDRESS` and `CHECKSIZE_CODELIMIT`.\n    4. Also check if the fuse bits from `AVRDUDE_PARAMS_FUSE` are correct.\n    5. If you want to use a bootloader, set `BOOTLOADER_ENABLED` to `1`. Make\n       sure your device has enough space to hold the main firmware together\n       with the bootloader.\n    6. Set `ENABLE_KEYBOARD`, `ENABLE_MOUSE` and `ENABLE_FULL_MENU` to `1` or\n       `0`, according to what you want in the final firmware. Look at the\n       comments in that file for detailed information.\n\n5. Run `make writefuse` to write the fuse bits.\n\n### Writing the bootloader (optional) ###\n\nThis section is completely optional. You don't need a bootloader. It's just\ncool and handy, but you don't need it. Feel free to skip these steps.\n\nThis project comes with USBaspLoader. After it is written to the\nmicrocontroller, any later firmware update can be done without the need of a\ndedicated AVR programmer.\n\nAfter the bootloader is written, if a certain condition is true (a specific\nbutton is held down) during the device boot, then the bootloader will take\ncontrol and the device will identify itself as USBasp. Writing to this\n\"virtual\" USBasp will actually update the firmware, without the need of any\nextra hardware.\n\n1. Did you update the `Makefile` as described above? Did you run `make\n   writefuse`?\n\n2. Run `make clean`.\n\n3. Run `make boot`. This will compile the bootloader.\n\n4. Run `make writeboot`. This will write the bootloader to the microcontroller.\n   You need an AVR programmer for this step.\n\n5. Run `make clean` to clean up compiled files. This is required because the\n   compiled files from the bootloader are incompatible with the main project\n   (and vice-versa).\n\nAll done! You don't need an AVR programmer anymore!\n\n### Writing the EEPROM (optional) ###\n\nYou don't need to write the EEPROM now. You can just use the firmware's\nbuilt-in menus (enabled with `ENABLE_KEYBOARD`) to interactively update the\nsettings stored in the EEPROM.\n\nThe EEPROM values defined in `sensor.c` are appropriate for my sensor.\nProbably your sensor will have different calibration numbers, and thus it is\nhighly recommended to use the firmware's menus to calibrate it (at least\nonce).\n\nAnyway, to write the EEPROM values, just run `make`, followed by `make\nwriteeeprom`.\n\n### Writing the main firmware ###\n\nYou either need an AVR programmer, or you need to start the bootloader on the\nmicrocontroller (see the section about the bootloader).\n\n1. Run either `make all` or `make combine`.\n    * `make` is a shortcut for `make all`.\n\n    * `make combine` uses some special compiler flags in order to compile\n      all files at the same time, leading to extra optimizations not\n      possible when compiling separately. This command will not work on\n      GCC 4.6 or newer, because the flags have changed (and, thus, they\n      need to be updated). Read `Makefile` to learn more.\n\n    * If it fails, try running `make clean`. The `Makefile` from this\n      project is not perfect and does not list all file dependencies. It's\n      always a good idea to run `make clean` whenever something fails.\n\n2. Run `make writeflash`.\n\nAfter you edit the firmware, you only need to redo these two steps.\n\n\n## Acknowledgements ##\n\n* *Prof. Nelson Quilula Vasconcelos*, advisor for this project.\n* *Bruno Bottino Ferreira* for the help and patience during this project.\n* *Marcelo Salhab Brogliato* for suggesting the coordinate conversion using\n  linear equations.\n* *OBJECTIVE DEVELOPMENT Software GmbH* for the awesome [V-USB][vusb]\n  firmware-only implementation of USB for AVR devices.\n* *Atmel Corporation* for the AVR microcontrollers and the [AVR315: TWI\n  Master Implementation][avr315].\n* Authors and contributors of all open-source and free software used during\n  this project.\n* *Marcin Wichary* demonstration at [Google I/O 2011: The Secrets of Google\n  Pac-Man: A Game Show][googleio], which gave me the main idea for this\n  project.\n\n[vusb]: http://www.obdev.at/products/vusb/index.html\n[avr315]: http://www.atmel.com/dyn/products/documents.asp?category_id=163\u0026family_id=607\u0026subfamily_id=760\n[googleio]: http://www.youtube.com/watch?v=ttavBa4giPc#t=2m46s\n\n\n vi:expandtab:filetype=markdown\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenilsonsa%2Fatmega8-magnetometer-usb-mouse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenilsonsa%2Fatmega8-magnetometer-usb-mouse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenilsonsa%2Fatmega8-magnetometer-usb-mouse/lists"}