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.