Raspberry Pi Pico: Schütteln erkennen mit dem MPU-6050
Mithilfe eines Raspberry Pi Pico und MPU-6050 soll die Bewegung „Schütteln“ erkannt werden. Hierfür wird der MPU-6050-Sensor eingesetzt, der mit seinem Gyroskop und Beschleunigungssensor präzise Daten liefert, die wir als Bewegung interpretieren können.
Der Raspberry Pi Pico wertet diese Daten aus. Wenn ein Schütteln erkannt wird, leuchtet die Onboard-LED kurz auf, um die Bewegung visuell anzuzeigen.
Weil „Schütteln“ keine kontinuierliche Bewegung ist, arbeiten wir hier nicht mit nur einem Schwellwert bei der Auswertung, sondern mit einer oberen Schwelle zur Schüttelerkennung und einer unteren Schwelle, die den Ruhezustand repräsentiert. Das hilft, Aussetzern vorzubeugen und „anhaltendes Schütteln“ besser zu erkennen.
Zur Erkennung von „Schütteln“ verwenden wir drei Lösungen, die unterschiedlich leistungsfähig sind. Im einen werden die Sensordaten des Gyroskops verwendet, in einem weiteren die des Beschleunigungssensors. Im dritten werden die Sensordaten miteinander kombiniert.
Aufbau und Bauteile

| Raspberry Pi Pico | MPU-6050 | |
|---|---|---|
| Pin 38 | GND | GND |
| Pin 36 | VCC +3,3V | VCC |
| Pin 27 | GPIO 21 | SCL |
| Pin 26 | GPIO 20 | SDA |
I2C verbinden und programmieren
- Raspberry Pi Pico: Grundlagen zum I2C
- Raspberry Pi Pico: I2C verbinden und programmieren
- Raspberry Pi Pico: Troubleshooting I2C - Fehler, Probleme und Lösungen
Schnell und einfach alle Bauteile zusammen bestellen
Programmcode: Lösung mit Gyroskop
Der Programmcode enthält die softwareseitige Ansteuerung des MPU-6050 zum Lesen der Sensordaten des Gyroskops. Wenn der Aufbau zum Zeitpunkt der Messung bewegt wird, leuchtet die Onboard-LED.
# Bibliotheken laden
import machine
import time
import math
# Schwellwerte (Hysterese)
UPPER_THRESHOLD = 100
LOWER_THRESHOLD = 30
shaking = False # Status merken
# Onboard-LED initialisieren
led = machine.Pin('LED', machine.Pin.OUT, value=0)
# MPU-6050 über I2C initialisieren
mpu = machine.I2C(0, scl=machine.Pin(21), sda=machine.Pin(20), freq=100000)
mpu.writeto_mem(0x68, 0x6B, b'\x00') # Wake up MPU-6050
# Funktion: Daten von MPU-6050 lesen
def read_gyro():
data = mpu.readfrom_mem(0x68, 0x43, 6)
gx = int.from_bytes(data[0:2], 'big') if data[0] < 0x80 else int.from_bytes(data[0:2], 'big') - 65536
gy = int.from_bytes(data[2:4], 'big') if data[2] < 0x80 else int.from_bytes(data[2:4], 'big') - 65536
gz = int.from_bytes(data[4:6], 'big') if data[4] < 0x80 else int.from_bytes(data[4:6], 'big') - 65536
return gx / 131, gy / 131, gz / 131 # in °/s
# Hauptprogramm: Endlos-Schleife
while True:
# Sensor-Werte lesen
gx, gy, gz = read_gyro()
total = abs(gx) + abs(gy) + abs(gz)
# Schwellwerte vergleichen
if not shaking and total > UPPER_THRESHOLD:
shaking = True
print(f"{total:.3f}", 'SHAKE', end="\r")
led.on()
time.sleep(.5)
elif shaking and total < LOWER_THRESHOLD:
shaking = False
print(f"{total:.3f}", str(shaking), end=" \r")
led.off()
#time.sleep(1)
else:
print(f"{total:.3f}", str(shaking), end=" \r")
time.sleep(.1)
Programmcode: Lösung mit Accelerometer
Der Programmcode enthält die softwareseitige Ansteuerung des MPU-6050 zum Lesen der Sensordaten des Beschleunigungssensors. Wenn der Aufbau zum Zeitpunkt der Messung bewegt wird, leuchtet die Onboard-LED.
# Bibliotheken laden
import machine
import time
# Schwellwerte (Hysterese)
UPPER_THRESHOLD = 2.0
LOWER_THRESHOLD = 1.5
shaking = False # Status merken
# Onboard-LED initialisieren
led = machine.Pin('LED', machine.Pin.OUT, value=0)
# MPU-6050 über I2C initialisieren
mpu = machine.I2C(0, scl=machine.Pin(21), sda=machine.Pin(20), freq=100000)
mpu.writeto_mem(0x68, 0x6B, b'\x00') # Wake up MPU-6050
# Funktion: Daten von MPU-6050 lesen
def read_accel():
data = mpu.readfrom_mem(0x68, 0x3B, 6)
ax = int.from_bytes(data[0:2], 'big') if data[0] < 0x80 else int.from_bytes(data[0:2], 'big') - 65536
ay = int.from_bytes(data[2:4], 'big') if data[2] < 0x80 else int.from_bytes(data[2:4], 'big') - 65536
az = int.from_bytes(data[4:6], 'big') if data[4] < 0x80 else int.from_bytes(data[4:6], 'big') - 65536
return ax / 16384, ay / 16384, az / 16384 # in g
# Hauptprogramm: Endlos-Schleife
while True:
# Sensor-Werte lesen
ax, ay, az = read_accel()
total = abs(ax) + abs(ay) + abs(az)
# Schwellwerte vergleichen
if not shaking and total > UPPER_THRESHOLD:
shaking = True
print(f"{total:.3f}", 'SHAKE', end="\r")
led.on()
time.sleep(.5)
elif shaking and total < LOWER_THRESHOLD:
shaking = False
print(f"{total:.3f}", '', end=" \r")
led.off()
#time.sleep(1) # Unterer Schwellwert herausfinden
else:
print(f"{total:.3f}", '', end=" \r")
time.sleep(.1)
Problem
Wenn der MPU-6050 am Umkehrpunkt einer Schüttelbewegung misst (z. B. ganz links oder rechts am Ende der Schwingung), dann ist die Geschwindigkeit dort Null oder nahezu Null, und die Beschleunigung kann – je nach Timing - auch klein oder scheinbar „normal“ sein. Dann sehen die Messwerte so aus, als ob gerade kein Schütteln stattfindet – obwohl du es deutlich in der Hand spürst.
Programmcode: Lösung mit Kombination aus Accelerometer und Gyroskop
Statt auf die absolute Beschleunigung oder Geschwindigkeit zu schauen, wird in diesem Programmcode, die schnelle Änderung der Bewegung betrachtet. Zusätzlich wird die Schüttelerkennung noch mit dem Gyroskop abgesichert.
# Bibliotheken laden
import machine
import time
# Schwellwerte (Hysterese)
UPPER_THRESHOLD = 0.4
LOWER_THRESHOLD = 0.02
GYRO_THRESHOLD = 300
# Anfangswerte
last_acc_total = 0
shaking = False
# Onboard-LED initialisieren
led = machine.Pin('LED', machine.Pin.OUT, value=0)
# MPU-6050 über I2C initialisieren
mpu = machine.I2C(0, scl=machine.Pin(21), sda=machine.Pin(20), freq=100000)
mpu.writeto_mem(0x68, 0x6B, b'\x00') # Wake up MPU-6050
# Funktion: Daten von MPU-6050 lesen
def read_accel():
data = mpu.readfrom_mem(0x68, 0x3B, 6)
ax = int.from_bytes(data[0:2], 'big') if data[0] < 0x80 else int.from_bytes(data[0:2], 'big') - 65536
ay = int.from_bytes(data[2:4], 'big') if data[2] < 0x80 else int.from_bytes(data[2:4], 'big') - 65536
az = int.from_bytes(data[4:6], 'big') if data[4] < 0x80 else int.from_bytes(data[4:6], 'big') - 65536
return ax / 16384, ay / 16384, az / 16384 # in g
def read_gyro():
data = mpu.readfrom_mem(0x68, 0x43, 6)
gx = int.from_bytes(data[0:2], 'big') if data[0] < 0x80 else int.from_bytes(data[0:2], 'big') - 65536
gy = int.from_bytes(data[2:4], 'big') if data[2] < 0x80 else int.from_bytes(data[2:4], 'big') - 65536
gz = int.from_bytes(data[4:6], 'big') if data[4] < 0x80 else int.from_bytes(data[4:6], 'big') - 65536
return gx / 131, gy / 131, gz / 131 # in °/s
# Hauptprogramm: Endlos-Schleife
while True:
# Sensor-Werte lesen
ax, ay, az = read_accel()
acc_total = ax * ax + ay * ay + az * az
delta_acc = abs(acc_total - last_acc_total)
last_acc_total = acc_total
# Unterstützung vom Gyroskop
gx, gy, gz = read_gyro()
gyro_total = int(abs(gx)) + int(abs(gy)) + int(abs(gz))
# Schwellwerte vergleichen
if delta_acc > UPPER_THRESHOLD or gyro_total > GYRO_THRESHOLD:
shaking = True
print(f"{delta_acc:.3f}", gyro_total, 'SHAKE', end=" \r")
led.on()
time.sleep(.2)
elif shaking and delta_acc < LOWER_THRESHOLD:
shaking = False
print(f"{delta_acc:.3f}", gyro_total, '', end=" \r")
led.off()
#time.sleep(1) # Unterer Schwellwert herausfinden
else:
print(f"{delta_acc:.3f}", gyro_total, '', end=" \r")
time.sleep(.01)
Lösung mit KI?
Nicht zu frieden mit der Erkennungsleistung? Vielleicht klappt es besser mit künstlicher Intelligenz (KI). Zeichne die Schüttelbewegung auf. Trainiere mit den Daten ein neuronales Netz und führe an Live-Daten die Bewegungsklassifizierung durch. Und das alles auf dem Raspberry Pi Pico mit dem selben Aufbau.
Weitere verwandte Themen:
- Raspberry Pi Pico: MPU-6050 programmieren
- Raspberry Pi Pico: Bewegung und Erschütterung erkennen mit dem MPU-6050
- Raspberry Pi Pico: Schütteln erkennen mit dem MPU-6050
- Raspberry Pi Pico: Diebstahl erkennen mit dem MPU-6050
Frag Elektronik-Kompendium.de
Hardware-nahes Programmieren mit dem Raspberry Pi Pico und MicroPython
Das Elektronik-Set Pico Edition ist ein Bauteile-Sortiment mit Anleitung zum Experimentieren und Programmieren mit MicroPython.
- LED: Einschalten, ausschalten, blinken und Helligkeit steuern
- Taster: Entprellen und Zustände anzeigen
- LED mit Taster einschalten und ausschalten
- Ampel- und Lauflicht-Steuerung
- Elektronischer Würfel
- Eigene Steuerungen programmieren
Online-Workshop: Programmieren mit dem Raspberry Pi Pico
Gemeinsam mit anderen und unter Anleitung experimentieren? Wir bieten unterschiedliche Online-Workshops zum Raspberry Pi Pico und MicroPython an. Einführung in die Programmierung, Sensoren programmieren und kalibrieren, sowie Internet of Things und Smart Home über WLAN und MQTT.
Besuchen Sie unser fast monatlich stattfindendes Online-Meeting PicoTalk und lernen Sie uns kennen. Die Teilnahme ist kostenfrei.






