Arduino-HMC5883L/blob/master/HMC5883L_
https://raw.githubusercontent.com/pimoroni/adxl345-
python/master/ adxl345.py.
The ADXL345 module I used had an onboard 3.3V
regulator, but ran at 3.3V.
I connected the ADXL345 module to the Pi I2C header
on RoboPi as follows:
Tilt and declination compensated heading function from
compass.py:
def heading(decl):
• Compass GND to pin 4 of the I2C header (GND)
axes = adxl.getAxes(True)
• Compass SDA to pin 2 of the I2C header (SDA)
• Compass SCL to pin 3 of the I2C header (SCL)
x = axes[‘x’]
y = axes[‘y’]
z = axes[‘z’]
I also connected the module’s Vcc to pin 2 on the
Raspberry Pi GPIO header to power it.
roll = math.asin( axes[‘y’])
pitch = math.asin(-axes[‘x’])
If you don’t have a RoboPi or PiDroidAlpha, you can
connect the ADXL345 module directly to the corresponding
Raspberry Pi GPIO pins as follows:
if ((roll>0.78) or (roll<-0.78) or
(pitch>0.78) or (pitch<-0.78)):
print “Pitch/Roll error”
return -1000
• Compass Vcc to pin 2 of the Pi GPIO header (5V)
scale = 1.0
• Compass GND to pin 6 of the Pi GPIO header (GND)
• Compass SDA to pin 3 of the Pi GPIO header (SDA)
• Compass SCL to pin 5 of the Pi GPIO header (SCL)
I got readings from the module right away. However,
the Z axis results never changed, and were way off! After
some more Googling, I found that this was a known
problem with the 2G and 4G sensitivity modes, and that
switching to 8G or 16G modes would fix it.
x = read_signed_word(3) scale - 2
# use calibrate.py to compute the x/y
# calibration
y = read_signed_word(7) scale + 115
z = read_signed_word(5) scale
xh = x math.cos(pitch) + z *
math.sin(pitch)
yh = x math.sin(roll) math.sin(pitch) +
y math.cos(roll) - z math.sin(roll) *
math.cos(pitch)
It did.
heading = math.atan2(yh, xh)
Looking at the results, it was obvious that my desk
(where I tested the module) was not perfectly level, and it
is pretty much a given that any floor my bots travel over will
not be perfectly flat either. I decided that there was no
point in trying to calibrate the ADXL345 to any great
precision, so I decided that all I needed was to calibrate the
module at the position it will be attached to Berry on my
desk.
if (heading < 0):
heading = heading + 2*3.141529
return (math.degrees(heading) + 360 - decl)
% 360
I made two modifications to the ADXL345.py library:
First, I had to make a “navigation deck” for Berry. I
used one of my EZasBone prototyping boards as the
platform for the HMC5883L and ADXL345 modules. It was
handy, and it had mounting holes I could use to attach it
on the Dagu chassis.
I found some C code for modifications needed for the
tilt compensation at https://github.com/jarzebski/
1. To calibrate the compass, I just gathered 600
samples while the module was in the correct position, and
calculated the minimum and maximum X, Y, and Z readings
in the main “execute if not used as a library” code. Don’t
forget to set xoffs/yoffs/zoffs to zero before calibrating!
2. I calculated the average X/Y/Z offsets, and
subtracted that from the subsequent readings returned
when the library was used.
Good enough for home bots :)
To get the heading for the bot, just
import the compass.py library and use the
heading function:
import compass
... other code ...
dir = compass.heading(my
declination)
44 SERVO 12.2016