Introduction: Interfacing Digital Compass (HMC5883L) With Raspberry Pi 2 Using Python3
Initially, I was working on a maze solving robot. Instead of using ultrasonic and infrared on Arduino Mega for wall following like my friends did, I try to do something different using the digital compass and Raspberry Pi 2. This experience is totally new for me as I'm now using Python instead of C++ (well we still have WiringPi which uses C Language) and figuring how Linux system works is not a one day tasks (can't always remember the syntax like "df" and others).
Anyways, I bought the digital compass without considering how I was going to interface it. When I got my RPi2, I was looking everywhere for tutorials. This tutorial is merely a compilation of the tutorials that I used to interface my digital compass. I just thought that it would be a great idea to post in one place where everyone would look for. After all, this is my first post.
This tutorial uses:
1. Raspberry Pi 2 (and whats necessary to power it up, I'm using headless setup on Raspbian)
2. HMC5883L Digital Compass (from electronic flea market)
3. Female to female jumper cables (4 pieces)
4. Your computer (with SSH client program such as "putty")
Step 1: Configuring RPi2
In order to use the RPi2's I2C, we have to first enable it. Boot up and login into the RPi.
Enter the RPi Configuration menu using "sudo raspi-config". Under "Advance Options" you can find "I2C" configuration. Select the option and it will prompt an option to enable or to disable I2C function in RPi2 (which is disabled by default). Select yes when prompted to load I2C kernel module by default. Exit the RPi configuration menu by selecting "Finish".
Returning to the terminal, we will need to modify the file called "modules". Using the text editor program called "nano", we can edit the file under superuser permission. Use, "sudo nano /etc/modules" and add these two lines
i2c-bcm2708#BCM2708 is the family of processors used by RPi, BCM2836 is the specific processor name of the RPi2
To exit, press "CTRL+X" and select "Y" to save and press Enter to overwrite the previous file. (Actually I don't quite understand why I need to do perform this step since we've already prompted and enable I2C kernel module to load by default. I am still searching for answers, please post in comments if you know)
Step 2: Getting Necessary Libraries and Packages
This step is very straight forward. Just needed some typing skills and an internet connection.
We will need this few packages and raspbian upgrade which is i2c-tools, python-smbus and python3(smbus only works in python3). Type in the following commands in the terminal (everything after "#" symbol is just comments for you to read):
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install i2c-tools
sudo apt-get install python-smbus
sudo apt-get install python3 #if you have the latest Raspbian, python3 should be pre-installed
After getting all the packages, reboot the RPi2 using "sudo reboot"
Then it is time to get the libraries. Among the libraries we will be needing is "quick2wire" and "i2clibraries" for python from Think-Bowl. Make a folder for your project, lets say the folder's name is "project", type in the following commands. (everything after "#" symbol is just comments for you to read)
mkdir ~/project#make a folder named 'project' at ~ (home) directory
cd project#change directory into the 'project folder
git clone https://github.com/quick2wire/quick2wire-python-ap...#get quick2wire from github.com
#if don't have git, try "sudo apt-get install git"
mv ./quick2wire-python-api ./code #renaming the quick2wire library folder to code for tidiness, you can skip this if you prefer keeping it original
nano setup.env#create a setup file, basically to point out where the quick2wire library is situated for your python
after this line, terminal will enter text editing mode, type in these lines
export QUICK2WIRE_API_HOME=~/project/code #change the directory address if different than what i'm using
after that CTRL+X, Y, ENTER to quit, save and overwrite
back in terminal mode
. ./quick2wire.env#run the environment setup, run this once every time after reboot, running twice will append the address directory
#for checking, use "env |grep quick2wire", address shown must be the same with the directory where you install your quick2wire library
cd code #go into the quick2wire folder, this will be where you put your python code
git clone https://bitbucket.org/thinkbowl/i2clibraries.git #getting library files containing functions for i2c devices such as HMC5883L, ITG-3205, ADXL345 and LCD
Now you can shut it down with "sudo shutdown -h now" so that we can do the wiring
Step 3: Hardware Wiring
The schematic is simple, its not rocket science to wire this baby up.
There are 4 basic connections we need to make, VCC (3.3V), GND, SDA and SCL, colors of the jumpers I used in the pictures are as below
VCC => RED => pin #1
GND => BLACK => pin #6
SDA => WHITE => pin #3
SCL => GREY => pin #5
So the VCC pin of compass connects to pin #1 of RPi2, GND to pin #6, SDA to pin #3 and SCL to pin #5. If you have trouble figuring out which pin on RPi2 is GND, VCC 3.3, SDA and SCL you can refer to the GPIO Pinout for RPi2 model B from Element14.
After connecting the compass, fire up the RPi2 again. To check if the connection is correct, type in:
i2cdetect -y 1 #RPi2 model B uses port 1 i2c, other models may use port 0 of i2c
The result should show a grid with the address '1e' on one of the grid blocks
Step 4: Coding
To test if this works, you can type in this codes in "nano" and name it as whatevernameyouwant.py
from i2clibraries import i2c_hmc5883l
hmc5883l = i2c_hmc5883l.i2c_hmc5883l(1) #choosing which i2c port to use, RPi2 model B uses port 1
hmc5883l.setDeclination(0,6) #type in the magnetic declination of your location in the bracket (degrees, minute)
Run the code using "sudo python3 whatevernameyouwant.py". This should output a series of measurement in terms of x, y and z axis and the calculated angle with reference to your true north.
2 People Made This Project!
We have a be nice policy.
Please be positive and constructive.