Bemerkung
Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie mit anderen Enthusiasten tiefer in Raspberry Pi, Arduino und ESP32 ein.
Warum beitreten?
Expertenunterstützung: Lösen Sie Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.
Lernen & Teilen: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern.
Exklusive Vorschauen: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und Sneak Peeks.
Sonderrabatte: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
Festliche Aktionen und Gewinnspiele: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.
👉 Bereit, mit uns zu entdecken und zu gestalten? Klicken Sie auf [here] und treten Sie noch heute bei!
4.1 Kamera
Einführung
Dieses Projekt zeigt, wie Sie mit dem Raspberry Pi Zero ein einfaches Kamerasystem mit Auslösetaste erstellen können. Wenn Sie die Taste drücken, nimmt die Kamera ein Foto auf, und eine LED blinkt zur Bestätigung der Aktion. Dieses Projekt ist eine gute Möglichkeit, praktische Erfahrung mit GPIO-Steuerung und dem Raspberry-Pi-Kameramodul zu sammeln.
Was Sie benötigen
Für dieses Projekt werden die folgenden Komponenten benötigt:
KOMPONENTENBESCHREIBUNG |
KAUFLINK |
|---|---|
- |
|
Raspberry Pi |
- |
Schaltplan
Nachfolgend ist die GPIO-Pinbelegung für dieses Projekt dargestellt:
Verdrahtungsdiagramm
Um das Kameramodul bequem zu verwenden, wird Pan-Tilt montieren (für die Kamera) empfohlen.
Bemerkung
Das Zusammenbauen der Pan-Tilt-Halterung kann einige Pins verdecken. Daher wird empfohlen, sie nur bei Verwendung der Kamera zu montieren oder sie nach der Montage außen zu platzieren.
Folgen Sie diesem Verdrahtungsdiagramm, um die Schaltung aufzubauen:
Beispiel ausführen
Greifen Sie auf den Raspberry-Pi-Desktop zu:
Remote Desktop: Verwenden Sie VNC für eine vollständige Desktop-Umgebung.
Raspberry Pi Connect: Verwenden Sie Raspberry Pi Connect, um sicher über einen Browser auf Ihren Pi zuzugreifen.
Öffnen Sie ein Terminal und wechseln Sie in den Code-Ordner:
cd ~/ai-lab-kit/python
Führen Sie das Skript aus, um die Kamera zu starten:
sudo python3 4.1_Camera.py
Nach dem Start des Programms beginnt die Kamera zu arbeiten.
Drücken Sie die Taste, um ein Foto aufzunehmen:
Die LED leuchtet auf.
Ein Foto wird aufgenommen und im Ordner
Picturesgespeichert (zum Beispielphoto_001.jpg,photo_002.jpg).
Lassen Sie die Taste los:
Die LED erlischt.
Das Programm läuft weiter, bis Sie Ctrl + C drücken. Danach wird es ohne Fehlermeldung sauber beendet.
Bemerkung
Die QT-Vorschau erfordert eine Desktop-Umgebung. Wenn die Vorschau nicht gestartet werden kann (z. B. bei Zugriff über SSH), kann die Kamera dennoch Fotos aufnehmen und normal speichern.
Code
Hier ist der in diesem Projekt verwendete Python-Code:
#!/usr/bin/env python3
import os
import time
import threading
from picamera2 import Picamera2, Preview
from fusion_hat.pin import Pin, Mode, Pull
# Resolve the correct user's home directory (works with sudo)
REAL_USER = os.getenv("SUDO_USER") or os.getlogin()
USER_HOME = f"/home/{REAL_USER}"
PICTURES_DIR = os.path.join(USER_HOME, "Pictures")
os.makedirs(PICTURES_DIR, exist_ok=True)
# Initialize camera
camera = Picamera2()
camera.configure(camera.create_preview_configuration(main={"size": (800, 600)}))
# Photo counter with thread safety
photo_index = 1
photo_lock = threading.Lock()
# Track whether preview was started successfully
preview_started = False
# Initialize LED and button
led = Pin(17, mode=Mode.OUT)
button = Pin(4, mode=Mode.IN, pull=Pull.DOWN)
def take_photo():
"""Capture one photo and increment the index."""
global photo_index
with photo_lock:
filepath = os.path.join(PICTURES_DIR, f"photo_{photo_index:03d}.jpg")
print(f"\nCapturing: {filepath}")
camera.capture_file(filepath)
print("Saved.")
photo_index += 1
def main():
global preview_started
# Start preview only when a GUI display is available (remote SSH often has no DISPLAY)
preview_started = False
if os.getenv("DISPLAY"):
try:
camera.start_preview(Preview.QT)
preview_started = True
except Exception as e:
preview_started = False
print(f"Preview start failed (continue without preview): {e}")
else:
print("No DISPLAY detected (running headless without preview).")
camera.start()
print("Camera is running.")
print("Press the button to take a photo.")
print(f"Photos will be saved to: {PICTURES_DIR}")
print("Press Ctrl+C to exit.\n")
try:
while True:
if button.value(): # Button pressed (HIGH)
led.on() # LED on
take_photo() # Take photo
time.sleep(0.3) # Simple debounce (avoid multiple shots)
while button.value(): # Wait until button is released
time.sleep(0.01)
led.off() # LED off after release
time.sleep(0.01)
except KeyboardInterrupt:
print("\nExiting...")
finally:
# Turn off LED
try:
led.off()
except Exception:
pass
# Stop the camera first
try:
camera.stop()
except Exception:
pass
# Stop preview only if it was started
if preview_started:
try:
camera.stop_preview()
except Exception:
pass
try:
camera.close()
except Exception:
pass
if __name__ == "__main__":
main()
Code verstehen
Importe und Zweck
import os import time import threading from picamera2 import Picamera2, Preview from fusion_hat.pin import Pin, Mode, Pull
Diese Module sind für folgende Aufgaben zuständig:
os: zum Umgang mit Umgebungsvariablen und Dateipfaden.time: für Zeitverzögerungen und um die Hauptschleife am Laufen zu halten.threading: sorgt dafür, dass das Aufnehmen von Fotos thread-sicher erfolgt.Picamera2undPreview: zur Steuerung der Raspberry-Pi-Kamera und der Vorschau-Modi.Pin,ModeundPull: zur Steuerung der LED und zum Auslesen des Tasters über das Fusion HAT.
Bestimmen des Speicherverzeichnisses (funktioniert mit sudo)
REAL_USER = os.getenv("SUDO_USER") or os.getlogin() USER_HOME = f"/home/{REAL_USER}" PICTURES_DIR = os.path.join(USER_HOME, "Pictures") os.makedirs(PICTURES_DIR, exist_ok=True)
Dieser Abschnitt stellt sicher, dass Fotos immer im Verzeichnis
~/Picturesdes tatsächlichen Benutzers gespeichert werden:Wenn das Skript mit
sudoausgeführt wird, verweistSUDO_USERauf den ursprünglichen Benutzer.Wenn
sudonicht verwendet wird, wird der aktuell angemeldete Benutzer verwendet.Der Ordner
Pictureswird automatisch erstellt, falls er noch nicht existiert.
Initialisierung und Konfiguration der Kamera
camera = Picamera2() camera.configure(camera.create_preview_configuration(main={"size": (800, 600)}))
Die Kamera wird initialisiert und für Vorschau und Fotoaufnahme konfiguriert:
Es wird eine Vorschauauflösung von
800 × 600verwendet.Diese Konfiguration funktioniert sowohl mit als auch ohne sichtbares Vorschaufenster.
Fotoindex und Thread-Sicherheit
photo_index = 1 photo_lock = threading.Lock()
photo_indexspeichert die aktuelle Bildnummer.photo_lockverhindert, dass mehrere Tastendrücke gleichzeitig überlappende Fotoaufnahmen auslösen.
Status der Vorschau
preview_started = False
Dieses Flag speichert, ob ein Vorschaufenster erfolgreich gestartet wurde, sodass das Programm nur dann versucht, die Vorschau zu beenden, wenn sie tatsächlich existiert.
LED- und Tasterkonfiguration
led = Pin(17, mode=Mode.OUT) button = Pin(4, mode=Mode.IN, pull=Pull.DOWN)
Die LED ist mit GPIO 17 verbunden und als Ausgang konfiguriert.
Der Taster ist mit GPIO 4 verbunden und als Eingang mit internem Pull-Down-Widerstand konfiguriert.
Ein HIGH-Signal bedeutet, dass die Taste gedrückt wurde.
Funktion zum Aufnehmen eines Fotos
def take_photo(): """Capture one photo and increment the index.""" global photo_index with photo_lock: filepath = os.path.join(PICTURES_DIR, f"photo_{photo_index:03d}.jpg") print(f"\nCapturing: {filepath}") camera.capture_file(filepath) print("Saved.") photo_index += 1
Diese Funktion:
erstellt einen Dateinamen wie
photo_001.jpg.nimmt ein Bild mit der Kamera auf.
erhöht den Fotoindex, sodass das nächste Bild einen neuen Namen erhält.
Bedingte Vorschau für lokale und entfernte Nutzung
preview_started = False if os.getenv("DISPLAY"): try: camera.start_preview(Preview.QT) preview_started = True except Exception as e: preview_started = False print(f"Preview start failed (continue without preview): {e}") else: print("No DISPLAY detected (running headless without preview).")
Wenn eine grafische Desktop-Umgebung verfügbar ist, wird eine QT-Vorschau gestartet.
Wenn das Programm über SSH ohne Anzeige ausgeführt wird, wird die Vorschau übersprungen.
Die Fotoaufnahme funktioniert in beiden Fällen normal.
Hauptschleife und Tasterlogik
try: while True: if button.value(): # Button pressed (HIGH) led.on() # LED on take_photo() # Take photo time.sleep(0.3) # Simple debounce (avoid multiple shots) while button.value(): # Wait until button is released time.sleep(0.01) led.off() # LED off after release time.sleep(0.01)
Innerhalb der Hauptschleife:
Beim Drücken der Taste wird die LED eingeschaltet.
Sofort wird ein Foto aufgenommen.
Das Programm wartet, bis die Taste losgelassen wird, um Mehrfachaufnahmen zu vermeiden.
Nach dem Loslassen der Taste wird die LED ausgeschaltet.
Sauberes Beenden und Freigabe der Ressourcen
except KeyboardInterrupt: print("\nExiting...") finally: # Turn off LED try: led.off() except Exception: ...
Wenn
Ctrl+Cgedrückt wird:Die LED wird ausgeschaltet.
Die Kamerapipeline wird gestoppt.
Die Vorschau wird nur beendet, wenn sie zuvor gestartet wurde.
Die Kameraressourcen werden sauber freigegeben.
Dadurch wird sichergestellt, dass das Programm ohne Fehler beendet wird – sowohl bei lokaler Ausführung mit Bildschirm als auch im Headless-Modus.
Fehlerbehebung
Foto wird nicht aufgenommen:
Ursache: Der Taster ist falsch angeschlossen oder die Kamera wurde nicht initialisiert.
Lösung:
Stellen Sie sicher, dass der Taster mit GPIO-Pin 4 und GND verbunden ist.
Prüfen Sie, ob die Kamera korrekt angeschlossen und über
raspi-configaktiviert ist.
LED blinkt nicht:
Ursache: Falsche Verdrahtung der LED oder falsche GPIO-Konfiguration.
Lösung:
Stellen Sie sicher, dass die LED mit GPIO-Pin 17 über einen passenden Widerstand verbunden ist.
Testen Sie die LED separat, um sicherzustellen, dass sie funktioniert.
Skript stürzt mit einem Kamerafehler ab:
Ursache: Das Kameramodul wird nicht erkannt oder wird von einem anderen Prozess verwendet.
Lösung:
Stellen Sie sicher, dass die Kamera korrekt angeschlossen ist, und starten Sie den Raspberry Pi neu.
Prüfen Sie auf Konflikte mit
sudo lsof /dev/video*.
Erweiterungsideen
Mehrere Fotos: Erlauben Sie das Aufnehmen mehrerer Fotos in einer Sitzung, jeweils mit einem eindeutigen Dateinamen:
counter = 0 camera.capture_file(f'{user_home}/photo_{counter}.jpg') counter += 1
Videoaufnahme: Erweitern Sie die Funktion, sodass beim Drücken der Taste ein Video aufgenommen wird:
camera.start_recording(f'{user_home}/my_video.h264') time.sleep(10) camera.stop_recording()
LED-Statusanzeige: Verwenden Sie die LED, um den Status der Kamera anzuzeigen:
Dauerlicht: Kamera bereit.
Blinken: Foto wird aufgenommen.
Fotoverwaltung: Organisieren Sie aufgenommene Fotos in Ordnern nach Datum oder Ereignis.
Zeitrafferfotografie: Nehmen Sie in regelmäßigen Abständen Fotos auf, um einen Zeitraffer zu erstellen:
for i in range(10): camera.capture_file(f'{user_home}/timelapse_{i}.jpg') time.sleep(5)
Fazit
Dieses Projekt zeigt eine grundlegende Kameraanwendung mit einem tastergesteuerten Auslösemechanismus. Es kombiniert GPIO-Steuerung mit der Picamera2-Bibliothek und demonstriert, wie interaktive Raspberry-Pi-Projekte erstellt werden können. Experimentieren Sie weiter, um zusätzliche Funktionen zu integrieren und noch vielseitigere Anwendungen zu entwickeln.