Skip to content

Commit ae10bfb

Browse files
Added LSM303 library (adapted from Arduino version)
1 parent 660dcc5 commit ae10bfb

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

Adafruit_LSM303/Adafruit_I2C.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../Adafruit_I2C/Adafruit_I2C.py

Adafruit_LSM303/Adafruit_LSM303.py

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/usr/bin/python
2+
3+
# Python library for Adafruit Flora Accelerometer/Compass Sensor (LSM303).
4+
# This is pretty much a direct port of the current Arduino library and is
5+
# similarly incomplete (e.g. no orientation value returned from read()
6+
# method). This does add optional high resolution mode to accelerometer
7+
# though.
8+
9+
# Copyright 2013 Adafruit Industries
10+
11+
# Permission is hereby granted, free of charge, to any person obtaining a
12+
# copy of this software and associated documentation files (the "Software"),
13+
# to deal in the Software without restriction, including without limitation
14+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
15+
# and/or sell copies of the Software, and to permit persons to whom the
16+
# Software is furnished to do so, subject to the following conditions:
17+
18+
# The above copyright notice and this permission notice shall be included
19+
# in all copies or substantial portions of the Software.
20+
21+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27+
# DEALINGS IN THE SOFTWARE.
28+
29+
from Adafruit_I2C import Adafruit_I2C
30+
31+
32+
class Adafruit_LSM303(Adafruit_I2C):
33+
34+
# Minimal constants carried over from Arduino library
35+
LSM303_ADDRESS_ACCEL = (0x32 >> 1) # 0011001x
36+
LSM303_ADDRESS_MAG = (0x3C >> 1) # 0011110x
37+
# Default Type
38+
LSM303_REGISTER_ACCEL_CTRL_REG1_A = 0x20 # 00000111 rw
39+
LSM303_REGISTER_ACCEL_CTRL_REG4_A = 0x23 # 00000000 rw
40+
LSM303_REGISTER_ACCEL_OUT_X_L_A = 0x28
41+
LSM303_REGISTER_MAG_CRB_REG_M = 0x01
42+
LSM303_REGISTER_MAG_MR_REG_M = 0x02
43+
LSM303_REGISTER_MAG_OUT_X_H_M = 0x03
44+
45+
# Gain settings for setMagGain()
46+
LSM303_MAGGAIN_1_3 = 0x20 # +/- 1.3
47+
LSM303_MAGGAIN_1_9 = 0x40 # +/- 1.9
48+
LSM303_MAGGAIN_2_5 = 0x60 # +/- 2.5
49+
LSM303_MAGGAIN_4_0 = 0x80 # +/- 4.0
50+
LSM303_MAGGAIN_4_7 = 0xA0 # +/- 4.7
51+
LSM303_MAGGAIN_5_6 = 0xC0 # +/- 5.6
52+
LSM303_MAGGAIN_8_1 = 0xE0 # +/- 8.1
53+
54+
55+
def __init__(self, busnum=-1, debug=False, hires=False):
56+
57+
# Accelerometer and magnetometer are at different I2C
58+
# addresses, so invoke a separate I2C instance for each
59+
self.accel = Adafruit_I2C(self.LSM303_ADDRESS_ACCEL, busnum, debug)
60+
self.mag = Adafruit_I2C(self.LSM303_ADDRESS_MAG , busnum, debug)
61+
62+
# Enable the accelerometer
63+
self.accel.write8(self.LSM303_REGISTER_ACCEL_CTRL_REG1_A, 0x27)
64+
# Select hi-res (12-bit) or low-res (10-bit) output mode.
65+
# Low-res mode uses less power and sustains a higher update rate,
66+
# output is padded to compatible 12-bit units.
67+
if hires:
68+
self.accel.write8(self.LSM303_REGISTER_ACCEL_CTRL_REG4_A,
69+
0b00001000)
70+
else:
71+
self.accel.write8(self.LSM303_REGISTER_ACCEL_CTRL_REG4_A, 0)
72+
73+
# Enable the magnetometer
74+
self.mag.write8(self.LSM303_REGISTER_MAG_MR_REG_M, 0x00)
75+
76+
77+
# Interpret signed 12-bit acceleration component from list
78+
def accel12(self, list, idx):
79+
n = list[idx] | (list[idx+1] << 8) # Low, high bytes
80+
if n > 32767: n -= 65536 # 2's complement signed
81+
return n >> 4 # 12-bit resolution
82+
83+
84+
# Interpret signed 16-bit magnetometer component from list
85+
def mag16(self, list, idx):
86+
n = (list[idx] << 8) | list[idx+1] # High, low bytes
87+
return n if n < 32768 else n - 65536 # 2's complement signed
88+
89+
90+
def read(self):
91+
# Read the accelerometer
92+
list = self.accel.readList(
93+
self.LSM303_REGISTER_ACCEL_OUT_X_L_A | 0x80, 6)
94+
res = [( self.accel12(list, 0),
95+
self.accel12(list, 2),
96+
self.accel12(list, 4) )]
97+
98+
# Read the magnetometer
99+
list = self.mag.readList(self.LSM303_REGISTER_MAG_OUT_X_H_M, 6)
100+
res.append((self.mag16(list, 0),
101+
self.mag16(list, 2),
102+
self.mag16(list, 4),
103+
0.0 )) # ToDo: Calculate orientation
104+
105+
return res
106+
107+
108+
def setMagGain(gain=LSM303_MAGGAIN_1_3):
109+
self.mag.write8( LSM303_REGISTER_MAG_CRB_REG_M, gain)
110+
111+
112+
# Simple example prints accel/mag data once per second:
113+
if __name__ == '__main__':
114+
115+
from time import sleep
116+
117+
lsm = Adafruit_LSM303()
118+
119+
print '[(Accelerometer X, Y, Z), (Magnetometer X, Y, Z, orientation)]'
120+
while True:
121+
print lsm.read()
122+
sleep(1) # Output is fun to watch if this is commented out

0 commit comments

Comments
 (0)