probelehrveranstaltung_april2023
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
probelehrveranstaltung_april2023 [2024/03/06 05:23] – [purrfelinus alpha – Von der Konzepskizze zum Prototypen] Felix Hardmood Beck | probelehrveranstaltung_april2023 [2024/11/21 17:05] (current) – removed Felix Hardmood Beck | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Teil 1: Lehrveranstaltung zu einem Thema der Mediengestaltung ====== | ||
- | |||
- | {{: | ||
- | |||
- | ^Dauer | ||
- | |05 min |Einleitung/ | ||
- | |15 min |Vorstellung Thema | | ||
- | |05 min |Demonstration | ||
- | |15 min |Kurze Übung | ||
- | |05 min |Vorstellung einiger Ergebnisse aus Übung | ||
- | |05 min |Zusammenfassung, | ||
- | |||
- | ====== Teil 2: Präsentation eines medialen Produktes ====== | ||
- | |||
- | Geplanter Aufbau | ||
- | |||
- | ^Dauer | ||
- | |05 min |Herleitung und Konzept (Skizzen, 3D-Visualisierung) | ||
- | |05 min |Einblick in Entwicklung des Prototypen (Hardware, Software)| | ||
- | |05 min |Demonstration | ||
- | |02 min |Fazit | ||
- | |03 min |Fragen | ||
- | |||
- | Die Basis für das "//auf kreative Weise gestaltete Produkt auf Basis eines Raspberry Pi//" bildet ein Gehäuse mit einem integrierten E27-Gewinde. Hiermit kann das Objekt in jedem Zuhause in ein handelsübliches Lampengewinde eingesetzt und betrieben werden. Betätigt man den entsprechenden Lichtschalter startet das integrierte Raspberry Pi. Die auf der unteren Seite revisionierbare und anpassbare Fläche läßt diverse Möglichkeiten zu eigene Hardware zu ergänzen und zu betreiben. Es sind unendlich viele Anwendungsmöglichkeiten denkbar. Was wäre Ihre Idee? | ||
- | |||
- | |||
- | |||
- | Personalisierbare farbige Ringe (siehe [[https:// | ||
- | |||
- | ===== purrfelinus alpha – Von der Konzepskizze zum Prototypen ===== | ||
- | |||
- | Ein Beispiel für eine mögliche Anwendung ist **purrfelinus alpha** (({{: | ||
- | |||
- | {{: | ||
- | Der Laserstrahl im rechten oberen Bild wurde in Photoshop eingefügt. | ||
- | |||
- | Benutzer*innen können auf einer Webseite einen Kamerastream in Echtzeit anschauen. Über die geöffnete Webseite kann man dann über ein Webinterface mit seiner Katze interagieren. Dabei wird ein Schieberegler verwendet, der die Bewegung eines Servomotors steuert, der mit einem Laserpointer verbunden ist und diesen bewegt. Im Kamerabild sieht man den Laserpointer und die Katze. | ||
- | |||
- | Das Konzept ist inspiriert durch [[https:// | ||
- | |||
- | Das Objekt // | ||
- | |||
- | * Raspberry Pi 4 ((Zu beziehen bspw. von [[https:// | ||
- | * Raspberry Pi 4 Kamera Modul (Rev. 1.3)((Zu beziehen bspw. von [[https:// | ||
- | * Servomotor SG 90(((Zu beziehen bspw. von [[https:// | ||
- | * 2x Netzteil 5.1V, 3A(((Zu beziehen bspw. von [[https:// | ||
- | * E27-Gewinde (ausgebaut aus einer LED-Birne) | ||
- | * 3D gedruckte Bauteile (siehe Dokumentation weiter unten) | ||
- | |||
- | Neben den entsprechenden Treibern und notwendigen Updates kommen folgende Software Module in // | ||
- | |||
- | * **Flask** | ||
- | * **roundSlider** | ||
- | ---- | ||
- | |||
- | ==== Stromversorgung via E27 Gewinde und modifiziertes 5.1V Netzteil ==== | ||
- | |||
- | **Bitte unbedingt folgendes beachten: | ||
- | |||
- | {{ : | ||
- | |||
- | Wenn Sie ein Projekt mit hohen Stromspannungen planen, sollten Sie sich immer an erfahrene Fachleute wenden und immer geeignete Sicherheitsvorkehrungen und Schutzmaßnahmen treffen, um ein sicheres Arbeitsumfeld zu gewährleisten. Suchen Sie entsprechende Labore auf. Bitte denken Sie daran, dass Ihre Gesundheit und Sicherheit immer Vorrang haben sollten, und seien Sie immer vorsichtig, wenn Sie mit elektrischen Komponenten arbeiten. | ||
- | |||
- | Beim Bau des Prototypen wurde eine E27-Fassung als Schnittstelle zur Stromzufuhr verwendet. Diese wurde aus einer defekten LED-Glühbirne ausgebaut. Es wurde sichergestellt, | ||
- | |||
- | {{: | ||
- | |||
- | Als erstes wurden alle Teile der LED-Birne, die nicht am Gewinde befestigt waren, einschließlich der elektrischen Komponenten und der Platine entfernt. Dafür wurde in einem ersten Schritt der transluzent/ | ||
- | |||
- | {{: | ||
- | |||
- | Die abgeschnittenen Plastikteile und die defekte LED-Platine, | ||
- | |||
- | Außen- und Neutralleiter werden über eine Dosen- und eine Lüsterklemme mit einem kleinen USB-C Netzteil (5.1V, 3A) verbunden. An dieser Stelle muss nochmals auf obige <hi # | ||
- | |||
- | {{: | ||
- | |||
- | ==== Entwicklung des Gehäuses (CAD, CAM) ==== | ||
- | |||
- | Die in den unteren Bildern dargestellten und herunter-ladbaren *.stl-Dateien sind mit der webbasierten Software [[https:// | ||
- | |||
- | Die nachfolgenden Iterationen geben einen Überblick zu den einzelnen Entwicklungsschritten, | ||
- | |||
- | === Iteration 1 === | ||
- | |||
- | {{ : | ||
- | |||
- | * Download [[http:// | ||
- | * Download [[http:// | ||
- | |||
- | ---- | ||
- | |||
- | === Iteration 2 === | ||
- | |||
- | {{ : | ||
- | |||
- | * Download [[http:// | ||
- | |||
- | ---- | ||
- | |||
- | === Iteration 3 === | ||
- | |||
- | {{: | ||
- | |||
- | * Download [[http:// | ||
- | |||
- | {{: | ||
- | |||
- | * Download [[http:// | ||
- | * Download [[http:// | ||
- | |||
- | {{: | ||
- | |||
- | * Download [[http:// | ||
- | |||
- | {{: | ||
- | |||
- | * Download [[http:// | ||
- | |||
- | {{: | ||
- | |||
- | * Download [[http:// | ||
- | * Download [[http:// | ||
- | * Download [[http:// | ||
- | |||
- | ==== Integration von Hardware ==== | ||
- | |||
- | {{: | ||
- | |||
- | ==== Realisierung Software Sketch ==== | ||
- | |||
- | Benutzer*innen können auf einer Webseite einen Kamerastream in Echtzeit anschauen. Auf der geöffneten Webseite soll man über das Webinterface mit seiner Katze interagieren können. Dabei wird ein Schieberegler verwendet, der die Bewegung eines Servomotors steuert, an dem ein Laserpointer befestigt ist. Im live-Bild der Kamera soll man letztendlich den Laserpointer-Punkt und die Katze sehen. | ||
- | |||
- | In den unteren Screenshots sieht man die Ausrichtung des Laserpointers passend zum eingestellten Winkel. In beiden Screenshots jeweils links ein Winkel von 48°, in beiden Bildern jeweils rechts ein Winkel von 135°. | ||
- | |||
- | {{: | ||
- | |||
- | Die Grundidee ist also die folgende: | ||
- | |||
- | - Benutzer*in öffnet die Webseite mit Kamerastream und UI-Element (Drehregler). | ||
- | - Benutzer*in ändert den Wert des runden Schiebereglers. | ||
- | - Die Webseite sendet den neuen Winkelwert an den Server. | ||
- | - Der Server empfängt den Winkelwert und steuert den Servomotor entsprechend. | ||
- | |||
- | === Datenfluss-Diagramm === | ||
- | |||
- | {{: | ||
- | |||
- | Obiges Datenfluss-Diagramm gibt einen Überblick, wie die verschiedenen Teile der Anwendung zusammenarbeiten, | ||
- | |||
- | === Schrittweise Erklärung des Codes === | ||
- | |||
- | Ähnlich wie bei der Hardware-Entwicklung auch, hat es einige Iterationen gebraucht, um einen akzeptablen Stand zum Laufen zu bringen. Bei der Entwicklung hat es geholfen, die einzelnen Komponenten für sich zu bearbeiten. So wurde erst mit dem Servo getestet, später mit dem Einzelnen Bestandteilen des Interfaces, etc. Das Gesamtpaket wurde in kleinere Aufgaben zerteilt, von der jedes Teil für sich alleine getestet werden konnte. Erst später wurden die einzelnen Bestandteile mit Hilfe von [[wp> | ||
- | |||
- | - Importieren der erforderlichen Bibliotheken: | ||
- | - Definieren des Servo-Pins, der an GPIO-Pin 18 angeschlossen ist. | ||
- | - Erstellen einer pigpio-Instanz und Setzen des Servo-Pins auf output. | ||
- | - Erstellen einer Flask-App-Instanz. | ||
- | - Initialisieren der globalen Variable current_angle auf 0, um den aktuellen Winkel des Servomotors zu speichern. | ||
- | - Definition der gen_frames()-Funktion, | ||
- | - Definition einer Route / | ||
- | - Definition der Haupt-Route /, die eine index.html-Datei aus dem Vorlagenverzeichnis rendert. | ||
- | - Definition der angle_to_pulse_width()-Funktion, | ||
- | - Definition der set_servo_angle_slowly()-Funktion, | ||
- | - Definition einer Route /set_angle, die den Servo-Winkel einstellt, wenn sie über eine POST-Anfrage aufgerufen wird. | ||
- | - Ausführen der Flask-App und anschließendes Beenden des Servomotors und der pigpio-Instanz, | ||
- | |||
- | === Python Code === | ||
- | |||
- | Wie im vorherigen Absatz beschrieben, | ||
- | |||
- | ++++ Python Quell-Code ein-/ | ||
- | < | ||
- | |||
- | |||
- | # Nicht vergessen "sudo pigpiod" | ||
- | |||
- | from flask import Flask, render_template, | ||
- | import pigpio | ||
- | import cv2 | ||
- | import time | ||
- | |||
- | servo_pin = 18 | ||
- | |||
- | # Erstellen der pigpio-Instanz | ||
- | pi = pigpio.pi() | ||
- | |||
- | # Setze den Modus des Servo-Pins auf OUTPUT | ||
- | pi.set_mode(servo_pin, | ||
- | |||
- | app = Flask(__name__) | ||
- | |||
- | current_angle = 0 # Speichern des aktuellen Servo-Winkels | ||
- | |||
- | # Generator-Funktion zum Streamen der Videoframes | ||
- | def gen_frames(): | ||
- | camera = cv2.VideoCapture(0) | ||
- | scale_percent = 30 | ||
- | first_frame = True | ||
- | while True: | ||
- | success, frame = camera.read() | ||
- | if not success: | ||
- | break | ||
- | else: | ||
- | # Skalieren des Frames | ||
- | width = int(frame.shape[1] * scale_percent / 100) | ||
- | height = int(frame.shape[0] * scale_percent / 100) | ||
- | dim = (width, height) | ||
- | resized_frame = cv2.resize(frame, | ||
- | |||
- | # Frame-Auflösung beim ersten Frame ausgeben | ||
- | if first_frame: | ||
- | print(f" | ||
- | first_frame = False | ||
- | |||
- | # Kodiere den Frame als jpg | ||
- | ret, buffer = cv2.imencode(' | ||
- | frame = buffer.tobytes() | ||
- | yield (b' | ||
- | | ||
- | |||
- | # Route für den Videostream | ||
- | @app.route('/ | ||
- | def video_feed(): | ||
- | return Response(gen_frames(), | ||
- | mimetype=' | ||
- | |||
- | # Haupt-Route | ||
- | @app.route("/" | ||
- | def index(): | ||
- | return render_template(" | ||
- | |||
- | # Funktion zum Umrechnen von Winkeln in Pulsbreite | ||
- | def angle_to_pulse_width(angle): | ||
- | min_pulse_width = 600 | ||
- | max_pulse_width = 2300 | ||
- | pulse_width_range = max_pulse_width - min_pulse_width | ||
- | return int(min_pulse_width + (angle / 180.0) * pulse_width_range) | ||
- | |||
- | # Funktion, um den Servo schrittweise zu bewegen (Schritte und Geschwindigkeit) | ||
- | def set_servo_angle_slowly(servo_pin, | ||
- | global current_angle | ||
- | |||
- | while current_angle != target_angle: | ||
- | if current_angle < | ||
- | current_angle = min(current_angle + step_size, target_angle) | ||
- | else: | ||
- | current_angle = max(current_angle - step_size, target_angle) | ||
- | |||
- | pulse_width = angle_to_pulse_width(current_angle) | ||
- | pi.set_servo_pulsewidth(servo_pin, | ||
- | time.sleep(step_delay) | ||
- | |||
- | # Route zum Einstellen des Servo-Winkels | ||
- | @app.route("/ | ||
- | def set_angle(): | ||
- | angle = int(request.form[" | ||
- | set_servo_angle_slowly(servo_pin, | ||
- | return " | ||
- | |||
- | # Hauptprogramm | ||
- | if __name__ == " | ||
- | try: | ||
- | app.run(host=" | ||
- | finally: | ||
- | # Servo-Impuls aus und stop und Tschuess! | ||
- | pi.set_servo_pulsewidth(servo_pin, | ||
- | pi.stop() | ||
- | |||
- | </ | ||
- | |||
- | ++++ | ||
- | |||
- | === html Code === | ||
- | |||
- | ++++ html Quell-Code ein-/ | ||
- | < | ||
- | |||
- | |||
- | < | ||
- | <html lang=" | ||
- | < | ||
- | <meta charset=" | ||
- | <meta name=" | ||
- | < | ||
- | <link rel=" | ||
- | <script src=" | ||
- | <script src=" | ||
- | < | ||
- | body { | ||
- | margin: 0; | ||
- | padding: 0; | ||
- | overflow: hidden; | ||
- | } | ||
- | img { | ||
- | transform: rotate(270deg); | ||
- | position: absolute; | ||
- | top: 50%; | ||
- | left: 50%; | ||
- | min-height: 100%; | ||
- | min-width: 100vh; /* Verwenden Sie die Viewport-Höhe, | ||
- | object-fit: cover; | ||
- | object-position: | ||
- | z-index: -1; | ||
- | transform-origin: | ||
- | transform: translate(-50%, | ||
- | } | ||
- | |||
- | # | ||
- | position: absolute; | ||
- | bottom: 0; | ||
- | left: 50%; | ||
- | transform: translateX(-50%); | ||
- | z-index: 1; | ||
- | } | ||
- | |||
- | .rs-control .rs-range-color { | ||
- | background-color: | ||
- | } | ||
- | .rs-control .rs-path-color { | ||
- | background-color: | ||
- | } | ||
- | .rs-control .rs-handle { | ||
- | background-color:# | ||
- | } | ||
- | .rs-control .rs-bg-color { | ||
- | background-color: | ||
- | } | ||
- | |||
- | # | ||
- | transition-timing-function: | ||
- | } | ||
- | |||
- | h1 { | ||
- | font-size: 3em; | ||
- | font-family: | ||
- | font-weight: | ||
- | color: white; | ||
- | letter-spacing: | ||
- | text-align: center; | ||
- | text-shadow: | ||
- | margin-top: 135px; /* Vertikale Position der Überschrift */ | ||
- | |||
- | } | ||
- | p { | ||
- | margin-left: | ||
- | margin-top: 0; | ||
- | } | ||
- | |||
- | .winkel { | ||
- | color: white; | ||
- | font-family: | ||
- | } | ||
- | |||
- | .winkel .bold { /* Neue Regel, um die Klasse .bold hinzuzufügen */ | ||
- | font-weight: | ||
- | } | ||
- | |||
- | </ | ||
- | </ | ||
- | < | ||
- | <img src=" | ||
- | < | ||
- | <div id=" | ||
- | <p class=" | ||
- | <div id=" | ||
- | </ | ||
- | < | ||
- | $("# | ||
- | circleShape: | ||
- | radius: 320, | ||
- | width: 10, | ||
- | |||
- | min: 0, | ||
- | value: 90, | ||
- | max: 180, | ||
- | step: 1, | ||
- | |||
- | handleShape: | ||
- | handleSize: " | ||
- | |||
- | showTooltip: | ||
- | editableTooltip: | ||
- | mouseScrollAction: | ||
- | |||
- | sliderType: " | ||
- | |||
- | // Fügen Sie die Klasse " | ||
- | cssClass: " | ||
- | |||
- | change: function (e) { | ||
- | var angle = e.value; | ||
- | $("# | ||
- | |||
- | $.post("/ | ||
- | console.log(" | ||
- | }).fail(function () { | ||
- | console.log(" | ||
- | }); | ||
- | } | ||
- | }); | ||
- | |||
- | $(document).on(" | ||
- | if (event.key === " | ||
- | $("# | ||
- | } | ||
- | }); | ||
- | </ | ||
- | |||
- | </ | ||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | ++++ | ||
- | |||
- | {{: | ||
- | |||
- | ===== Nächste Schritte & "Nice to Have" ===== | ||
- | |||
- | Die aktuelle Version könnte an vielen Punkten weiter ausgearbeitet werden. Nachfolgend einige Überlegungen zu nächsten Schritten: | ||
- | |||
- | * <del> ⇒ **anstelle von RPi.GPIO library die pigpio library** | ||
- | * D< | ||
- | * Servospeed anpassen ⇒ weichere Bewegungsabläufe | ||
- | * Die Kamerabild-Einstellungen optimieren: Farben entsättigen (evtl. nur Graustufen) und grünen laser-Punkt deutlicher hervorheben. | ||
- | * Die Kamera physikalisch um 90° rotieren damit das Videobild besser zur aspect-ratio des Browserfensters passt und die Benutzer*innen mehr Fläche zum Spielen zu Verfügung haben. | ||
- | * Autostart von // | ||
- | * Integration von Status-LEDs: | ||
- | * Das WiFi-Signal erscheint schlechter, wenn das Raspberry Pi im Gehäuse verbaut ist. Es müßte getestet werden, ob die Geometrie des Gehäuses hier einen Einfluss hat. | ||
- | * Automatisierte Bilderkennung: | ||
- | |||
- | ====== Weiterführende Literatur ====== | ||
- | |||
- | * A Touch of Code, Interactive Installations and Experiences, | ||
- | * Coding Languages for Absolute Beginners, Zach Webber, 2018 | ||
- | * Creative Code, Aesthetic und Programmierung am MIT Media Lab, John Magda, Birkhäuser, | ||
- | * Design und künstliche Intelligenz, | ||
- | * Designing Interactions, | ||
- | * HelloWorld – The Big Book of Computing Content, Raspberry Pi Foundation, 2022 ([[https:// | ||
- | * Interaktive Systeme, Band 1, Grundlagen, Graphical User Interfaces, Informationsvisualisierung, | ||
- | * MAKE: Getting started with Sensors, Measure the World with Electronics, | ||
- | * Raspberry Pi* – one Vorkenntnisse, | ||
- | * The Manga Guide to Electricity, | ||
- | * Zukünfte gestalten – Spekulation, | ||
- | |||
- | * siehe auch [[literature: | ||
- | |||
- | ====== Fazit ====== | ||
- | |||
- | Es handelt sich bei dieser Idee nur um einen konzeptionellen Ansatz, mit dem Ziel unterschiedliche Einsatzmöglichkeiten des Moduls zu verdeutlichen. Ich gehe davon aus, dass ein Laser, der Katzen in die Augen schießt, grundsätzlich schädlich ist. Aus diesem Grunde sollte das Projekt nicht realisiert werden. | ||
- | |||
- | — // | ||
/var/www/vhosts/hardmood.info/httpdocs/data/attic/probelehrveranstaltung_april2023.1709702603.txt.gz · Last modified: 2024/06/28 19:08 (external edit)