Skip to content

Initial commit #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2017 Radomir Dopieralski for Adafruit Industries
Copyright (c) 2017 Radomir Dopieralski, written for Adafruit Industries

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
56 changes: 44 additions & 12 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,32 +1,63 @@

Introduction
============

.. image:: https://readthedocs.org/projects/adafruit-circuitpython-bno055/badge/?version=latest
:target: https://circuitpython.readthedocs.io/projects/bno055/en/latest/
:alt: Documentation Status

.. image :: https://badges.gitter.im/adafruit/circuitpython.svg
.. image:: https://badges.gitter.im/adafruit/circuitpython.svg
:target: https://gitter.im/adafruit/circuitpython?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
:alt: Gitter

TODO

Dependencies
=============
This driver depends on:

* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
This driver depends on the `Register
<https://github.com/adafruit/Adafruit_CircuitPython_Register>`_ and `Bus Device
<https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_ libraries.
Please ensure they are also available on the CircuitPython filesystem. This is
easily achieved by downloading `a library and driver bundle
<https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.

Please ensure all dependencies are available on the CircuitPython filesystem.
This is easily achieved by downloading
`the Adafruit library and driver bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.
Usage Notes
===========

Usage Example
=============
Of course, you must import the library to use it:

.. code:: python

import adafruit_bno055


This driver takes an instantiated and active I2C object (from the `nativeio` or
the `bitbangio` library) as an argument to its constructor. The way to create
an I2C object depends on the board you are using. For boards with labeled SCL
and SDA pins, you can:

.. code:: python

from nativeio import I2C
#from bitbangio import I2C
from board import SDA, SCL

i2c = I2C(SCL, SDA)

Once you have the I2C object, you can create the sensor object:

.. code:: python

sensor = adafruit_bno055.BNO055(i2c)


And then you can start reading the measurements:

.. code:: python

print(sensor.temperature)
print(sensor.euler)
print(sensor.gravity)

TODO

Contributing
============
Expand All @@ -35,6 +66,7 @@ Contributions are welcome! Please read our `Code of Conduct
<https://github.com/adafruit/Adafruit_CircuitPython_bno055/blob/master/CODE_OF_CONDUCT.md>`_
before contributing to help this project stay welcoming.


API Reference
=============

Expand Down
182 changes: 178 additions & 4 deletions adafruit_bno055.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The MIT License (MIT)
#
# Copyright (c) 2017 Radomir Dopieralski for Adafruit Industries
# Copyright (c) 2017 Radomir Dopieralski for Adafruit Industries.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -19,11 +19,185 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.


"""
`adafruit_bno055`
====================================================
``adafruit_bno055``
===================

TODO(description)
This is a CircuitPython driver for the Bosch BNO055 nine degree of freedom
inertial measurement unit module with sensor fusion.

* Author(s): Radomir Dopieralski
"""

from micropython import const
from adafruit_bus_device.i2c_device import I2CDevice
from adafruit_register.i2c_struct import Struct, UnaryStruct
import time


_CHIP_ID = const(0xa0)

CONFIG_MODE = const(0x00)
ACCONLY_MODE = const(0x01)
MAGONLY_MODE = const(0x02)
GYRONLY_MODE = const(0x03)
ACCMAG_MODE = const(0x04)
ACCGYRO_MODE = const(0x05)
MAGGYRO_MODE = const(0x06)
AMG_MODE = const(0x07)
IMUPLUS_MODE = const(0x08)
COMPASS_MODE = const(0x09)
M4G_MODE = const(0x0a)
NDOF_FMC_OFF_MODE = const(0x0b)
NDOF_MODE = const(0x0c)

_POWER_NORMAL = const(0x00)
_POWER_LOW = const(0x01)
_POWER_SUSPEND = const(0x02)

_MODE_REGISTER = const(0x3d)
_PAGE_REGISTER = const(0x07)
_TRIGGER_REGISTER = const(0x3f)
_POWER_REGISTER = const(0x3e)
_ID_REGISTER = const(0x00)


class _ScaledReadOnlyStruct(Struct):
def __init__(self, register_address, struct_format, scale):
super(_ScaledReadOnlyStruct, self).__init__(
register_address, struct_format)
self.scale = scale

def __get__(self, obj, objtype=None):
result = super(_ScaledReadOnlyStruct, self).__get__(obj, objtype)
return tuple(self.scale * v for v in result)

def __set__(self, obj, value):
raise NotImplementedError()


class _ReadOnlyUnaryStruct(UnaryStruct):
def __set__(self, obj, value):
raise NotImplementedError()


class BNO055:
"""
Driver for the BNO055 9DOF IMU sensor.
"""

temperature = _ReadOnlyUnaryStruct(0x34, 'B')
"""Measures the temperature of the chip in degrees Celsius."""
accelerometer = _ScaledReadOnlyStruct(0x08, '<hhh', 1/100)
"""Gives the raw accelerometer readings, in m/s."""
magnetometer = _ScaledReadOnlyStruct(0x0e, '<hhh', 1/16)
"""Gives the raw magnetometer readings in microteslas."""
gyroscope = _ScaledReadOnlyStruct(0x14, '<hhh', 1/900)
"""Gives the raw gyroscope reading in degrees per second."""
euler = _ScaledReadOnlyStruct(0x1a, '<hhh', 1/16)
"""Gives the calculated orientation angles, in degrees."""
quaternion = _ScaledReadOnlyStruct(0x20, '<hhhh', 1/(1<<14))
"""Gives the calculated orientation as a quaternion."""
linear_acceleration = _ScaledReadOnlyStruct(0x28, '<hhh', 1/100)
"""Returns the linear acceleration, without gravity, in m/s."""
gravity = _ScaledReadOnlyStruct(0x2e, '<hhh', 1/100)
"""Returns the gravity vector, without acceleration in m/s."""

def __init__(self, i2c, address=0x28):
self.i2c_device = I2CDevice(i2c, address)
self.buffer = bytearray(2)
self.init()

def _write_register(self, register, value):
self.buffer[0] = register
self.buffer[1] = value
with self.i2c_device as i2c:
i2c.writeto(self.buffer)

def _read_register(self, register):
self.buffer[0] = register
with self.i2c_device as i2c:
i2c.writeto(self.buffer, end=1, stop=False)
i2c.readfrom_into(self.buffer, start=1)
return self.buffer[1]

def switch_mode(self, mode):
"""
Switch the mode of operation and return the previous mode.

Mode of operation defines which sensors are enabled and whether the
measurements are absolute or relative:

+------------------+-------+---------+------+----------+
| Mode | Accel | Compass | Gyro | Absolute |
+==================+=======+=========+======+==========+
| CONFIG_MODE | - | - | - | - |
+------------------+-------+---------+------+----------+
| ACCONLY_MODE | X | - | - | - |
+------------------+-------+---------+------+----------+
| MAGONLY_MODE | - | X | - | - |
+------------------+-------+---------+------+----------+
| GYRONLY_MODE | - | - | X | - |
+------------------+-------+---------+------+----------+
| ACCMAG_MODE | X | X | - | - |
+------------------+-------+---------+------+----------+
| ACCGYRO_MODE | X | - | X | - |
+------------------+-------+---------+------+----------+
| MAGGYRO_MODE | - | X | X | - |
+------------------+-------+---------+------+----------+
| AMG_MODE | X | X | X | - |
+------------------+-------+---------+------+----------+
| IMUPLUS_MODE | X | - | X | - |
+------------------+-------+---------+------+----------+
| COMPASS_MODE | X | X | - | X |
+------------------+-------+---------+------+----------+
| M4G_MODE | X | X | - | - |
+------------------+-------+---------+------+----------+
| NDOF_FMC_OFF_MODE| X | X | X | X |
+------------------+-------+---------+------+----------+
| NDOF_MODE | X | X | X | X |
+------------------+-------+---------+------+----------+

The default mode is ``NDOF_MODE``.
"""
last_mode = self._read_register(_MODE_REGISTER)
self._write_register(_MODE_REGISTER, mode)
return last_mode

def init(self, mode=NDOF_MODE):
chip_id = self._read_register(_ID_REGISTER)
if chip_id != _CHIP_ID:
raise RuntimeError("bad chip id (%x != %x)" % (chip_id, _CHIP_ID))
self.reset()
self._write_register(_POWER_REGISTER, _POWER_NORMAL)
self._write_register(_PAGE_REGISTER, 0x00)
self._write_register(_TRIGGER_REGISTER, 0x00)
time.sleep(0.01)
self.switch_mode(mode)
time.sleep(0.01)

def reset(self):
"""Resets the sensor to default settings."""
self.switch_mode(CONFIG_MODE)
try:
self._write_register(_TRIGGER_REGISTER, 0x20)
except OSError: # error due to the chip resetting
pass
while True: # wait for the chip to reset
time.sleep(0.01)
try:
chip_id = self._read_register(_ID_REGISTER)
except OSError:
chip_id = 0
if chip_id == _CHIP_ID:
break

def use_external_crystal(self, value):
"""Switches the use of external crystal on or off."""
last_mode = self.switch_mode(CONFIG_MODE)
self._write_register(_PAGE_REGISTER, 0x00)
self._write_register(_TRIGGER_REGISTER, 0x80 if value else 0x00)
self.switch_mode(last_mode)
time.sleep(0.01)
2 changes: 0 additions & 2 deletions api.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@

.. If you created a package, create one automodule per module in the package.

.. automodule:: adafruit_bno055
:members:
4 changes: 2 additions & 2 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# General information about the project.
project = u'Adafruit BNO055 Library'
copyright = u'2017 Radomir Dopieralski'
author = u'Scott Shawcroft'
author = u'Radomir Dopieralski'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -118,7 +118,7 @@
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'AdafruitBNO055Library.tex', u'Adafruit BNO055 Library Documentation',
u'Phiilip Moyer', 'manual'),
u'Radomir Dopieralski', 'manual'),
]

# -- Options for manual page output ---------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
adafruit-circuitpython-bus-device
adafruit-micropython-register
adafruit-micropython-bus-device>=0.1.1