By William Henning
SERVO 12.2016 43
Post comments on this section and find any associated files and/or downloads at
www.servomagazine.com/index.php/magazine/article/December2016_RaspPi-Robots_Indoor-Positioning.
• IR beacons initially to find what room
the robot is in
By adding more IR beacons, it will be
possible to more precisely localize Berry. If
the IR beacons do not give me the precision I
desire, I may explore RF beacons as well.
In the last article, I added an HMC5883L
compass module to Berry, and showed some
simple Python code for getting a bearing to
magnetic north from the module.
A compass is only the first step in
exploring indoor positioning and navigation
for my robots since a compass alone is not
enough to be able to know where the robot is in your
home. Even worse, a compass module by itself can be
extremely inaccurate.
The HMC5883L module can be powered by either 5V
or 3.3V, which makes it very easy to connect to a Raspberry
Pi and/or RoboPi. I connected the compass to the Pi I2C
header on RoboPi as follows:
• Compass Vcc to pin 1 of the I2C header ( 3.3V)
• Compass GND to pin 4 of the I2C header (GND)
• Compass SDA to pin 2 of the I2C header (SDA)
• Compass SCL to pin 3 of the I2C header (SCL)
If you don’t have a RoboPi or PiDroidAlpha, you can
connect the compass directly to the corresponding
Raspberry Pi GPIO pins as follows:
• Compass Vcc to pin 1 of the Pi GPIO header ( 3.3V)
• 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 powered the compass from 3.3V as the Pi’s I2C port is
pulled up to 3.3V.
Improving Compass Accuracy
As I mentioned in the last article, there are a number
of sources of error and interference:
1. “General” local magnetic field variations
2. Local magnetic fields from wiring and metal
3. Correction for the difference between magnetic
north and true north
4. Tilt compensation
We can use “ hmc5883l_calibrate.py” to calibrate the
HMC5883L module for local variations in the magnetic
field; go to http://blog.bitify.co.uk/2013/11/connecting-
and-calibrating-hmc5883l.html for an explanation on how
this calibration works.
There is not a lot we can do about variations in the
local magnetic field caused by wiring and metal in the
house, but frankly, extreme accuracy is not required for a
small indoor robot. It is important to point towards true
north instead of magnetic north – as the difference
between the two can be rather large. To get a “true north”
reading, I had to add code to correct for the magnetic
declination at my location (Langley, BC, Canada). See an
explanation at http://geomag.nrcan.gc.ca/mag_fld/
magdec-en.php for more.
I found an excellent site for getting the magnetic
declination for any location on earth, as long as you have
the latitude and longitude at http://geomag.nrcan.gc.ca/
calc/ mdcal-r-en.php. I used Vancouver’s longitude and
latitude (latitude 49. 28° north, longitude 123.12° west).
The declination calculator returned a magnetic
declination of 16° 26.94’ east, so the correction for
Vancouver is approximately 16 degrees and 27 minutes
east.
As the accuracy of the module is not great, it is enough
to simply subtract 16 degrees from the magnetic north
result, so:
true_bearing = (magnetic_bearing + (360 – 27)) 360
Having taken care of magnetic declination, we now
have to look at tilt compensation.
If the compass module is not perfectly level, the
readings can be quite a bit off. So, we also have to
compensate for tilt if we want to be as accurate as we can
reasonably be. You can measure the tilt affecting your bot
with an accelerometer such as the popular (and
inexpensive) ADXL345 accelerometer.
After some Googling, I found a nice simple ADX345
library (originally from Adafruit) in PiMoroni’s github at: