This guide will help you get started with a PiicoDev® Magnetometer - get it working as a compass, and read the magnetic field strength of a nearby magnet.
This guide is for the current revision of the PiicoDev Magnetometer, featuring the MMC5603. All of the video content is still relevant for both revisions.
For more information on the differences, select the "Check Revision" tab
To get started - select your dev. board below.
We have tried our hardest to make it a drop-in replacement, the measurement directions and code should work in place of the previous Magnetometer featuring the QMC6310,
The biggest change is to the main IC being used, the previous revision features the QMC6310, while the current revision features the MMC5603.
Hardware and Connections
To follow along, it's best to have:
- A Raspberry Pi Pico with pins soldered (pointing down)
- A PiicoDev Magnetometer MMC5603
- A PiicoDev Expansion Board for Raspberry Pi Pico
- A PiicoDev Cable - longer cables are useful to keep your Magnetometer away from magnetic interference.
- (Optional) A magnetic compass - to compare measured headings.
- (Optional) A PiicoDev platform helps secure everything together.
- (Optional) A magnet
- (Optional) A PiicoDev OLED Module and additional cable for the final project.
Plug your Pico into the expansion board. Make sure it is plugged in the correct orientation - Pin 0 on the expansion board should be to the left of the Pico's USB connector.
If you're unfamiliar with connecting PiicoDev modules, read the PiicoDev Connection Guide before proceeding.
To follow along, it's best to have:
- A Raspberry Pi (model 3, 4, Zero W) This tutorial will use a Raspberry Pi 4, Model B
- A PiicoDev Adapter for Raspberry Pi
- A PiicoDev Magnetometer QMC6310
- A PiicoDev Cable - longer cables are useful to keep your Magnetometer away from magnetic interference.
- (Optional) A magnetic compass - to compare measured headings.
- (Optional) A PiicoDev platform helps secure everything together.
- (Optional) A magnet
- (Optional) A PiicoDev OLED Module and additional cable for the final project.
Mount the PiicoDev® Adapter on your Raspberry Pi and plug connect your Magnetometer to the Adapter via the PiicoDev cable.
The adapter connects to the 40-pin GPIO header on the Raspberry Pi - ensure the header is mounted correctly, with the "Ethernet" label on the same side as the Pi's ethernet adapter (for a Pi 4. On a Pi 3 this will be the USB connector).
Pictured above: A Raspberry Pi 4 Model B with USB Power and HDMI (two white leads). The PiicoDev Adapter is placed on the 40-pin header, and connects to the weather sensor with a PiicoDev Cable.
To follow along, it's best to have:
- A MicroBit V2
- A PiicoDev Magnetometer QMC6310
- A PiicoDev Adapter for MicroBit
- A PiicoDev Cable - longer cables are useful to keep your Magnetometer away from magnetic interference.
- (Optional) A magnetic compass - to compare measured headings.
- (Optional) A PiicoDev platform helps secure everything together.
- (Optional) A magnet
- (Optional) A PiicoDev OLED Module and additional cable for the final project.
Plug your micro:bit into the Adapter - make sure the buttons are facing up, as shown in the picture below. Connect your magnetometer to the Adapter via the PiicoDev cable, and finally connect your micro:bit to your computer with a USB lead.
If you're unfamiliar with connecting PiicoDev modules, read the PiicoDev Connection Guide before proceeding.
Setup Thonny
Select your dev board from the tabs above to get ready for programming with Thonny for the first time.
If you have already programmed with PiicoDev modules before, there's probably no need to follow these steps again.
Download / Install PiicoDev Modules
To work with PiicoDev hardware, we need to download some drivers. The drivers provide all the functions to easily connect and communicate with PiicoDev hardware. Select your dev board from the options above.
We will need these files to easily drive the PiicoDev Magnetometer:
- Save the following files to your preferred coding directory - In this tutorial, we save to My Documents > PiicoDev.
- Download the PiicoDev Unified Library: PiicoDev_Unified.py (right-click, "save link as").
- Download the device module: PiicoDev_MMC5603.py (right-click, "save link as")
- Upload the files to your Pico. This process was covered in the Setup Thonny section.
The PiicoDev Unified Library is responsible for communicating with PiicoDev hardware, and the device module contains functions for driving specific PiicoDev devices.
We will need these files to easily drive the PiicoDev Magnetometer:
- Save the following files to your preferred coding directory - In this tutorial, we save to My Documents > PiicoDev.
- Download the PiicoDev Unified Library: PiicoDev_Unified.py (right-click, "save link as").
- Download the device module: PiicoDev_MMC5603.py (right-click, "save link as")
- Upload the files to your Pico. This process was covered in the Setup Thonny section.
The PiicoDev Unified Library is responsible for communicating with PiicoDev hardware, and the device module contains functions for driving specific PiicoDev devices.
Example 1 - Compass and Calibration
We're ready to go with our first example on the Magnetometer! The following example compass.py, first requests to calibrate the magnetometer:
# Calibrate the sensor by turning it in a circle # Display the heading with compensation for magnetic declination from PiicoDev_MMC5603 import PiicoDev_MMC5603 from PiicoDev_Unified import sleep_ms # Cross-platform compatible sleep function compass = PiicoDev_MMC5603() # Initialise the sensor # Calibration recommended for best results. compass.calibrate() # only need to calibrate once # Optional: Declination is the difference between magnetic-north and true-north ("heading") and depends on location # compass.setDeclination(12.3) # Found with: https://www.magnetic-declination.com/Australia/Newcastle/122944.html while True: heading = compass.readHeading() # get the heading from the sensor if compass.dataValid(): # Rejects invalid data heading = round(heading) # round to the nearest degree print( str(heading) + "°") # print the data with a degree symbol sleep_ms(100)
Slowly rotate the sensor on a flat surface until calibration is complete. You can see the calibration progress shown by a progress bar in the shell.
Follow along with the video for this part - getting a high-quality calibration is important for reading an accurate heading.
Once calibration is complete, your console will begin printing the measured heading into the shell. This is the same heading that you would read off a magnetic compass. The heading is the direction the top edge (with the PiicoDev label) of the module is pointing when placed on a level surface like a table.
If you have a magnetic compass you can compare headings. In the video I scribe a line pointing north - as read from my magnetic compass. I then compare the data gathered by the magnetometer and the results are really close!
You may notice a new file named calibration.cal has appeared on your micro:bit - this is the calibration data. This calibration data will be automatically loaded every time the script runs, so you can comment-out compass.calibrate() if you don't want to calibrate on every power-up. It's still a good idea to calibrate periodically, or if you notice your heading has drifted.
Remix - True North
So far we have been working with Magnetic North - this is the direction a magnetic compass will point. To find a true heading, we need to input some more information. Magnetic Declination is the difference between Magnetic North and True North (or "Geographic North"). The value for declination changes depending on location. In Newcastle, Australia, the declination is about 12° (as of 2022). There are lots of online tools that will help you find the declination in your area (here's one example). Once you know the declination in your area, you can input that angle into the setDeclination() function. Re-run your script and you should notice the heading data has been offset slightly. Your magnetometer is now indicating its measurement for True North.
Example 2 - Detect a Magnet
In this example, we'll measure magnetic-field-strength. This is useful to detect the presence of a nearby magnet. Replace the code in main.py with the following code.
# Read the magnetic field strength and determine if a magnet is nearby from PiicoDev_MMC5603import PiicoDev_MMC5603 from PiicoDev_Unified import sleep_ms magSensor = PiicoDev_MMC5603() # initialise the magnetometer # magSensor.calibrate() threshold = 120 # microTesla or 'uT'. while True: strength = magSensor.readMagnitude() # Reads the magnetic-field strength in microTesla (uT) myString = str(strength) + ' uT' # create a string with the field-strength and the unit print(myString) # Print the field strength if strength > threshold: # Check if the magnetic field is strong print('Strong Magnet!') sleep_ms(1000)
When we run the script, we see the measured field strength being printed to the shell. If the measured strength goes above a set threshold, the program prints a message to the shell. This time around, the magnetometer is initialised with the maximum range (3000 uT), since there could be a strong magnet nearby. When we exceed the range of the magnetometer, the measurement becomes invalid and so the measurement data is returned as a special "Not a Number" type.
A note about calibration: In Example 1 we performed a 2-axis calibration (rotating the magnetometer on a flat surface. For best results in this example a 3-axis calibration is necessary. To calibrate 3-axes, call the calibrate() function, and rotate the device slowly in all axes.
Above: Bring a magnet nearby the Magnetometer and observe how small movements can be easily observed by the magnetic field strength. The above figure is using modified code that removes other print() statements. Refer to tutorial video to reproduce this example.
Example 3 - Raw Data
The read() method allows you to extract the 3-axis magnetometer data (in uT, or just the raw register data) - for when you wish to process the data with your own algorithm.
# Read the magnetic field strength and determine if a magnet is nearby from PiicoDev_MMC5603import PiicoDev_MMC5603 from PiicoDev_Unified import sleep_ms magSensor = PiicoDev_MMC5603() # initialise the magnetometer # magSensor.calibrate() while True: raw_data = magSensor.read() # Read the field strength on each axis in uT # raw_data = magSensor.read(raw=True) # Read the raw, unscaled data on each axis print(raw_data) # Print the data sleep_ms(200)
Project - Graphical Compass
So far we've been using the shell to visualise information collected from the magnetometer. Now for a fun mini-project. We can use a PiicoDev OLED Module to display a digital compass-needle that always points north. The following code is really similar to Example 1, except there's extra code to drive the display, and handle drawing an indicator on the display.
To follow along with this project, you'll need to save PiicoDev_SSD1306.py onto your Pico.
# Read the magnetic field strength and determine if a magnet is nearby from PiicoDev_MMC5603import PiicoDev_MMC5603 from PiicoDev_Unified import sleep_ms magSensor = PiicoDev_MMC5603() # initialise the magnetometer # magSensor.calibrate() while True: raw_data = magSensor.read() # Read the field strength on each axis in uT # raw_data = magSensor.read(raw=True) # Read the raw, unscaled data on each axis print(raw_data) # Print the data sleep_ms(200)
The drawCompass() method converts the heading into x,y coordinates that draw a line to the centre of the display. A circle is drawn on the end of the line and the heading in degrees is shown in the bottom corner of the display.
Above: a compass needle is animated on the OLED to point North, even if the whole assembly is rotated.
Conclusion
We can measure the properties of magnetic fields using a 3-axis magnetometer. Build-in functions allow us to easily measure the sensor's heading in a magnetic field, and we've even built a cool graphical compass project using an extra display module.
If you make something cool with this starter project we'd love for you to share it on our forums! And if you'd like some help with this guide, start the conversation below - We're full-time makers and here to help!
Resources
- Magnetometer library: PiicoDev® Magnetometer QMC6310 MicroPython Module
- Hardware Repository for the PiicoDev Magnetometer
- OLED Library: PiicoDev Unified MicroPython module for SSD1306