{"id":22053137,"url":"https://github.com/nuilab/gyrowatch","last_synced_at":"2025-08-30T10:36:35.120Z","repository":{"id":72991027,"uuid":"75881161","full_name":"NuiLab/GyroWatch","owner":"NuiLab","description":"Firmware for a custom watch that features a gyroscope.","archived":false,"fork":false,"pushed_at":"2016-12-13T07:30:35.000Z","size":33,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-29T05:34:30.305Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"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/NuiLab.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":"2016-12-07T22:31:10.000Z","updated_at":"2017-01-14T17:32:48.000Z","dependencies_parsed_at":"2023-03-04T18:45:16.267Z","dependency_job_id":null,"html_url":"https://github.com/NuiLab/GyroWatch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/NuiLab/GyroWatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NuiLab%2FGyroWatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NuiLab%2FGyroWatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NuiLab%2FGyroWatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NuiLab%2FGyroWatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NuiLab","download_url":"https://codeload.github.com/NuiLab/GyroWatch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NuiLab%2FGyroWatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272839630,"owners_count":25001860,"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","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-30T15:15:20.950Z","updated_at":"2025-08-30T10:36:35.083Z","avatar_url":"https://github.com/NuiLab.png","language":"C","readme":"# Magic Motion Sensor Watch Software\n\n## Overview\n\nThe software is comprised of the I2C library, the LSM9DS1 module, the Filter and\nthe main program file that ties these things together.\n\n## I2C Library\n\nThe I2C Library is comprised of the libi2c.h and libi2c.c files. These files\ndepend on the linux kernel headers being installed, as well as the linux i2c\ndriver being installed. Note that for the MMSW, these are preinstalled as part\nof the custom image for the PiTFT touchscreen. In order to use the library, you\nmust first open the I2C bus with the `open_i2c(int bus)` function. The function\nwill return a file descriptor for the opened I2C Bus. This will be passed to the\nother functions in the library. When you are done using the bus, you should\nclose the descriptor with `close(int fd)`. The bus argument is used to select an\nI2C Bus. Note that on the raspberry pi, there are two I2C busses, but only the\nsecond bus, bus 1, is used for the sensor. The other is reserved.\n\nOnce the bus is opened, the `set_slave(int fd, uint8_t addr)` function can be\nused to set the slave to talk to. Once a slave address is set, you can use\n`write_bytes()` or `read_bytes()` to write or read multiple bytes. The\n`write_bytes()` function performs a \"burst mode\" write. The `read_bytes()`\nfunction performs a \"burst mode\" read.\n\n## LSM9DS1 Module\n\nThis library consists of the lsm9ds1.c and lsm9ds1.h files, as well as the\nregisters.h file. The registers.h file contains a list of register addresses for\ninteresting and useful registers on the LSM9DS1. The lsm9ds1.c and .h files\ndefine structures and methods for setting up the sensor for data collection and\nactually collecting data. An example of how to use this module can be seen in\ni2c.c or main.cpp. The important thing to note here is that gyroscope and\naccelerometer data are collected with one function call and magnetometer data\nwith another. This is due to the magnetometer being at a different I2C address\nand thus needing a seperate I2C read command. If the magnetometer data is not\nneeded, you can simply not call the `get_mag()` function. The `convert()`\nfunction converts the raw 16 bit sign integer data from the sensor to floating\npoint data. Gyroscope data is read in degrees per second, accelerometer data is\nin g's and magnetometer data is in milligauss(I think). The conversion is done\nby multiplying the raw integer by the full scale value of each sensor and then dividing by\n2^15 - 1. This has the effect of converting to the actual measurement of each\nsensor. The full scale values are defined in lsm9ds1.c and are set upon\ninitialization of the sensor in the `init_sensor()` routine. Note that you need\nonly change the variables at the top of the function in order to change the\ndesired full scale value and output data rate. These values are from the LSM9DS1\ndatasheet, and are the actual bits set in the `CTRL_REG1_G`, `CTRL_REG6_XL`,\n`CTRL_REG1_M`, and `CTRL_REG2_M` registers. More info in the LSM9DS1 datasheet. \n\n## i2c.c and main.cpp\n\nIncluded are two programs that can be used to extract data from the sensor. The\n`i2c.c` program was written first and used for most of the development of the\nsensor module and i2c library. The program runs an infinite loop, displaying\nraw, unfiltered data from all nine axes in the terminal. The data is comma\nsepperated and suitable for generating a comma separated values file. The first\nline of output contains a header for easy importing into spreadsheet software\nsuch as MS Excel, or for importing into Matlab or Python for further processing.\nThis is the program used to generate the raw data that the filter design team\nused to design the kalman and moving average filter. Running the program is as\nsimple as compiling it with `make i2c` and then running it with either `./i2c`\nto display to the terminal, or `./i2c \u003e data.csv` which redirects this output to\na file called `data.csv`. To quit the program, simply hit Ctrl-C on the\nkeyboard. Note that the last line will most likely be truncated because of\nkilling the program with Ctrl-C.\n\nThe `main.cpp` file is the program used during the demonstration itself, and it\nis a bit more sofisticated. It can be compiled by running `make` with out any\narguments, and run with `./main`. It takes a single command line argument in the\nform of an IPv4 address in quad-dotted decimal format, for example,\n`192.168.0.1`. This IP address is where the program will send the filtered data.\nIf no IP address is supplied, the program uses the loopback address `127.0.0.1`\nas a default. Filtered data comes in the form of an Euler angle, comprised of\nthree individual angles, pitch, roll, and yaw. In addition, unfiltered\nacelerometer and gyroscope data is sent as well. The data is sent as UDP packets\nto UDP Port 9001. The packets contain a string representation of the Euler angle\nand the individual raw measurements of the accellerometer and gyroscope. This\ndata can be seen simply by pointing the program to a computer running this\nnetcat command `nc -lu 9001`. This command sets netcat to listen for data coming\nin on UDP port 9001. For the purposes of the demonstration, we had Alain, a\nstudent in the OpenHID lab add some code to an Unreal powered 3d game that would\nlisten to this port, and we pointed the software on the watch at the computer\nrunning the game. The output format can easily be changed, as the output is\nsplit into it's own function, the `send_angles()` function.\n\nfiltering is handled by two files, the `euler.cpp` file and the `moving.cpp` file.\nThese define functions for converting from raw measurements to euler angles, and\nfor filtering said euler angles. At this time, only the moving average filter is\nimplemented, but it should be a relatively simply task to integrate any other\nfilter. One would just have to add another `.cpp` and `.h` file for the new filter,\nand change the `main` function in `main.cpp`. Specifically, the line where\n`avg_angle - moving_avg(raw_angle)` would need to be changed to call the desired\nfiltering funciton.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuilab%2Fgyrowatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnuilab%2Fgyrowatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuilab%2Fgyrowatch/lists"}