{"id":14978096,"url":"https://github.com/niru-5/imusensor","last_synced_at":"2025-07-06T13:07:20.081Z","repository":{"id":40421215,"uuid":"273680989","full_name":"niru-5/imusensor","owner":"niru-5","description":"Python library for communication between raspberry pi and MPU9250 imu","archived":false,"fork":false,"pushed_at":"2022-05-09T18:51:12.000Z","size":126,"stargazers_count":109,"open_issues_count":16,"forks_count":32,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-06T08:18:39.170Z","etag":null,"topics":["accelerometer","caliberation","gyroscope","imu","imu-sensor","kalman","kalman-filter","madgwick","mpu9250","python3","raspberry-pi","raspberry-pi-3","rpi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/niru-5.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-20T09:50:10.000Z","updated_at":"2025-06-16T14:10:24.000Z","dependencies_parsed_at":"2022-08-09T20:00:29.691Z","dependency_job_id":null,"html_url":"https://github.com/niru-5/imusensor","commit_stats":null,"previous_names":["niru-5/imu-mpu9250"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/niru-5/imusensor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niru-5%2Fimusensor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niru-5%2Fimusensor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niru-5%2Fimusensor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niru-5%2Fimusensor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/niru-5","download_url":"https://codeload.github.com/niru-5/imusensor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niru-5%2Fimusensor/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263905742,"owners_count":23527972,"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":["accelerometer","caliberation","gyroscope","imu","imu-sensor","kalman","kalman-filter","madgwick","mpu9250","python3","raspberry-pi","raspberry-pi-3","rpi"],"created_at":"2024-09-24T13:56:51.551Z","updated_at":"2025-07-06T13:07:20.063Z","avatar_url":"https://github.com/niru-5.png","language":"Python","readme":"# Update  \nAdding blog links to provide more information about the math behind the code.    \n[IMU Intro](https://medium.com/@niru5/intro-to-inertial-measurement-unit-imu-part-1-47f19fc7d68d) - It gives an introduction into IMU working and the math behind calibration and basic idea behind finding roll, pitch and yaw.   \n[Sensor Fusion](https://medium.com/@niru5/fusion-of-accelerometer-magnetometer-data-with-gyroscope-part-2-2887261e7245) - This blog goes into math behind kalman filter, Madgwick filter and how they are applied here.   \n[Hands-on Intro](https://medium.com/@niru5/hands-on-with-rpi-and-mpu9250-part-3-232378fa6dbc) - A general overview of getting started. \n\n# imusensor\nThe repo provides a bridge between MPU9250 and raspberry pi. It also lists various caliberation code and filters for getting an accurate orientation from MPU9250\nThis repo mostly concentrates on the problem of connecting IMU(MPU9250) to raspberry pi through I2C communication. \n# Pre-requisites\nSome of the requirements are to enable I2C in rpi. \nInstalling I2C tools and smbus\n```bash\nsudo apt-get install i2c-tools\nsudo pip install smbus\n```\nConnect the MPU9250 with rpi using the below connections  \n|Rpi pin | MPU9250 pins|\n|--------|----------|\n| pin 3 -\u003e| SDA pin|\n| pin 5 -\u003e| SCL pin|\n| pin 6 -\u003e| Ground(GND)|\n| pin 1 -\u003e| VCC|\n\nAfter you have made the connections, type the following command - \n```bash\nsudo i2cdetect -y 1\n```\nIf you see 68 in the output, then that means the sensor is connected to the rpi and 68 is the address of the sensor. \n\n# Basic Usage\nThe below code is a basic starter for the library\n```python\nimport os\nimport sys\nimport time\nimport smbus\n\nfrom imusensor.MPU9250 import MPU9250\n\naddress = 0x68\nbus = smbus.SMBus(1)\nimu = MPU9250.MPU9250(bus, address)\nimu.begin()\n# imu.caliberateGyro()\n# imu.caliberateAccelerometer()\n# or load your own caliberation file\n#imu.loadCalibDataFromFile(\"/home/pi/calib_real_bolder.json\")\n\nwhile True:\n\timu.readSensor()\n\timu.computeOrientation()\n\n\tprint (\"roll: {0} ; pitch : {1} ; yaw : {2}\".format(imu.roll, imu.pitch, imu.yaw))\n\ttime.sleep(0.1)\n\n```\n# Other Functionalities\n\n## Setting Accelerometer Range\nThe accelerometer in MPU9250 has the following ranges of +-2g, +-4g, +-8g and +-16g  \nYou can set this setting by the below command\n```python\nimu.setAccelRange(\"AccelRangeSelect2G\")\n```\nSimiarly for 4g use \"AccelRangeSelect4G\" and follow similary for 8g and 16g ranges.\n\n## Setting Gyroscope Range\nGyroscope sensor in MPU9250 has the following ranges +-250DPS, +-500DPS, +-1000DPS and +-2000DPS  \nYou can set this setting by the below command\n```python\nimu.setGyroRange(\"GyroRangeSelect250DPS\")\n```\nSimiarly for 500DPS use \"GyroRangeSelect500DPS\" and follow similary for 1000DPS and 2000DPS ranges.  \n**Note:** DPS means degrees per second\n\n## Setting internal low pass filter frequency\nThe sensor has an internal low pass filter to remove some basic noise in the values generated by accelerometer and gyrscope.  \nUse the following command \n```python\nimu.setLowPassFilterFrequency(\"AccelLowPassFilter184\")\n```\n|frequency | str |\n|---------|-----|\n| 5Hz| AccelLowPassFilter5|\n| 10Hz| AccelLowPassFilter10|\n| 20Hz| AccelLowPassFilter20|\n| 41Hz| AccelLowPassFilter41|\n| 92Hz| AccelLowPassFilter92|\n| 184Hz| AccelLowPassFilter184|\n\n## Gyroscope Caliberation\nThough most sensors are caliberated during manufacturing, however, there still could be a need for caliberation due to various cahnges like being soldered to a breakout board. Gyroscope normally comes with a bias. This can be found by averaging the values when it is kept still and then subtract those values to get the appropriate values.\n```python\nimu.caliberateGyro()\n```\nThis will calculate the bias and it is stored in ```imu.GyroBias```\nYou can also set its value, but make sure you give 3x1 numpy array.\n\n## Accelerometer Caliberation\nThis caliberation includes an extra parameter called scale apart from bias. Use the below command\n```python\nimu.caliberateAccelerometer()\n```\nThe above function will store the scale and bias in the following variables ```imu.Accels``` and ```imu.AccelBias``` respectively.\n\n## Magnometer Caliberation\nThis has two types of caliberation \n* ```imu.caliberateMagApprox()``` : As the name suggests, this is a near approximation of scale and bias parameters. It saves time however, might not be always accurate. In this the scale and bias are stored in ```imu.Mags``` and ```imu.MagBias``` respectively.\n* ```imu.caliberateMagPrecise()``` : It tries to fit the data to an ellipsoid and is more complicated and time consuming. It gives a 3x3 symmetric transformation matrix(```imu.Magtransform```) instead of a common 3x1 scale values. The bias variable is ```imu.MagBias```  \nFor more details on this, have a look at mag_caliberation folder in examples. \n## IMU Orientation\nThe computed orientation is in terms of eurler angles. roll for x axis, pitch for y axis and yaw for z axis. We use NED format which basically means, the sensor's x-axis is aligned with north, sensor's y-axis is aligned with east and sensor's x-axis is aligned with down. \n```imu.computeOrientation()```\nThe roll, pitch and yaw can be accessed by ```imu.roll```, ```imu.pitch``` and ```imu.yaw```.\n**Note:** The euler angles will only make sense when all the sensors are properly caliberated.\n\n# Filters for sensorfusion\nOrientation from accelerometer and magnetometer are noisy, while estimating orientation from gyroscope is noise free but accumulates drift over time. We will combining both of these to obtain more stable orientation. There are multiple ways to do it and we have given two options of kalman and madgwick. You are free to write your own algorithms. \n\n## Kalman\nIt uses gyroscope to estimate the new state. Accelerometer and magnetometer provide the new measured state. The kalman filter aims to find a corrected state from the above two by assuming that both are forms of gaussian distributions.\nlook at kalmanExample.py in examples\n```python\nimport os\nimport sys\nimport time\nimport smbus\nimport numpy as np\n\nfrom imusensor.MPU9250 import MPU9250\nfrom imusensor.filters import kalman \n\naddress = 0x68\nbus = smbus.SMBus(1)\nimu = MPU9250.MPU9250(bus, address)\nimu.begin()\n# imu.caliberateAccelerometer()\n# print (\"Acceleration calib successful\")\n# imu.caliberateMag()\n# print (\"Mag calib successful\")\n# or load your caliberation file\n# imu.loadCalibDataFromFile(\"/home/pi/calib_real_bolder.json\")\n\nsensorfusion = kalman.Kalman()\n\nimu.readSensor()\nimu.computeOrientation()\nsensorfusion.roll = imu.roll\nsensorfusion.pitch = imu.pitch\nsensorfusion.yaw = imu.yaw\n\ncount = 0\ncurrTime = time.time()\nwhile True:\n\timu.readSensor()\n\timu.computeOrientation()\n\tnewTime = time.time()\n\tdt = newTime - currTime\n\tcurrTime = newTime\n\n\tsensorfusion.computeAndUpdateRollPitchYaw(imu.AccelVals[0], imu.AccelVals[1], imu.AccelVals[2], imu.GyroVals[0], imu.GyroVals[1], imu.GyroVals[2],\\\n\t\t\t\t\t\t\t\t\t\t\t\timu.MagVals[0], imu.MagVals[1], imu.MagVals[2], dt)\n\n\tprint(\"Kalmanroll:{0} KalmanPitch:{1} KalmanYaw:{2} \".format(sensorfusion.roll, sensorfusion.pitch, sensorfusion.yaw))\n\n\ttime.sleep(0.01)\n\n```\n\n## Madgwick\nThis is slightly better than kalman and more smooth in giving out the orientation. However, for this to work properly, the sensor fusion needs to run at least 10 times faster frequency than the sensor sampling frequency. \nlook at madgwickExample.py in examples\n```python\nimport os\nimport sys\nimport time\nimport smbus\n\n\nfrom imusensor.MPU9250 import MPU9250\nfrom imusensor.filters import madgwick\n\nsensorfusion = madgwick.Madgwick(0.5)\n\naddress = 0x68\nbus = smbus.SMBus(1)\nimu = MPU9250.MPU9250(bus, address)\nimu.begin()\n\n# imu.caliberateGyro()\n# imu.caliberateAccelerometer()\n# or load your own caliberation file\n#imu.loadCalibDataFromFile(\"/home/pi/calib_real4.json\")\n\ncurrTime = time.time()\nprint_count = 0\nwhile True:\n\timu.readSensor()\n\tfor i in range(10):\n\t\tnewTime = time.time()\n\t\tdt = newTime - currTime\n\t\tcurrTime = newTime\n\n\t\tsensorfusion.updateRollPitchYaw(imu.AccelVals[0], imu.AccelVals[1], imu.AccelVals[2], imu.GyroVals[0], \\\n\t\t\t\t\t\t\t\t\timu.GyroVals[1], imu.GyroVals[2], imu.MagVals[0], imu.MagVals[1], imu.MagVals[2], dt)\n\n\tif print_count == 2:\n\t\tprint (\"mad roll: {0} ; mad pitch : {1} ; mad yaw : {2}\".format(sensorfusion.roll, sensorfusion.pitch, sensorfusion.yaw))\n\t\tprint_count = 0\n\n\tprint_count = print_count + 1\n\ttime.sleep(0.01)\n```\nFor the detailed explanation -\u003e [link](https://www.x-io.co.uk/res/doc/madgwick_internal_report.pdf)\n\n## Filter comparison\nWe have also done a small filter comparison of all the filters. This data can be streamed to your computer using zmq and also you can visualize the imu orientation using pygame_viz.py in examples/filters_comparison. \n\n# Acknowledgments\nMost of the documentation for interfacing MPU9250 with arduino is present. Our work has been inspired by the following works.  \n\n1) [bolderflight/MPU9250](https://github.com/bolderflight/MPU9250): This is a nice library for interfacing MPU9250 with arduino. \n2) [kriswiner/MPU9250](https://github.com/kriswiner/MPU9250): This is a library for getting some accurate orientation from MPU9250. The author has answered a lot of questions in the issues and most of them are very enlightening for anybody working with IMUs. Highly recommend it.\n3) [TKJElectronics/KalmanFilter ](https://github.com/TKJElectronics/KalmanFilter): This is an implementation of second order kalman filter for IMU when using with arduino. \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniru-5%2Fimusensor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fniru-5%2Fimusensor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniru-5%2Fimusensor/lists"}