Skip to content

Commit a705ed3

Browse files
authored
Merge pull request #1 from deshipu/master
Initial commit
2 parents 4d3c77e + 6f58838 commit a705ed3

File tree

6 files changed

+227
-22
lines changed

6 files changed

+227
-22
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2017 Radomir Dopieralski for Adafruit Industries
3+
Copyright (c) 2017 Radomir Dopieralski, written for Adafruit Industries
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.rst

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,63 @@
1-
21
Introduction
32
============
43

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

9-
.. image :: https://badges.gitter.im/adafruit/circuitpython.svg
8+
.. image:: https://badges.gitter.im/adafruit/circuitpython.svg
109
:target: https://gitter.im/adafruit/circuitpython?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
1110
:alt: Gitter
1211

13-
TODO
1412

1513
Dependencies
1614
=============
17-
This driver depends on:
1815

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

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

26-
Usage Example
27-
=============
26+
Of course, you must import the library to use it:
27+
28+
.. code:: python
29+
30+
import adafruit_bno055
31+
32+
33+
This driver takes an instantiated and active I2C object (from the `nativeio` or
34+
the `bitbangio` library) as an argument to its constructor. The way to create
35+
an I2C object depends on the board you are using. For boards with labeled SCL
36+
and SDA pins, you can:
37+
38+
.. code:: python
39+
40+
from nativeio import I2C
41+
#from bitbangio import I2C
42+
from board import SDA, SCL
43+
44+
i2c = I2C(SCL, SDA)
45+
46+
Once you have the I2C object, you can create the sensor object:
47+
48+
.. code:: python
49+
50+
sensor = adafruit_bno055.BNO055(i2c)
51+
52+
53+
And then you can start reading the measurements:
54+
55+
.. code:: python
56+
57+
print(sensor.temperature)
58+
print(sensor.euler)
59+
print(sensor.gravity)
2860
29-
TODO
3061
3162
Contributing
3263
============
@@ -35,6 +66,7 @@ Contributions are welcome! Please read our `Code of Conduct
3566
<https://github.com/adafruit/Adafruit_CircuitPython_bno055/blob/master/CODE_OF_CONDUCT.md>`_
3667
before contributing to help this project stay welcoming.
3768

69+
3870
API Reference
3971
=============
4072

adafruit_bno055.py

Lines changed: 178 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# The MIT License (MIT)
22
#
3-
# Copyright (c) 2017 Radomir Dopieralski for Adafruit Industries
3+
# Copyright (c) 2017 Radomir Dopieralski for Adafruit Industries.
44
#
55
# Permission is hereby granted, free of charge, to any person obtaining a copy
66
# of this software and associated documentation files (the "Software"), to deal
@@ -19,11 +19,185 @@
1919
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
# THE SOFTWARE.
22+
23+
2224
"""
23-
`adafruit_bno055`
24-
====================================================
25+
``adafruit_bno055``
26+
===================
2527
26-
TODO(description)
28+
This is a CircuitPython driver for the Bosch BNO055 nine degree of freedom
29+
inertial measurement unit module with sensor fusion.
2730
2831
* Author(s): Radomir Dopieralski
2932
"""
33+
34+
from micropython import const
35+
from adafruit_bus_device.i2c_device import I2CDevice
36+
from adafruit_register.i2c_struct import Struct, UnaryStruct
37+
import time
38+
39+
40+
_CHIP_ID = const(0xa0)
41+
42+
CONFIG_MODE = const(0x00)
43+
ACCONLY_MODE = const(0x01)
44+
MAGONLY_MODE = const(0x02)
45+
GYRONLY_MODE = const(0x03)
46+
ACCMAG_MODE = const(0x04)
47+
ACCGYRO_MODE = const(0x05)
48+
MAGGYRO_MODE = const(0x06)
49+
AMG_MODE = const(0x07)
50+
IMUPLUS_MODE = const(0x08)
51+
COMPASS_MODE = const(0x09)
52+
M4G_MODE = const(0x0a)
53+
NDOF_FMC_OFF_MODE = const(0x0b)
54+
NDOF_MODE = const(0x0c)
55+
56+
_POWER_NORMAL = const(0x00)
57+
_POWER_LOW = const(0x01)
58+
_POWER_SUSPEND = const(0x02)
59+
60+
_MODE_REGISTER = const(0x3d)
61+
_PAGE_REGISTER = const(0x07)
62+
_TRIGGER_REGISTER = const(0x3f)
63+
_POWER_REGISTER = const(0x3e)
64+
_ID_REGISTER = const(0x00)
65+
66+
67+
class _ScaledReadOnlyStruct(Struct):
68+
def __init__(self, register_address, struct_format, scale):
69+
super(_ScaledReadOnlyStruct, self).__init__(
70+
register_address, struct_format)
71+
self.scale = scale
72+
73+
def __get__(self, obj, objtype=None):
74+
result = super(_ScaledReadOnlyStruct, self).__get__(obj, objtype)
75+
return tuple(self.scale * v for v in result)
76+
77+
def __set__(self, obj, value):
78+
raise NotImplementedError()
79+
80+
81+
class _ReadOnlyUnaryStruct(UnaryStruct):
82+
def __set__(self, obj, value):
83+
raise NotImplementedError()
84+
85+
86+
class BNO055:
87+
"""
88+
Driver for the BNO055 9DOF IMU sensor.
89+
"""
90+
91+
temperature = _ReadOnlyUnaryStruct(0x34, 'B')
92+
"""Measures the temperature of the chip in degrees Celsius."""
93+
accelerometer = _ScaledReadOnlyStruct(0x08, '<hhh', 1/100)
94+
"""Gives the raw accelerometer readings, in m/s."""
95+
magnetometer = _ScaledReadOnlyStruct(0x0e, '<hhh', 1/16)
96+
"""Gives the raw magnetometer readings in microteslas."""
97+
gyroscope = _ScaledReadOnlyStruct(0x14, '<hhh', 1/900)
98+
"""Gives the raw gyroscope reading in degrees per second."""
99+
euler = _ScaledReadOnlyStruct(0x1a, '<hhh', 1/16)
100+
"""Gives the calculated orientation angles, in degrees."""
101+
quaternion = _ScaledReadOnlyStruct(0x20, '<hhhh', 1/(1<<14))
102+
"""Gives the calculated orientation as a quaternion."""
103+
linear_acceleration = _ScaledReadOnlyStruct(0x28, '<hhh', 1/100)
104+
"""Returns the linear acceleration, without gravity, in m/s."""
105+
gravity = _ScaledReadOnlyStruct(0x2e, '<hhh', 1/100)
106+
"""Returns the gravity vector, without acceleration in m/s."""
107+
108+
def __init__(self, i2c, address=0x28):
109+
self.i2c_device = I2CDevice(i2c, address)
110+
self.buffer = bytearray(2)
111+
self.init()
112+
113+
def _write_register(self, register, value):
114+
self.buffer[0] = register
115+
self.buffer[1] = value
116+
with self.i2c_device as i2c:
117+
i2c.writeto(self.buffer)
118+
119+
def _read_register(self, register):
120+
self.buffer[0] = register
121+
with self.i2c_device as i2c:
122+
i2c.writeto(self.buffer, end=1, stop=False)
123+
i2c.readfrom_into(self.buffer, start=1)
124+
return self.buffer[1]
125+
126+
def switch_mode(self, mode):
127+
"""
128+
Switch the mode of operation and return the previous mode.
129+
130+
Mode of operation defines which sensors are enabled and whether the
131+
measurements are absolute or relative:
132+
133+
+------------------+-------+---------+------+----------+
134+
| Mode | Accel | Compass | Gyro | Absolute |
135+
+==================+=======+=========+======+==========+
136+
| CONFIG_MODE | - | - | - | - |
137+
+------------------+-------+---------+------+----------+
138+
| ACCONLY_MODE | X | - | - | - |
139+
+------------------+-------+---------+------+----------+
140+
| MAGONLY_MODE | - | X | - | - |
141+
+------------------+-------+---------+------+----------+
142+
| GYRONLY_MODE | - | - | X | - |
143+
+------------------+-------+---------+------+----------+
144+
| ACCMAG_MODE | X | X | - | - |
145+
+------------------+-------+---------+------+----------+
146+
| ACCGYRO_MODE | X | - | X | - |
147+
+------------------+-------+---------+------+----------+
148+
| MAGGYRO_MODE | - | X | X | - |
149+
+------------------+-------+---------+------+----------+
150+
| AMG_MODE | X | X | X | - |
151+
+------------------+-------+---------+------+----------+
152+
| IMUPLUS_MODE | X | - | X | - |
153+
+------------------+-------+---------+------+----------+
154+
| COMPASS_MODE | X | X | - | X |
155+
+------------------+-------+---------+------+----------+
156+
| M4G_MODE | X | X | - | - |
157+
+------------------+-------+---------+------+----------+
158+
| NDOF_FMC_OFF_MODE| X | X | X | X |
159+
+------------------+-------+---------+------+----------+
160+
| NDOF_MODE | X | X | X | X |
161+
+------------------+-------+---------+------+----------+
162+
163+
The default mode is ``NDOF_MODE``.
164+
"""
165+
last_mode = self._read_register(_MODE_REGISTER)
166+
self._write_register(_MODE_REGISTER, mode)
167+
return last_mode
168+
169+
def init(self, mode=NDOF_MODE):
170+
chip_id = self._read_register(_ID_REGISTER)
171+
if chip_id != _CHIP_ID:
172+
raise RuntimeError("bad chip id (%x != %x)" % (chip_id, _CHIP_ID))
173+
self.reset()
174+
self._write_register(_POWER_REGISTER, _POWER_NORMAL)
175+
self._write_register(_PAGE_REGISTER, 0x00)
176+
self._write_register(_TRIGGER_REGISTER, 0x00)
177+
time.sleep(0.01)
178+
self.switch_mode(mode)
179+
time.sleep(0.01)
180+
181+
def reset(self):
182+
"""Resets the sensor to default settings."""
183+
self.switch_mode(CONFIG_MODE)
184+
try:
185+
self._write_register(_TRIGGER_REGISTER, 0x20)
186+
except OSError: # error due to the chip resetting
187+
pass
188+
while True: # wait for the chip to reset
189+
time.sleep(0.01)
190+
try:
191+
chip_id = self._read_register(_ID_REGISTER)
192+
except OSError:
193+
chip_id = 0
194+
if chip_id == _CHIP_ID:
195+
break
196+
197+
def use_external_crystal(self, value):
198+
"""Switches the use of external crystal on or off."""
199+
last_mode = self.switch_mode(CONFIG_MODE)
200+
self._write_register(_PAGE_REGISTER, 0x00)
201+
self._write_register(_TRIGGER_REGISTER, 0x80 if value else 0x00)
202+
self.switch_mode(last_mode)
203+
time.sleep(0.01)

api.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11

2-
.. If you created a package, create one automodule per module in the package.
3-
42
.. automodule:: adafruit_bno055
53
:members:

conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# General information about the project.
2929
project = u'Adafruit BNO055 Library'
3030
copyright = u'2017 Radomir Dopieralski'
31-
author = u'Scott Shawcroft'
31+
author = u'Radomir Dopieralski'
3232

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

124124
# -- Options for manual page output ---------------------------------------

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
adafruit-circuitpython-bus-device
1+
adafruit-micropython-register
2+
adafruit-micropython-bus-device>=0.1.1

0 commit comments

Comments
 (0)