{"id":13802528,"url":"https://github.com/OneMadGypsy/upy-motion","last_synced_at":"2025-05-13T13:31:45.410Z","repository":{"id":112922926,"uuid":"375186076","full_name":"OneMadGypsy/upy-motion","owner":"OneMadGypsy","description":"A simple MPU6050 driver written in micropython","archived":false,"fork":false,"pushed_at":"2021-06-24T16:07:59.000Z","size":403,"stargazers_count":14,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-22T12:36:29.697Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/OneMadGypsy.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-06-09T01:04:19.000Z","updated_at":"2024-03-16T07:00:51.000Z","dependencies_parsed_at":"2023-03-23T23:47:44.480Z","dependency_job_id":null,"html_url":"https://github.com/OneMadGypsy/upy-motion","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OneMadGypsy%2Fupy-motion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OneMadGypsy%2Fupy-motion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OneMadGypsy%2Fupy-motion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OneMadGypsy%2Fupy-motion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OneMadGypsy","download_url":"https://codeload.github.com/OneMadGypsy/upy-motion/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253950121,"owners_count":21989307,"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":[],"created_at":"2024-08-04T00:01:46.576Z","updated_at":"2025-05-13T13:31:45.152Z","avatar_url":"https://github.com/OneMadGypsy.png","language":"Python","readme":"# upy-motion\n\n\nAn MPU6050 driver written in micropython. This driver should be compatible with any micropython device. This driver does not support quaternion\n\n### Features:\n\n1) Auto-calibration if the `ofs` argument is omitted\n2) After auto-calibration the `ofs` argument is supplied to you\n3) Automatic FIFO if an interrupt pin and callback are supplied\n4) Kalman and complimentary filters are built in and automatically applied to data based on flags you set\n5) Data can be retrieved as raw gyroscope and accelerometer data or as angles (roll, pitch only)\n6) Temperature can be retrieved as Celsius or Fahrenheit\n7) Numerous print options available that format the data into a very neat and easy-to-read display\n8) Self-test is built in and using just one property will tell you if your device is functioning properly\n9) Everything you can do is well-documented below\n\n\n### Community:\n\n_To officially file a bug report or feature request you can use these templates:_   [bug report](https://github.com/OneMadGypsy/upy-motion/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) | [feature request](https://github.com/OneMadGypsy/upy-motion/blob/main/.github/ISSUE_TEMPLATE/feature_request.md)\n\n_To discus features, bugs or share your own project that utilize code in this repo:_   [join the discussion](https://github.com/OneMadGypsy/upy-motion/discussions/1)\n\n\u003cbr /\u003e\n\n-------\n\n\u003cbr /\u003e\n\n## Ports:\n\n### MPU6050.py\n\u003eThis can be uploaded directly to the board, but is intended to be used as a frozen module. For information regarding how to setup the sdk and freeze a module you can refer to [this post](https://www.raspberrypi.org/forums/viewtopic.php?f=146\u0026t=306449#p1862108) on the Raspberry Pi forum.\n\n\n### MPU6050.mpy\n\u003eThis is a cross-compiled version of `MPU6050.py`. It is intended to be uploaded to your board as you would any normal `.py` script.\n\n\n\u003cbr /\u003e\n\n-------\n\n\u003cbr /\u003e\n\n## Docs:\n\n\n**MPU6050(`bus`, `sda`, `scl`, `ofs`, `intr`, `callback`, `angles`, `clock`, `gyro`, `accel`, `dlpf`, `rate`, `filtered`, `anglefilter`, `R`, `Q`, `A`, `addr`, `freq`)**\n\n\u003eThe argument for this constructor may seem daunting, but it can be broken up into sections that make it far easier to manage. From `bus` through `scl` sets up I2C connection with the device. `ofs` is the configuration offsets that help your device function accurately. Examples are provided later in this document that explain how to get this value. From `intr` through `angles` are interrupt related and only used if you want to use FIFO. From `clock` through `rate` are device specific settings. From `filtered` through `A` are filter specific settings. `addr` and `freq` are the device address and the frequency it should run at. There is very little reason why you should ever have to change these, which is why they are the very last arguments.\n\n\n\u003eMost things are evidenced later in this document, but there are a couple of things that are easier to simply explain right here. Providing an interrupt pin and a callback will automatically trigger the script to use FIFO. The `rate` argument has 2 purposes. Whatever value you supply will be the divisor for gyroscope clock output, which is it's main intended purpose. However, my driver also uses half of this number to determine how many samples to average when using a complementary filter.\n\n\nArg             | Type       | Description                                    | Default\n----------------|------------|------------------------------------------------|-------------\n**bus**         | int        | I2C bus id                                     | **REQUIRED**  \n**sda**         | int or Pin | data pin                                       | **REQUIRED**\n**scl**         | int or Pin | clock pin                                      | **REQUIRED**\n**ofs**         | tuple      | axis offsets                                   | None\n**intr**        | int or Pin | interrupt pin (FIFO only)                      | None\n**callback**    | function   | function to call on interrupt (FIFO only)      | None\n**angles**      | int        | return `angles` instead of `data` (FIFO only)  | False\n**clock**       | int        | clock source to use                            | CLK_PLL_XGYRO\n**gyro**        | int        | gyroscope full scale range                     | GYRO_FS_500\n**accel**       | int        | accelerometer full scale range                 | ACCEL_FS_2\n**dlpf**        | int        | digital low-pass filter                        | DLPF_BW_188\n**rate**        | int        | sample rate                                    | 4\n**filtered**    | int        | which properties to filter                     | NONE\n**anglefilter** | int        | which filters to apply to angles               | NONE\n**R**           | float      | Kalman filter measure                          | 0.003\n**Q**           | float      | Kalman filter bias                             | 0.001\n**A**           | float      | complementary filter alpha                     | .8\n**addr**        | int        | device I2C address                             | 0x68\n**freq**        | int        | I2C frequency                                  | 400000\n\n\u003cbr /\u003e\n\n-------\n\n\u003cbr /\u003e\n\n## Constants:\n\n\u003cbr /\u003e\n\n#### clock\n\u003ePossible values for the `clock` constructor argument are the following. The default clock is `CLK_PLL_XGYRO`. The documents recommend that you use one of the gyro clocks. All clocks (except external) have their typical frequency listed. Actual frequency may vary +/- 3 Khz.\n\n Const            | Value | Frequency\n------------------|-------|--------\n**CLK_INTERNAL**  | 0x00  | 8 Mhz\n**CLK_PLL_XGYRO** | 0x01  | 33 Khz\n**CLK_PLL_YGYRO** | 0x02  | 30 Khz\n**CLK_PLL_ZGYRO** | 0x03  | 27 Khz\n**CLK_PLL_EXT32K**| 0x04  | 32.768 Khz\n**CLK_PLL_EXT19M**| 0x05  | 19.2 Mhz\n**CLK_KEEP_RESET**| 0x07  | 0\n\n\u003cbr /\u003e\n\n#### gyro\n\u003ePossible values for the `gyro` constructor argument are the following. The default gyro is `GYRO_FS_500`.\n\n Const          | Value \n----------------|-------\n**GYRO_FS_250** | 0x00  \n**GYRO_FS_500** | 0x01  \n**GYRO_FS_1000**| 0x02  \n**GYRO_FS_2000**| 0x03  \n\n\u003cbr /\u003e\n\n#### accel\n\u003ePossible values for the `accel` constructor argument are the following. The default accel is `ACCEL_FS_2`\n\n Const          | Value\n----------------|-------\n**ACCEL_FS_2**  | 0x00\n**ACCEL_FS_4**  | 0x01\n**ACCEL_FS_8**  | 0x02\n**ACCEL_FS_16** | 0x03\n\n\u003cbr /\u003e\n\n#### dlpf\n\u003ePossible values for the `dlpf` constructor argument include the following. The default dlpf is `DLPF_BW_188`. Headers marked **ms** below represent the milliseconds of delay a DLPF will create.\n\nConst           | Value | Accel(ms) | Gyro(ms) | FS (Khz)\n----------------|-------|-----------|----------|---------\n**DLPF_BW_256** | 0x00  | 0         |  0.98    | 8\n**DLPF_BW_188** | 0x01  | 2.0       |  1.9     | 1\n**DLPF_BW_98**  | 0x02  | 3.0       |  2.8     | 1\n**DLPF_BW_42**  | 0x03  | 4.9       |  4.8     | 1\n**DLPF_BW_20**  | 0x04  | 8.5       |  8.3     | 1\n**DLPF_BW_10**  | 0x05  | 13.8      | 13.4     | 1\n**DLPF_BW_5**   | 0x06  | 19.0      | 18.6     | 1\n\n\u003cbr /\u003e\n\n#### filtered\n\u003ePossible values for the `filtered` constructor argument include the following. The default filter is `NONE`. Applying one or more of these flags tells the driver which data to filter. For accel and gyro Kalman filters will be applied. For angles another flag must be used to determine which filters you want applied.\n\nFlag             | Value\n-----------------|-------\n**NONE**         | 0x00\n**FILTER_ACCEL** | 0x01\n**FILTER_GYRO**  | 0x02\n**FILTER_ANGLES**| 0x04\n**FILTER_ALL**   | 0x07\n\n\u003cbr /\u003e\n\n#### anglefilter\n\u003ePossible values for the `anglefilter` constructor argument include the following. The default anglefilter is `NONE`. \n\nFlag             | Value\n-----------------|-------\n**NONE**         | 0x00\n**ANGLE_KAL**    | 0x01\n**ANGLE_COMP**   | 0x02\n**ANGLE_BOTH**   | 0x03\n\n\u003cbr /\u003e\n\n-----------------\n\n\u003cbr /\u003e\n\n### Properties:\n\n\u003cbr /\u003e\n\n**.device_id**\n\u003eThe id of the device\n\n\u003cbr /\u003e\n\n**.connected**\n\u003eTrue or False device is connected\n\n\u003cbr /\u003e\n\n**.data**\n\u003eReturns gyroscope and accelerometer data. This data may be filtered with a Kalman filter if the appropriate flag is supplied to the `filtered` argument in the constructor. The [filters](https://github.com/OneMadGypsy/upy-motion/blob/main/README.md#filters) section contains more information on how to use filters. This is a `namedtuple` with the following fields\n\nField       | Type  |  Description\n------------|-------|-----------------\n**.acc_x**  | float | accelerometer x\n**.acc_y**  | float | accelerometer y\n**.acc_z**  | float | accelerometer z\n**.gyro_x** | float | gyroscope x\n**.gyro_y** | float | gyroscope y\n**.gyro_z** | float | gyroscope z\n\n\u003cbr /\u003e\n\n**.angles**\n\u003eReturns angles concocted from accelerometer data. These angles may be filtered (with Kalman, complementar or both) according to the flag supplied for the `anglefilter` argument in the constructor. The [filters](https://github.com/OneMadGypsy/upy-motion/blob/main/README.md#filters) section contains more information on how to use filters. This is a `namedtuple` with the following fields\n\nField       | Type  |  Description\n------------|-------|-----------------\n**.roll**   | float | roll angle\n**.pitch**  | float | pitch angle\n\n\u003cbr /\u003e\n\n**.int_angles**\n\u003eReturns angles concocted from accelerometer data as _ints_. These angles may be filtered (with Kalman, complementar or both) according to the flag supplied for the `anglefilter` argument in the constructor. The [filters](https://github.com/OneMadGypsy/upy-motion/blob/main/README.md#filters) section contains more information on how to use filters. This is a `namedtuple` with the following fields\n\nField       | Type  |  Description\n------------|-------|-----------------\n**.roll**   | int   | roll angle\n**.pitch**  | int   | pitch angle\n\n\u003cbr /\u003e\n\n**.passed_self_test**\n\u003eTrue or False passed system self-test\n\n\u003cbr /\u003e\n\n**.celsius**\n\u003eReturns the temperature in Celsius\n\n\u003cbr /\u003e\n\n**.fahrenheit**\n\u003eReturns the temperature in Fahrenheit\n\n\u003cbr /\u003e\n\n-----------------\n\n\u003cbr /\u003e\n\n### Methods:\n\n\u003cbr /\u003e\n\n**.start()**\n\u003eIf an interrupt pin and callback were supplied to the constructor, this will start FIFO interrupts\n\n\u003cbr /\u003e\n\n**.stop()**\n\u003eIf an interrupt pin and callback were supplied to the constructor, this will stop FIFO interrupts\n\n\u003cbr /\u003e\n\n**.print_data()**\n\u003ePrints the gyroscope and accelerometer data with any flagged filters automatically applied. The [filters](https://github.com/OneMadGypsy/upy-motion/blob/main/README.md#filters) section contains more information on how to use filters.\n\n\u003cbr /\u003e\n\n**.print_from_data(`data:tuple`)**\n\u003ePrints the gyroscope and accelerometer data that was passed to it\n\n\u003cbr /\u003e\n\n**.print_angles(`asint:bool=False`)**\n\u003ePrints the roll and pitch angles with any flagged filters automatically applied. If `asint` is `True` angles will be gathered from `.int_angles`. The [filters](https://github.com/OneMadGypsy/upy-motion/blob/main/README.md#filters) section contains more information on how to use filters.\n\n\u003cbr /\u003e\n\n**.print_from_angles(`angles:tuple`)**\n\u003ePrints the angle data that was passed to it\n\n\u003cbr /\u003e\n\n**.print_celsius()**\n\u003ePrints the temperature in Celsius\n\n\u003cbr /\u003e\n\n**.print_fahrenheit()**\n\u003ePrints the temperature in Fahrenheit\n\n\u003cbr /\u003e\n\n**.print_offsets()**\n\u003ePrints the offsets as a line of code to be used as the `ofs` argument when instantiating `MPU6050`\n\n\u003cbr /\u003e\n\n**.print_all()**\n\u003ePrints everything except offsets\n\n\u003cbr /\u003e\n\n-------\n\n\u003cbr /\u003e\n\n## Usage\n\nAll the below examples can be copy/pasted, but you must make sure to provide the `bus`, `sda` and `scl` pins (or pin numbers) that apply to your wiring scheme. If an interrupt pin or calibration offsets are used in an example, those too must be replaced with the data that applies to you.\n\n\u003cbr /\u003e\n\n#### calibration\n\n\u003eThe very first thing you should do is calibrate the device. When it completes it will print a small line of code that you need to copy and paste for use with the `ofs` argument. Failure to provide an `ofs` argument will result in your device auto-calibrating every time you instance it. Make sure your device is as flat and level as you can get it before running calibration. Only run calibration from a fresh power-up of the device. If you do a good job calibrating, the numbers this returns can be used constantly, and you should not need to calibrate again unless you customize any of the device configuration arguments (ie. `clock`, `dlpf`, `rate`, `gyro` or `accel`). If you do intend to change any of the configuration arguments, you should add those changes to the script below before running it.\n\n```python\nfrom mpu6050 import MPU6050\n\nMPU6050(1, 6, 7)\n```\n\u003cbr /\u003e\n\n#### FIFO\n\n\u003eSupplying an interrupt pin and a callback will trigger the driver to use FIFO automatically. You must also call `start()` for interrupts to begin. The `data` argument in the handler will contain all of the accelerometer and gyroscope data, unless you set the `angles` constructor argument to `True`, in which case `data` will then contain angles values. \n\n```python\nfrom mpu6050 import MPU6050\n\ndef handler(data:tuple):\n    if 'mpu' in globals():\n        print('[{:\u003c16}] {:\u003c10.2f}'.format('TEMPERATURE', mpu.fahrenheit))\n        mpu.print_from_data(data)\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51), 2, handler)\nif mpu.passed_self_test:\n    mpu.start()\n```\n\n\u003cbr /\u003e\n\n#### polling\n\n\u003eIf an interrupt pin and callback are not supplied the driver assumes you want to manage your own polling\n\n```python\nfrom mpu6050 import MPU6050\nimport utime\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51))\n\nif mpu.passed_self_test:\n    while True:\n        print('[{:\u003c16}] {:\u003c10.2f}'.format('TEMPERATURE', mpu.fahrenheit))\n        mpu.print_data()\n        utime.sleep_ms(100)\n```\n\n\u003cbr /\u003e\n\n#### accessing data\n\n\u003edata is a `namedtuple` and can be used like any other `namedtuple`. You can either unpack the properties or use them directly. The below examples illustrate both of these methods.\n\n```python\nfrom mpu6050 import MPU6050\nimport utime\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51))\n\nif mpu.passed_self_test:\n    while True:\n        ax, ay, az, gx, gy, gz = mpu.data\n```\n\n\n_or_\n\n\n```python\nfrom mpu6050 import MPU6050\n\ndef handler(data:tuple):\n    if 'mpu' in globals():\n        asum = data.acc_x  + data.acc_y  + data.acc_z\n        gsum = data.gyro_x + data.gyro_y + data.gyro_z\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51), 2, handler)\nif mpu.passed_self_test:\n    mpu.start()\n```\n\n\u003cbr /\u003e\n\n#### angles\n\n\u003e`angles` are handled no different than `data`\n\n```python\nfrom mpu6050 import MPU6050\n\ndef handler(data:tuple):\n    if 'mpu' in globals():\n        roll, pitch = mpu.angles\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51), 2, handler)\nif mpu.passed_self_test:\n    mpu.start()\n```\n\n\n_just like `data`, `angles` has its own print method, as well_\n\n\n```python\nfrom mpu6050 import MPU6050\nimport utime\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51))\n\nif mpu.passed_self_test:\n    while True:\n        mpu.print_angles()\n        utime.sleep_ms(100)\n```\n\n_when using fifo you can tell the script to send `angles` instead of axis `data` to the handler callback by setting the `angles` constructor argument to `True`_\n\n\n```python\nfrom mpu6050 import MPU6050\n\ndef handler(data:tuple):\n    if 'mpu' in globals():\n        roll, pitch = data\n        mpu.print_from_angles(data)\n\nmpu = MPU6050(1, 6, 7, (1314, -1629, 410, 28, -17, 51), 2, handler, True)\nif mpu.passed_self_test:\n    mpu.start()\n\n```\n\n\u003cbr /\u003e\n\n#### filters\n\n\u003eThis driver supports 2 different types of filters (Kalman and complementary). Complementary filters can only be applied to angles. If a complementary filter is flagged on angles it will return the average of all the samples taken. The amount of samples that are taken will be half of the `rate` argument that was supplied to the constructor.\n\n\n```python\nfrom mpu6050 import MPU6050, FILTER_GYRO, FILTER_ANGLES, ANGLE_COMP\n\ndef handler(data:tuple):\n    if 'mpu' in globals():\n        mpu.print_from_angles(data)\n        \ncfg = dict(\n    rate        = 20,                          #MPU6050_SPLRTDIV ~ comp filter samples at half of this number\n    filtered    = FILTER_GYRO | FILTER_ANGLES, #wont filter accelerometer raw readings\n    anglefilter = ANGLE_COMP,                  #apply only complementary filter to angles\n    angles      = True                         #send data to handler as angles\n)\nmpu = MPU6050(1, 6, 7, (1368, -1684, 416, 20, -6, 49), 2, handler, **cfg)\n\nif mpu.passed_self_test:\n    mpu.start()\n\n```\n","funding_links":[],"categories":["Libraries"],"sub_categories":["Sensors"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOneMadGypsy%2Fupy-motion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOneMadGypsy%2Fupy-motion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOneMadGypsy%2Fupy-motion/lists"}