Morse De- und Encoder mittels FPGA 3.0
Erweiterung des Morse De- und Encoders um KI-basierte Gestensteuerung
1. Einführung/Funktionsweise
Dieses Projekt, entwickelt im Rahmen des Moduls Entwurf Digitaler Systeme bei Prof. Dr. Jorczyk, basiert ebenfalls auf dem Projekt „Beschreibung eines Morsedecoders und -encoders mittels VHDL und Implementierung auf einem FPGA-Entwicklungsboard“ von Kai-Frederik Nessitt. Zudem wurde aus der unter „4. Erweiterung eines Morsedecoders und -encoders, Implementierung eines RAMs, ROMs, und UART“ zu findende Erweiterung von Wassim Bouchnak und Moujahid Bouhouch die Programmierung der UART-Schnittstelle als Grundlage für die UART-Kommunikation genutzt.
In diesem Projekt wurde der klassische Morsetaster durch eine Gestensteuerung ersetzt. Mittels einer Kamera und einem Jetson Nano wird die Hand als Objekt erkannt und die Fingerstellung ausgewertet. Wird die Hand ausgestreckt und alle Finger aufrecht gehalten entspricht dies der Betätigung des Morsetasters Hier wird abhängig davon, wie lange diese Position gehalten wird ein kurzes oder ein langes Morse-Signal gesendet. Werden alle Finger runter genommen entspricht dies dem Nicht-Betätigen des Tasters und damit einem Pausenzeichen.
Video Funktionsweise: https://youtu.be/quRndJoUEgI
2. Materialien und Aufbau
Zur Verarbeitung und Ausgabe der Morse-Signale wird das FPGA Cyclon IV auf dem Entwicklerboard DE2-115 von Altera verwendet.
Zur Aufnahme der Handbewegung wird eine Webcam verwendet.
Die Handerkennung wird mit Hilfe eines Jetson Nano von Nvidia durchgeführt.
Der Jetson Nano wird mittels des HDMI-Anschlusses mit einem Bildschirm verbunden. Zusätzlich werden über USB-Tastatur und Maus angeschlossen. Auch die Kamera wird per USB mit dem Jetson Nano verbunden. Die Stromversorgung erfolgt über einen Micro-USB Anschluss.
Die Datenverbindung zwischen Jetson Nano und FPGA ist mittels UART realisiert. Die UART-Pins sind auf dem Entwicklungsboard in der RS-232 Schnittstelle angelegt, weshalb ein RS-232 Kabel verwendet wird. Dieses Kabel wird mit den UART-Pins des Jetson Nano verbunden.
Am FPGA-Entwicklungsboard angeschlossen werden die Stromversorgung (siehe Abbildung 1: -1- ), das USB-Kabel zur Programmierung des Boards (-2-), Lautsprecher zur Audioausgabe (-3-) und das RS-232 Kabel für die UART-Kommunikation (-4-).
Abbildung 1: Aufbau mit FPGA-Board, Jetson Nano und der dazugehörigen Peripherie
3. Set-up Jetson Nano und Datenverbindung UART
Setup: Als erstes wurde der Jetson Nano geupdated, um diesen auf den aktuellsten Stand zu bringen. Es wurden Systempakete für TensorFlow sowie Python installiert.
Zur Handerkennung wurde das Programm MediaPipe Hands aus folgender Quelle verwendet: https://google.github.io/mediapipe/solutions/hands.html
Die Funktionsweise ist nur im Decoder Modus realisiert. Die Daten fließen demnach nur vom Jetson Nano zum FPGA. Aus diesem Grund wird in dieser Konfiguration am Jetson Nano nur die Tx Leitung und der GND-Anschluss der UART Schnittstelle benötigt.
Die Gestenerkennung auf dem Nano wurde in Phython programmiert.
Wird eine Hand erkannt werden auf diese 21 Punkte gelegt (siehe Abbildung 2).
Zur Erkennung, ob ein Finger gehoben ist oder nicht, werden die Positionen der obersten Punkte an den Fingerspitzen mit den darunter liegenden Punkten verglichen. Liegen diese Fingerspitzen oberhalb der anderen Punkte, wird diesem jeweiligen Finger eine 1 zu geordnet. Liegen die Fingerspitzen unterhalb der anderen Punkte wird den jeweiligen Fingern eine 0 zugeordnet. So entsteht zunächst eine Abfolge von Bits je nach Fingerposition. Diese Bitreihenfolge muss weiter zur Versendung über UART angepasst werden.
Beim Reihenfolge in der UART-Übertragung ist folgende:
1 Startbit – 8 Datenbit – 1 Stoppbit
Zusätzlich kann optional noch ein Parity-Bit verwendet werden, auf dieses wurde hier verzichtet.
Um das UART-Protokoll einhalten zu können, muss der bei der Handerkennung entstehende Bit-Storm in Datenpakete unterteilt werden. Zunächst ist es sinnvoll für jede Erkennung alle fünf Finger zu einem Paket zusammenzufassen. Um auf die 8 Datenbits des UART-Übertragungsprotokolls zu kommen werden zusätzlich zu jeden Paktet mit den 5 Bits für die Finger 3 Bits mit 0 ergänzt (Datenpakete siehe Abbildung 2).
Abbildung 2: Handerkennung und aufgenommene Daten
4. Anpassung der Top-Level-Entity
In der Top-Level-Entity morse wird das über UART empfangene Signal dem Signal des Morsebuttons zugewiesen. Im Process Hand wird zwischen gehobenen und gesenkten Fingern unterschieden. In der if-Abfrage wird der Inhalt des Vektors Nanodata abgeprüft. Sind die vordersten 5 Stellen des Vektors Nanodata = 0, entspricht dies der Senkung aller Finger und es wird eine Pausensignal gesendet, also kein Ton ausgegeben. Ist mindestens einer der Finger gehoben, soll dies einem Druck auf den Morsetaster entsprechen und somit ein Tonsignal ausgegeben werden.
Hand : PROCESS (reset, clockNC_en)-- Empfangene Daten werden zum Tastendruck BEGIN IF Nanodata(7) = '0' and Nanodata(6) = '0' and Nanodata(5) = '0' and Nanodata(4) = '0' and Nanodata(3) = '0' then NanoButton <= '1'; -- Keine Finger elsif Nanodata(7) = '1' OR Nanodata(6) = '1' OR Nanodata(5) = '1' OR Nanodata(4) = '1' OR Nanodata(3) = '1' then NanoButton <= '0'; -- mindestens ein Finger END IF; END PROCESS;
5. Ausblick
In einer Erweiterung des Programms wäre es denkbar gezielt zwischen verschiedenen Gesten mit der Hand zu unterscheiden. Zum Beispiel könnte eine Art Tastaturfunktion implementiert werden, sodass eine bestimmte Fingerstellung einem Buchstaben entspricht, zu welchem dann automatisch das zugehörige Morsesignal ausgesendet wird.
Autoren: Robert Jung und Franziska Gröniger
Gelsenkirchen 2022
Projektdateien: