-
Notifications
You must be signed in to change notification settings - Fork 0
/
XLoBorg.py
executable file
·305 lines (259 loc) · 8.57 KB
/
XLoBorg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/usr/bin/env python
# coding: latin-1
"""
This module is designed to communicate with the XLoBorg
busNumber I²C bus on which the XLoBorg is attached (Rev 1 is bus 0, Rev 2 is bus 1)
bus the smbus object used to talk to the I²C bus
addressAccelerometer The I²C address of the accelerometer chip
addressCompass The I²C address of the compass chip
foundAccelerometer True if the accelerometer chip can be seen, False otherwise
foundCompass True if the compass chip can be seen, False otherwise
printFunction Function reference to call when printing text, if None "print" is used
gPerCount Number of G represented by the LSB of the accelerometer at the current sensitivity
tempOffest The offset to add to the temperature reading in °C
"""
# Import the libraries we need
import smbus
import struct
### MODULE DATA ###
# Shared values used by this module
global busNumber
global bus
global addressAccelerometer
global addressCompass
global foundAccelerometer
global foundCompass
global printFunction
global gPerCount
global tempOffest
# Constant values
addressAccelerometer = 0x1C
addressCompass = 0x0E
# Check here for Rev 1 vs Rev 2 and select the correct bus
busNumber = 1
### MODULE FUNCTIONS ###
def Print(message):
"""
Print(message)
Wrapper used by the XLoBorg module to print messages, will call printFunction if set, print otherwise
"""
global printFunction
if printFunction == None:
print message
else:
printFunction(message)
def NoPrint(message):
"""
NoPrint(message)
Does nothing, intended for disabling diagnostic printout by using:
XLoBorg.printFunction = XLoBorg.NoPrint
"""
pass
def Init(tryOtherBus = True):
"""
Init([tryOtherBus])
Prepare the I2C driver for talking to the XLoBorg
If tryOtherBus is True or omitted, this function will attempt to use the other bus if none of the XLoBorg devices can be found on the current busNumber
"""
global busNumber
global bus
global addressAccelerometer
global addressCompass
global foundAccelerometer
global foundCompass
Print('Loading XLoBorg on bus %d' % (busNumber))
# Open the bus
bus = smbus.SMBus(busNumber)
# Check for accelerometer
try:
byte = bus.read_byte_data(addressAccelerometer, 1)
foundAccelerometer = True
Print('Found accelerometer at %02X' % (addressAccelerometer))
except:
foundAccelerometer = False
Print('Missing accelerometer at %02X' % (addressAccelerometer))
# Check for compass
try:
byte = bus.read_byte_data(addressCompass, 1)
foundCompass = True
Print('Found compass at %02X' % (addressCompass))
except:
foundCompass = False
Print('Missing compass at %02X' % (addressCompass))
# See if we are missing chips
if not (foundAccelerometer or foundCompass):
Print('Both the compass and accelerometer were not found')
if tryOtherBus:
if busNumber == 1:
busNumber = 0
else:
busNumber = 1
Print('Trying bus %d instead' % (busNumber))
Init(False)
else:
Print('Are you sure your XLoBorg is properly attached, and the I2C drivers are running?')
bus = None
else:
Print('XLoBorg loaded on bus %d' % (busNumber))
if foundAccelerometer:
InitAccelerometer()
if foundCompass:
InitCompass()
def InitAccelerometer():
"""
InitAccelerometer()
Initialises the accelerometer on bus to default states
"""
global bus
global addressAccelerometer
global gPerCount
# Setup mode configuration
register = 0x2A # CTRL_REG1
data = (0 << 6) # Sleep rate 50 Hz
data |= (0 << 4) # Data rate 800 Hz
data |= (0 << 2) # No reduced noise mode
data |= (1 << 1) # Normal read mode
data |= (1 << 0) # Active
try:
bus.write_byte_data(addressAccelerometer, register, data)
except:
Print('Failed sending CTRL_REG1!')
# Setup range
register = 0x0E # XYZ_DATA_CFG
data = 0x00 # Range 2G, no high pass filtering
try:
bus.write_byte_data(addressAccelerometer, register, data)
except:
Print('Failed sending XYZ_DATA_CFG!')
gPerCount = 2.0 / 128 # 2G over 128 counts
# System state
register = 0x0B # SYSMOD
data = 0x01 # Awake mode
try:
bus.write_byte_data(addressAccelerometer, register, data)
except:
Print('Failed sending SYSMOD!')
# Reset ready for reading
register = 0x00
try:
bus.write_byte(addressAccelerometer, register)
except:
Print('Failed sending final write!')
def InitCompass():
"""
InitCompass()
Initialises the compass on bus to default states
"""
global bus
global addressCompass
# Acquisition mode
register = 0x11 # CTRL_REG2
data = (1 << 7) # Reset before each acquisition
data |= (1 << 5) # Raw mode, do not apply user offsets
data |= (0 << 5) # Disable reset cycle
try:
bus.write_byte_data(addressCompass, register, data)
except:
Print('Failed sending CTRL_REG2!')
# System operation
register = 0x10 # CTRL_REG1
data = (0 << 5) # Output data rate (10 Hz when paired with 128 oversample)
data |= (3 << 3) # Oversample of 128
data |= (0 << 2) # Disable fast read
data |= (0 << 1) # Continuous measurement
data |= (1 << 0) # Active mode
try:
bus.write_byte_data(addressCompass, register, data)
except:
Print('Failed sending CTRL_REG1!')
def ReadAccelerometer():
"""
x, y, z = ReadAccelerometer()
Reads the X, Y and Z axis force, in terms of Gs
"""
global bus
global addressAccelerometer
global gPerCount
# Read the data from the accelerometer chip
try:
[status, x, y, z] = bus.read_i2c_block_data(addressAccelerometer, 0, 4)
except:
Print('Failed reading registers!')
status = 0
x = 0
y = 0
z = 0
# Convert from unsigned to correctly signed values
bytes = struct.pack('BBB', x, y, z)
x, y, z = struct.unpack('bbb', bytes)
# Convert to Gs
x *= gPerCount
y *= gPerCount
z *= gPerCount
return x, y, z
def ReadCompassRaw():
"""
x, y, z = ReadCompassRaw()
Reads the X, Y and Z axis raw magnetometer readings
"""
global bus
global addressCompass
# Read the data from the compass chip
try:
bus.write_byte(addressCompass, 0x00)
[status, xh, xl, yh, yl, zh, zl, who, sm, oxh, oxl, oyh, oyl, ozh, ozl, temp, c1, c2] = bus.read_i2c_block_data(addressCompass, 0, 18)
except:
Print('Failed reading registers!')
status = 0
xh = 0
xl = 0
yh = 0
yl = 0
zh = 0
zl = 0
# Convert from unsigned to correctly signed values
bytes = struct.pack('BBBBBB', xl, xh, yl, yh, zl, zh)
x, y, z = struct.unpack('hhh', bytes)
return x, y, z
def ReadTemperature():
"""
temp = ReadTemperature()
Reads the die temperature of the compass in degrees Celsius
"""
global bus
global addressCompass
global tempOffest
# Read the data from the compass chip
try:
bus.write_byte(addressCompass, 0x00)
[status, xh, xl, yh, yl, zh, zl, who, sm, oxh, oxl, oyh, oyl, ozh, ozl, temp, c1, c2] = bus.read_i2c_block_data(addressCompass, 0, 18)
except:
Print('Failed reading registers!')
temp = 0
# Convert from unsigned to correctly signed values
bytes = struct.pack('B', temp)
temp = struct.unpack('b', bytes)[0]
temp += tempOffset
return temp
### STARTUP ROUTINES ###
# Default user settings
printFunction = None
tempOffset = 0
# Auto-run code if this script is loaded directly
if __name__ == '__main__':
# Load additional libraries
import time
# Start the XLoBorg module (sets up devices)
Init()
try:
# Loop indefinitely
while True:
# Read the
x, y, z = ReadAccelerometer()
mx, my, mz = ReadCompassRaw()
temp = ReadTemperature()
print 'X = %+01.4f G, Y = %+01.4f G, Z = %+01.4f G, mX = %+06d, mY = %+06d, mZ = %+06d, T = %+03d°C' % (x, y, z, mx, my, mz, temp)
time.sleep(0.1)
except KeyboardInterrupt:
# User aborted
pass