In dieser Anleitung wird mit Hilfe eines Magnetometers MMC56X3 von Adafruit eine Kompassanwendung auf dem Pico-Geek dargestellt. Damit der Anschluss
des I2C-Sensors besonders einfach ist, habe ich mich einmal dafür entschieden, die Firmware speziell für den Pico-Geek
von Waveshare zu nehmen.
Dadurch kann der I2C- Port mit den GP28 und GP29 direkt mit dem 4-poligen Stecker eines Qwiic-Kabels (siehe bei Hardware) verbunden werden. Ich werde
parallel zeigen, wie man das in der Firmware integrierte Display nutzt. Der Vorteil ist, dass die Teile einfach zusammengesteckt werden und los gehts.
Hardware
- Pico-Geek (z.B. von Botland )
- Qwiic-Kabel mit 4-poligem Stecker(z.B. von Botland )
- Magnetometer MMC56X3 von Adafruit (z.B. von Botland )
Software
- aktuelle Firmware Adafruit CircuitPython; Waveshare RP2040-GEEK with rp2040
- library adafruit_mmc5656x3.mpy aus dem CircuitPython-Bundle zur Firmwareversion
- Ordner adafruit_imageload aus dem CircuitPython-Bundle zur Firmwareversion
- Ordner adafruit_register aus dem CircuitPython-Bundle zur Firmwareversion
- Ordner adafruit_display_text aus dem CircuitPython-Bundle zur Firmwareversion
Los gehts
Verbinden Sie also den Magnetsensor über das Qwiic-Kabel mit der Stemma-QT Buchse am Pico-Geek.

Wenn das erledigt ist, kann das Magnetometer in Betrieb genommen werden. Adafruit beschreibt in seinen Anleitungen einen ersten s.g. 'simpletest.py', der im unteren Kasten gezeigt ist. Beachten Sie, dass sich die Bibliothek adafruit_mmc5656x3.mpy im 'lib-Ordner' befindet.
1 # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2 # SPDX-License-Identifier: MIT
3
4 # Simple demo of the MMC56x3 magnetometer.
5 # Will print the magnetometer values every second.
6 import time
7 import board
8 import busio
9 import adafruit_mmc56x3
10
11 # Initialize I2C bus and sensor.
12 i2c = busio.I2C(board.GP29, board.GP28)
13 # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
14 sensor = adafruit_mmc56x3.MMC5603(i2c)
15
16 # values every second and print them out.
17 while True:
18 mag_x, mag_y, mag_z = sensor.magnetic
19 temp = sensor.temperature
20 # Print values.
21 print(
22 "Magnetometer (gauss): ({0:0.3f},{1:0.3f},{2:0.3f})".format(mag_x, mag_y, mag_z)
23 )
24 print("Temperature: {0:0.3f}C".format(temp))
25 # Delay for a second.
26 time.sleep(1.0)
Wenn Sie das Programm starten und den Pico-Geek auf einer flachen Unterlage etwas hin- und herbewegen, werden in der
Console der Thonny-IDE entsprechende Werte ausgegeben:
Bildbox 2 (klick hier)
Was die Werte bedeuten und wie sie genutzt werden können, wird nachfolgend erklärt. Dass der Chip auch die Temperatur erfasst, sei hier nur am
Rande erwähnt und wird nicht weiter verfolgt.
Notwendigkeit zum Kalibrieren des Sensors:
Magnetometer können verwendet werden, um die Orientierung in Bezug auf das Erdmagnetfeld zu ermitteln. Im Grunde wie ein Kompass!
Beim Kompass richtet sich eine Magnetnadel in Richtung des Erdmagnetfeldes aus und zeigt zum magnetischen Nordpol. So können wir sagen,
wo Norden ist. Aber Magnetometer müssen in einer Welt voller Magnete (Motoren, Spulen, Stromleitungen, Maschinen aus Eisen/Stahl u.s.w.)
ein sehr kleines Magnetfeld von 35-65 µTesla messen. Deshalb müssen sie kalibriert werden. Durch eine s.g. Hard-Iron-Offset-Berechnung
werden starke Offsetwerte ausgeschlossen. So können sie den magnetischen Norden finden.
Methode zum Kalibrieren des Sensors:
Eine einfache Methode zur Kalibrierung verwendet das Aufzeichnen von Werten, um die minimalen und maximalen Messwerte auf allen drei Achsen zu
erfassen. Während Sie die Aufzeichnung ausführen, drehen Sie das Modul mehrmals langsam in allen drei Achsen. Das Ziel besteht darin,
die absoluten Minima und Maxima für jede Achse aufzuzeichnen. Je mehr Sie es also drehen, desto wahrscheinlicher ist es, dass Sie den absoluten
Spitzenwert erfassen.
Das Programm im folgenden Kasten bestimmt diese Minimal- und Maximalwerte und schreibt sie in ein Array, welches im späteren Compass-Programm
genutzt wird.
Bildbox 2 (klick hier)
1 # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2 # SPDX-License-Identifier: MIT
3
4 """ Calibrate the magnetometer and print out the hard-iron calibrations """
5
6 import time
7 import board
8 import busio
9 import adafruit_mmc56x3
10
11 # Initialize I2C bus and sensor.
12 i2c = busio.I2C(board.GP29, board.GP28)
13 magnetometer = adafruit_mmc56x3.MMC5603(i2c)
14
15 # calibration for magnetometer X (min, max), Y and Z
16 hardiron_calibration = [[1000, -1000], [1000, -1000], [1000, -1000]]
17
18 def calibrate():
19 start_time = time.monotonic()
20 # Update the high and low extremes
21 while time.monotonic() - start_time < 15.0:
22 magval = magnetometer.magnetic
23 print("Calibrating - X:{0:10.2f}, Y:{1:10.2f}, Z:{2:10.2f} uT".format(*magval))
24 for i, axis in enumerate(magval):
25 hardiron_calibration[i][0] = min(hardiron_calibration[i][0], axis)
26 hardiron_calibration[i][1] = max(hardiron_calibration[i][1], axis)
27 print("Calibration complete:")
28 print("hardiron_calibration =", hardiron_calibration)
29
30 print("Prepare to calibrate! Twist the magnetometer around in 3D in...")
31 print("3...")
32 time.sleep(1)
33 print("2...")
34 time.sleep(1)
35 print("1...")
36 time.sleep(1)
37
38 calibrate()
Wenn Sie das Programm starten und den Pico-Geek langsam in verschiedene Richtungen bewegen, werden in der
Console der Thonny-IDE entsprechende Werte ausgegeben:
Bildbox 3 (klick hier)
Entscheidend ist die letzte Zeile in der Kommandozeile:
hardiron_calibration = [[14.8625, 69.6], [-40.6875, 31.3062], [-56.4312, -11.0562]]
Hier sind die Minimal- und Maximalwerte für die X, Y und Z Richtung enthalten. Speichern Sie die komplette Zeile in die Zwischenablage, um sie
später in das Kompass-Programm einzusetzen.
Damit sind wir so weit, um ein erstes kurzes Programm mit der Kompassrichtung zu testen. Auf dem Kompass ist eine Scheibe mit einer im
Uhrzeigersinn aufgetragenen 360-Grad-Einteilung angebracht (Kompassrose). Die vier Himmelsrichtungen Norden, Osten, Süden und Westen
entsprechen 0°, 90°, 180° und 270°. Der Sensor des Magnetometers gibt uns die Werte des Magnetfeldes der Erde in µTesla
an. Zur Berechnung benutzen wir die x- und y-Richtung des Sensors. Um die Mikrotesla-Werte in eine Kompassrichtung von 0-360 Grad umzuwandeln,
können wir die Funktion atan2() verwenden. Das Ergebnis wird in Radiant angegeben, also multiplizieren wir es mit 180 Grad und dividieren
durch Pi, um es in Grad umzuwandeln. Im unteren Kasten finden Sie dafür den Quellcode, wie ihn Adafruit für eine Vielzahl seiner
Magnetometer vorschlägt:
Bildbox 3 (klick hier)
1 # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2 # SPDX-License-Identifier: MIT
3
4 """ Display compass heading data from a calibrated magnetometer """
5
6 import time
7 import math
8 import board
9 import busio
10 import adafruit_mmc56x3
11
12 # Initialize I2C bus and sensor.
13 i2c = busio.I2C(board.GP29, board.GP28)
14 sensor = adafruit_mmc56x3.MMC5603(i2c)
15
16 # You need t copy your own value for hardiron_calibration from the output and paste it
17 # into this script here:
18 hardiron_calibration = [[14.8625, 69.6], [-40.6875, 31.3062], [-56.4312, -11.0562]]
19
20 # This will take the magnetometer values, adjust them with the calibrations
21 # and return a new array with the XYZ values ranging from -100 to 100
22 def normalize(_magvals):
23 ret = [0, 0, 0]
24 for i, axis in enumerate(_magvals):
25 minv, maxv = hardiron_calibration[i]
26 axis = min(max(minv, axis), maxv) # keep within min/max calibration
27 ret[i] = (axis - minv) * 200 / (maxv - minv) + -100
28 return ret
29
30
31 while True:
32 magvals = sensor.magnetic
33 normvals = normalize(magvals)
34
35 # we will only use X and Y for the compass calculations, so hold it level!
36 compass_heading = int(math.atan2(normvals[1], normvals[0]) * 180 / math.pi)
37 # compass_heading is between -180 and +180 since atan2 returns -pi to +pi
38 # this translates it to be between 0 and 360
39 if compass_heading < 0:
40 compass_heading += 360
41
42 print("Heading:", compass_heading)
43 time.sleep(1)
Was bedeuten die Anzeigen?
- Richtung: 0° Norden
- Richtung: 90° Osten
- Richtung: 180° Süden
- Richtung: 270° Westen
Nun wäre es natürlich schön, wenn die Werte nicht nur in der Console der Thonny-IDE angezeigt würden.
Deshalb folgt hier noch ein Vorschlag, wie eine Kompassrose auf dem Display des Pico-Geek dargestellt wird, die sich
bei Bewegung des Pico-Geek dreht und immer nach Norden ausrichtet.
Bildbox 4 (klick hier)
Bevor Sie den Quellcode aus dem unteren Kasten ausprobieren, erinnere ich noch einmal an die unter 'Software' genannten Bibliotheken und
Bibliotheksordner, die sich jetzt alle im 'lib-Ordner' befinden müssen. Ausserdem wird die Bitmap-Datei 'compass.bmp'
in einem Ordner 'images' benötigt. Legen Sie den Ordner auf dem Pico-Geek Laufwerk an,
downloaden die Bilddatei von hier
und speichern sie im Ordner 'images'.
Bildbox 4 (klick hier)
1 # SPDX-FileCopyrightText : 2026 Detlef Gebhardt, written for 10.0.3 on 2025-10-17; Waveshare RP2040-GEEK with rp2040
2 # SPDX-FileCopyrightText : Copyright (c) 2026 Detlef Gebhardt
3 # SPDX-Filename : RP2040 GEEK - Compass
4 # SPDX-License-Identifier: https://dgebhardt.de
5 import time
6 import board
7 import busio
8 import displayio
9 import terminalio
10 from adafruit_display_text import label
11 import adafruit_imageload
12 import bitmaptools
13 import adafruit_mmc56x3
14 import math
15
16 # Display initialisieren
17 display = board.DISPLAY
18 display.rotation = 90
19 display.brightness = 1
20 main_group = displayio.Group()
21 display.root_group = main_group
22
23 # Bitmap-Dateien fuer Hintergrund und Zeiger
24 zifferblatt = "/images/compass.bmp"
25 ## Compassnadel 140x140 Hintergrund
26 bg_bitmap, bg_pal = adafruit_imageload.load(zifferblatt, bitmap=displayio.Bitmap,palette=displayio.Palette)
27 bg_pal.make_transparent(0)
28 bg_bitmap_scribble = displayio.Bitmap(display.width, display.height, len(bg_pal))
29 bg_tile_grid = displayio.TileGrid(bg_bitmap_scribble, pixel_shader=bg_pal)
30 main_group.append(bg_tile_grid)
31 bitmaptools.rotozoom( bg_bitmap_scribble, bg_bitmap, angle = 0)
32
33 # Initialize I2C bus and sensor.
34 i2c = busio.I2C(board.GP29, board.GP28)
35 sensor = adafruit_mmc56x3.MMC5603(i2c)
36
37 # set the main_group as the root_group of the built-in DISPLAY
38 # display.root_group = main_group
39
40 sensor.data_rate = 10 # in Hz, from 1-255 or 1000
41 sensor.continuous_mode = True
42
43 #my values
44 hardiron_calibration = [[-7.925, 22.4375], [10.9312, 43.5562], [-32.825, -13.3687]]
45
46 # This will take the magnetometer values, adjust them with the calibrations
47 # and return a new array with the XYZ values ranging from -100 to 100
48 def normalize(_magvals):
49 ret = [0, 0, 0]
50 for i, axis in enumerate(_magvals):
51 minv, maxv = hardiron_calibration[i]
52 axis = min(max(minv, axis), maxv) # keep within min/max calibration
53 ret[i] = (axis - minv) * 200 / (maxv - minv) + -100
54 return ret
55
56 # main loop
57 while True:
58 magvals = sensor.magnetic
59 normvals = normalize(magvals)
60 # we will only use X and Y for the compass calculations
61 compass_heading = math.atan2(normvals[1], normvals[0]) * 30 / math.pi
62 # this translates it to be between 0 and 60
63 if compass_heading < 0:
64 compass_heading += 60
65 #print("Kurswinkel: ", 6*int(compass_heading + 0.5))
66 bitmaptools.rotozoom( bg_bitmap_scribble, bg_bitmap, angle = math.pi/30 * (1 - compass_heading))
67 time.sleep(0.3)
Zum Abschluss noch ein paar Erläuterungen zum Programm:
Die Zeilen 5- 14 importieren die benötigten Bibliotheken und Module. In den Zeilen 16 bis 21 wird das Display initialisiert.
In den Zeilen 23 bis 31 wird eine Tile_Grid mit der Bilddatei als Hintergrundbild angelegt und mit Hilfe von 'bitmaptools.rotozoom' (31) als
drehbar definiert. Die Zeilen 33 bis 67 entsprechen im Wesentlichen den vorangegangenen Tests. Die Angabe des Winkels für die
Kompassrichtung in Zeile 61 habe ich zwischen 0 und 60 gewählt. So kann ich in Zeile 66 die Ausrichtung der 'Nadel' ähnlich
den Sekunden auf dem Zifferblatt einer Uhr vornehmen. So findet man Norden bei beliebiger Lage des Pico-Geek, da der Zeiger immer
in diese Richtung zeigt.
Viel Spass und Erfolg beim Ausprobieren.
Viel Spass und Erfolg beim Ausprobieren.
