Bemerkung
Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauche tiefer in Raspberry Pi, Arduino und ESP32 mit anderen Technikbegeisterten ein.
Warum beitreten?
Expertenunterstützung: Löse Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.
Lernen & Teilen: Tausche Tipps und Tutorials aus, um deine Fähigkeiten zu verbessern.
Exklusive Vorschauen: Erhalte frühzeitigen Zugriff auf neue Produktankündigungen und Sneak Peeks.
Spezielle Rabatte: Profitiere von exklusiven Rabatten auf unsere neuesten Produkte.
Festliche Aktionen und Gewinnspiele: Nimm an Gewinnspielen und saisonalen Aktionen teil.
👉 Bereit, mit uns zu experimentieren und zu erschaffen? Klicke auf [hier] und tritt noch heute bei!
7.12 Bau einer digitalen Wasserwaage
In diesem Projekt erstellen wir eine digitale Wasserwaage mit dem Raspberry Pi Pico 2, einem MPU6050-Beschleunigungs- und Gyroskopsensor sowie einer 8x8-LED-Matrix, die über zwei 74HC595-Schieberegister gesteuert wird. Dieses Gerät funktioniert ähnlich wie eine herkömmliche Wasserwaage und zeigt die Neigung einer Oberfläche an. Je nach Neigung des MPU6050 bewegt sich eine auf der LED-Matrix dargestellte „Blase“ entsprechend und ermöglicht eine visuelle Anzeige der Ebenheit.
Benötigte Komponenten
Für dieses Projekt benötigen wir die folgenden Komponenten.
Es ist definitiv praktisch, ein komplettes Kit zu kaufen, hier ist der Link:
Name |
ENTHALTENE TEILE |
LINK |
|---|---|---|
Newton Lab Kit |
450+ |
Du kannst sie auch einzeln über die folgenden Links kaufen.
SN |
KOMPONENTE |
MENGE |
LINK |
|---|---|---|---|
1 |
1 |
||
2 |
Micro-USB-Kabel |
1 |
|
3 |
1 |
||
4 |
Mehrere |
||
5 |
1 |
||
6 |
2 |
||
7 |
1 |
Verständnis der Komponenten
MPU6050 Beschleunigungssensor und Gyroskop: Liefert Beschleunigungs- und Rotationsdaten entlang der X-, Y- und Z-Achsen, die zur Berechnung der Neigungswinkel verwendet werden.
8x8-LED-Matrix: Ein Raster aus LEDs, das es ermöglicht, Muster oder Bilder darzustellen, indem einzelne LEDs gesteuert werden.
74HC595 Schieberegister: Ermöglichen die Steuerung mehrerer Ausgänge (in diesem Fall Zeilen und Spalten der LED-Matrix) mit nur wenigen GPIO-Pins des Pico.
Schaltplan
Der MPU6050 erfasst die Beschleunigungswerte in jeder Richtung und berechnet den Neigungswinkel.
Basierend auf diesen Daten zeichnet das Programm einen 2x2-Pixel-Punkt auf der LED-Matrix mithilfe der beiden 74HC595-Chips.
Wenn sich der Neigungswinkel ändert, sendet das Programm unterschiedliche Daten an die 74HC595-Chips, wodurch sich die Position des Punkts ändert und ein „Blaseneffekt“ entsteht.
Verdrahtung
Code schreiben
Wir schreiben ein MicroPython-Skript, das:
Die Beschleunigungsdaten vom MPU6050 liest.
Die Neigungswinkel entlang der X- und Y-Achsen berechnet.
Die Neigungswinkel auf Positionen der 8x8-LED-Matrix abbildet.
Eine „Blase“ (eine 2x2-Pixel-Darstellung) anzeigt, die sich entsprechend der Neigung bewegt.
Bemerkung
Öffne
7.12_digital_bubble_level.pyausnewton-lab-kit/micropythonoder kopiere den Code in Thonny und klicke dann auf „Run“ oder drücke F5.Stelle sicher, dass der richtige Interpreter ausgewählt ist: MicroPython (Raspberry Pi Pico).COMxx.
Hier benötigst du die Bibliotheken
imu.pyundvector3d.py. Überprüfe, ob sie bereits auf den Pico hochgeladen wurden. Eine detaillierte Anleitung findest du unter Bibliotheken auf den Pico hochladen.
import machine
from machine import I2C, Pin
import time
import math
from imu import MPU6050
# Initialisierung der I2C-Kommunikation mit dem MPU6050-Sensor
i2c = I2C(1, sda=Pin(6), scl=Pin(7), freq=400000)
mpu = MPU6050(i2c)
# Funktion zur Berechnung der Distanz zwischen zwei Punkten
def dist(a, b):
return math.sqrt((a * a) + (b * b))
# Funktion zur Berechnung der Rotation entlang der y-Achse
def get_y_rotation(x, y, z):
radians = math.atan2(x, dist(y, z))
return -math.degrees(radians)
# Funktion zur Berechnung der Rotation entlang der x-Achse
def get_x_rotation(x, y, z):
radians = math.atan2(y, dist(x, z))
return math.degrees(radians)
# Funktion zur Ermittlung der aktuellen Winkel vom MPU6050-Sensor
def get_angle():
y_angle = get_y_rotation(mpu.accel.x, mpu.accel.y, mpu.accel.z)
x_angle = get_x_rotation(mpu.accel.x, mpu.accel.y, mpu.accel.z)
return x_angle, y_angle
# Initialisierung der Schieberegister-Pins zur Steuerung der LED-Matrix
sdi = machine.Pin(18, machine.Pin.OUT)
rclk = machine.Pin(19, machine.Pin.OUT)
srclk = machine.Pin(20, machine.Pin.OUT)
# Funktion, um Daten ins Schieberegister zu schieben
def hc595_in(dat):
for bit in range(7, -1, -1):
srclk.low()
time.sleep_us(30)
sdi.value(1 & (dat >> bit))
time.sleep_us(30)
srclk.high()
# Funktion, um die Daten vom Schieberegister auf die LED-Matrix auszugeben
def hc595_out():
rclk.high()
time.sleep_us(200)
rclk.low()
# Funktion zur Anzeige eines Glyphs (8x8-Matrix) auf der LED-Matrix
def display(glyph):
for i in range(0, 8):
hc595_in(glyph[i])
hc595_in(0x80 >> i)
hc595_out()
# Konvertierung einer 2D-Matrix in ein Glyph, das auf der LED-Matrix angezeigt werden kann
def matrix_2_glyph(matrix):
glyph = [0 for i in range(8)]
for i in range(8):
for j in range(8):
glyph[i] += matrix[i][j] << j
return glyph
# Klemmen eines Werts zwischen einem festgelegten Minimum und Maximum
def clamp_number(val, min_val, max_val):
return min_val if val < min_val else max_val if val > max_val else val
# Abbilden eines Werts von einem Bereich auf einen anderen
def interval_mapping(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
# Berechnung der Position der Blase in der Matrix basierend auf den MPU6050-Lesungen
sensitivity = 4 # Empfindlichkeit der Blasenbewegung
matrix_range = 7 # Die Matrixgröße ist 8x8, also ist der Bereich 0-7
point_range = matrix_range - 1 # Die Position der Blase sollte zwischen 0 und 6 liegen
# Funktion zur Berechnung der Position der Blase basierend auf Sensordaten
def bubble_position():
y, x = get_angle() # Erhalten der aktuellen Rotationswinkel
x = int(clamp_number(interval_mapping(x, 90, -90, 0 - sensitivity, point_range + sensitivity), 0, point_range))
y = int(clamp_number(interval_mapping(y, -90, 90, point_range + sensitivity, 0 - sensitivity), 0, point_range))
return [x, y]
# Fallenlassen der Blase (dargestellt durch das Ausschalten von 2x2 LEDs) in die Matrix
def drop_bubble(matrix, bubble):
matrix[bubble[0]][bubble[1]] = 0
matrix[bubble[0] + 1][bubble[1]] = 0
matrix[bubble[0]][bubble[1] + 1] = 0
matrix[bubble[0] + 1][bubble[1] + 1] = 0
return matrix
# Hauptschleife
while True:
matrix = [[1 for i in range(8)] for j in range(8)] # Erstellen einer leeren Matrix (alle LEDs an)
bubble = bubble_position() # Erhalten der aktuellen Blasenposition basierend auf Sensordaten
matrix = drop_bubble(matrix, bubble) # Fallenlassen der Blase in die Matrix
display(matrix_2_glyph(matrix)) # Anzeigen der Matrix auf dem LED-Gitter
time.sleep(0.1) # Kleine Verzögerung, um Aktualisierungen zu verlangsamen
Wenn der Code ausgeführt wird, platziere die Schaltung auf einer ebenen Fläche. Die Blase (ein 2x2-Pixel-Bereich) sollte sich im Zentrum der LED-Matrix befinden. Neige das Breadboard oder das MPU6050-Modul. Beobachte, wie sich die Blase auf der LED-Matrix in Richtung der Neigung bewegt und eine echte Wasserwaage simuliert.
Verständnis des Codes
Dieser Code liest Daten von einem MPU6050-Beschleunigungs- und Gyroskopsensor, um die Neigung des Geräts zu bestimmen, und zeigt eine „Blase“ auf einer 8x8-LED-Matrix an, die eine digitale Wasserwaage simuliert.
Importe und Initialisierung:
machine: Zugriff auf die Hardwarekomponenten des Mikrocontrollers.I2C,Pin: Für I2C-Kommunikation und GPIO-Pin-Steuerung.time: Zeitfunktionen für Verzögerungen.math: Mathematische Funktionen für Berechnungen.MPU6050ausimu: Bibliothek zur Schnittstelle mit dem MPU6050-Sensor.
I2C-Initialisierung:
Einrichtung der I2C-Kommunikation mit SDA auf Pin 6 und SCL auf Pin 7.
Die Frequenz wird auf 400 kHz für eine schnelle Datenübertragung eingestellt.
Ein
mpu-Objekt wird erstellt, um mit dem MPU6050-Sensor zu kommunizieren.
Mathematische Funktionen:
dist(a, b):Berechnet die euklidische Distanz zwischen zwei Werten.
Wird zur Berechnung der Größe der Komponenten in den Winkelberechnungen verwendet.
get_y_rotation(x, y, z):Berechnet die Rotation um die Y-Achse in Grad.
Nutzt
math.atan2, um den Arkustangens von x und der Distanz zwischen y und z zu berechnen.Das Ergebnis wird negiert, um die gewünschte Ausrichtung zu erhalten.
get_x_rotation(x, y, z):Berechnet die Rotation um die X-Achse in Grad.
Ähnlich wie
get_y_rotation, aber mit Berechnung des Arkustangens von y und der Distanz zwischen x und z.
get_angle():Ruft die aktuellen Beschleunigungsdaten vom MPU6050-Sensor ab.
Berechnet die X- und Y-Rotationswinkel basierend auf den Beschleunigungswerten.
Schieberegister-Funktionen:
Pin-Definitionen:
sdi: Serial Data Input (Pin 18).rclk: Register Clock (Latch) (Pin 19).srclk: Shift Register Clock (Pin 20).
hc595_in(dat):Schiebt ein 8-Bit-Datenbyte in das Schieberegister.
Iteriert über jedes Bit vom MSB zum LSB.
Steuert
srclkundsdi, um die Bits in das Register zu schieben.
hc595_out():Latcht die Daten vom Schieberegister auf die Ausgänge.
Kippt das
rclk-Signal, um die Daten auszugeben.
LED-Matrix-Anzeigefunktionen:
display(glyph):Zeigt ein 8x8-Glyph auf der LED-Matrix an.
Iteriert durch jede Zeile des Glyphs.
Verschiebt die Zeilendaten und den entsprechenden Spaltenselektor.
Ruft
hc595_out()auf, um die Anzeige zu aktualisieren.
matrix_2_glyph(matrix):Wandelt eine 8x8 2D-Matrix von 0en und 1en in ein 8-Byte-Glyph um.
Jedes Byte im Glyph repräsentiert eine Zeile in der LED-Matrix.
Bits in jedem Byte entsprechen den LEDs in dieser Zeile.
Hilfsfunktionen:
clamp_number(val, min_val, max_val):Stellt sicher, dass
valinnerhalb des angegebenen Bereichs bleibt.Verhindert, dass die Blase sich außerhalb der LED-Matrix bewegt.
interval_mapping(x, in_min, in_max, out_min, out_max):Ordnet einen Wert
xvon einem numerischen Bereich auf einen anderen zu.Wird verwendet, um Winkelmessungen in Matrixpositionen zu übersetzen.
Blasen-Positionsberechnung:
Empfindlichkeitseinstellungen:
sensitivity = 4: Bestimmt, wie empfindlich die Blase auf Neigungsänderungen reagiert.matrix_range = 7: Der maximale Index für die 8x8-Matrix (0 bis 7).point_range = matrix_range - 1: Angepasster Bereich, um die Blase innerhalb der Grenzen zu halten (0 bis 6).
bubble_position():Ruft die aktuellen X- und Y-Rotationswinkel ab.
Ordnet die Winkel auf Positionen auf der LED-Matrix zu, indem
interval_mappingverwendet wird.Begrenzt die Positionen, um sicherzustellen, dass sie innerhalb der Matrix bleiben.
Blasen-Anzeigefunktion:
drop_bubble(matrix, bubble):Ändert die LED-Matrix, um die Blase an der angegebenen Position darzustellen.
Schaltet einen 2x2-Block von LEDs aus, der sich um die Blasenkoordinaten befindet.
Aktualisiert die Matrix, um den visuellen Effekt einer sich bewegenden Blase zu erzeugen.
Hauptschleife
Läuft kontinuierlich, um die Anzeige basierend auf den Sensoreingaben zu aktualisieren.
Initialisiert eine frische 8x8-Matrix mit allen eingeschalteten LEDs (Wert
1).Ruft die aktuelle Blasenposition von
bubble_position()ab.Aktualisiert die Matrix mit
drop_bubble(), um die neue Position der Blase anzuzeigen.Wandelt die Matrix mit
matrix_2_glyph()in ein Glyph um.Zeigt das Glyph auf der LED-Matrix mit
display()an.Wartet 0,1 Sekunden vor der Wiederholung, um die Aktualisierungsrate zu steuern.
Fehlersuche
LED-Matrix wird nicht korrekt angezeigt:
Überprüfe alle Verdrahtungen zwischen den Schieberegistern und der LED-Matrix.
Stelle sicher, dass die Schieberegister korrekt mit dem Pico verbunden sind.
Prüfe, ob die Konfiguration der gemeinsamen Anode oder Kathode deiner LED-Matrix mit der Code-Logik übereinstimmt.
Blasenbewegung ist inkorrekt:
Stelle sicher, dass der MPU6050 richtig angeschlossen und funktionsfähig ist.
Überprüfe, ob der MPU6050 korrekt ausgerichtet ist.
Programmfehler:
Stelle sicher, dass
imu.pyundvector3d.pykorrekt hochgeladen wurden.Prüfe den Code auf Tippfehler oder Einrückungsfehler.
Weiterführende Experimente
Empfindlichkeit anpassen:
Ändere die Skalierung der Winkel-zu-Matrix-Zuordnung, um die Blasenbewegung fein abzustimmen.
Anzeigeverbesserungen:
Ändere die Größe oder Form der Blase.
Füge visuelle Effekte wie Nachzieheffekte oder verschiedene Muster hinzu.
Kalibrierung hinzufügen:
Implementiere eine Kalibrierungsroutine, um einen Nullpunkt zu setzen, wenn das Gerät auf einer unebenen Oberfläche liegt.
Alternative Anzeigen:
Verwende ein OLED- oder LCD-Display, um numerische Winkelwerte zusätzlich zur visuellen Blase anzuzeigen.
Fazit
Du hast erfolgreich eine digitale Wasserwaage mit dem Raspberry Pi Pico 2 gebaut! Dieses Projekt zeigt, wie Beschleunigungsdaten genutzt werden können, um Orientierung und Neigung visuell darzustellen, und wie eine LED-Matrix-Anzeige mithilfe von Schieberegistern gesteuert wird.
Erweitere das Projekt mit zusätzlichen Funktionen oder integriere es in größere Systeme!

