Erweiterung des Morse Decoders um einen Beschleunigungssensor als Morsetaster in VHDL
1. Motivation
Ziel des Projektes im Rahmen des Moduls Entwurf Digitaler Systeme bei Herrn Prof. Dr. Jorczyk war es, den bestehenden FPGA-basierten Morse De- und Encoder, der von Kai-Frederik Nessitt programmiert und in darauffolgenden Projekten von Studierenden umfangreich erweitert wurde (Projektseite), um eine weitere Option zur Eingabe des Morsecodes zu ergänzen. Die Eingabe sollte sensortechnisch erfasst werden. Dazu wurde die Verwendung eines Beschleunigungssensors in Betracht gezogen, welcher das Tippen mit einem Finger erkennen soll.
Da durch ein Tippen mit dem Finger nur ein kurzes Signal entsteht, erwies sich die Erzeugung und Unterscheidung von kurzen und langen Signalen, wie sie beim Morsen verwendet werden, als schwierig. Zur Lösung des Problems wurden verschiedene Lösungsansätze erörtert. Neben der Möglichkeit der Verwendung von zwei Sensoren, dessen Messungen unterschiedlich interpretiert werden (Sensor 1 -> kurz; Sensor 2 -> lang), wurde die Verwendung eines Sensors und der Erzeugung der gewünschten Signale durch einfaches (Dit) und doppeltes Tippen (Dah) in Betracht gezogen.
2. Bestehende Funktionalität des Morse Decoders und Belegung/Anschluss in diesem Projekt
Der Morse De- und Encoder wurde in vorausgegangenen Projekten von mehreren Studierenden weiterentwickelt. Zu den Funktionalitäten des Decoding-Teils gehören unter anderem die Eingabe des Morsecodes über einen Taster des FPGA-Boards sowie über einen externen Morsetaster, der über GPIO-Pins an das Board angeschlossen wird. Darüber hinaus wird der eingegebene Morsecode vom FPGA decodiert und auf dem 16x2 LCD-Display des Boards ausgegeben. Während der Eingabe werden die „Dits“ (kurz) und „Dahs“ (lang) des Morsecodes akustisch mittels eines über Klinke angeschlossenen Lautsprechers und über LEDs auf dem Board signalisiert. Darüber hinaus besteht die Möglichkeit, die Morsegeschwindigkeit über zwei Schalter auszuwählen. Zur Verfügung stehen neben der Einstellung von 5 Words-per-minute (WPM) auch 13 WPM und 20 WPM.
3. Belegung und Anschluss des Terasic Altera DE2-115 FPGA-Boards
Abb. 1: Zuweisung und Anschluss, Terasic Altera DE2-115 FPGA-Board
4. Der Beschleunigungssensor ADXL345 und die Tap-Detection
Als Beschleunigungssensor kommt ein ADXL345 des Herstellers Analog Devices (Link zum Datenblatt) zum Einsatz. Dieser 3-Achse-Beschleunigungssensor ist preiswert als Modul erhältlich. Der Sensor verfügt über mehrere Features, wie der Erkennung von (In-)Aktivität, freiem Fall und Tippen. Der Sensor kann sowohl ein einfaches Tippen (Single-Tap-Detection) als auch ein doppeltes Tippen (Double-Tap-Detection) erkennen. Diese Funktionalität soll zur Erzeugung von Signalen dienen, welche kurzen und langen Tastendrücken entsprechen. Wird ein solches Ereignis detektiert, erzeugt der Sensor einen Interrupt, der je nach Konfiguration an den Pins INT1 und INT2 ausgegeben werden kann. Das Konfigurieren und Auslesen des ADXL345 kann über die Busse I²C und SPI geschehen. Für das Projekt wurde aufgrund des geringeren Schaltungsaufwandes die Verwendung des I²C-Busses gewählt.
Abb. 2: Modul mit ADXL345 Beschleunigungssensor
Beim Start des FPGA-Boards und somit des Sensors muss dieser konfiguriert werden. Die Konfiguration geschieht, indem vordefinierte binärcodierte Werte in 8-Bit-breite Register des Sensors geschrieben werden. Die Adressen dieser Register sowie deren Funktion und der damit zusammenhängenden Bedeutung der vordefinierten Konfigurations-Bytes lassen sich dem Datenblatt des ADXL345 entnehmen.
Für die Verwendung der Funktionalität „Tap-Detection“ wurden folgende Register nacheinander konfiguriert:
- DATA_FORMAT (0x31): Polarität der Interrupt-Signale + Messbereich (nur für Beschleunigungsmessungen relevant)
- THRESH_Tap (0x1D): Schwellenwert zur Erkennung von Taps, hier wurden 5 g gewählt
- DUR (0x21): maximale Zeit, die ein Signal über dem Schwellenwert sein darf, um als Tippen erkannt zu werden, hier 20 ms
- Latent (0x22): Zeitfenster nach einem ersten Tippen, nach Ablauf dessen ein zweites Tippen erkannt werden kann.
- Window (0x23): Zeitfenster, in dem ein zweites Tippen erkannt werden kann, um als Double-Tap-Ereignis zu gelten
- TAP_AXES (0x2A): Einstellung der Achsen, die an der Tap-Detection beteiligt sind
- INT_MAP (0x2F): Einstellung, welches Interrupt Ereignis über welchen Pin ausgegeben werden soll. Hier INT1 -> Single-Tap, INT1 und INT2 -> Double-Tap
- INT_ENABLE (0x2E): Einstellung, welche Features Interrupts erzeugen dürfen
- BW_RATE (0x2C): Datenrate am Output, hier 100 Hz
- POWER_CTL (0x2D): Einstellung des Modus. Hier „Measure“, um kontinuierliche Messung zu starten
5. Finite State Machine (FSM) für die Kommunikation mit dem Sensor über I²C
Für die Kommunikation über den I²C-Bus wurde der in VHDL geschriebene „I²C_master“ von Scott Larsson als Komponente In der Entity „ADXL345I2C“ instanziiert. Der I²C-Master steuert die Kommunikation auf dem Bus. In der Entity „ADXL345I2C“ läuft die FSM ab, die die Kommunikation mit dem Sensor realisiert und ihn anfänglich konfiguriert und anschließend ausliest. Beim Starten des Sensors werden zunächst 100 ms gewartet, bis die Konfiguration des Sensors beginnt, wie in ABBILDUNG STATEMACHINE beschrieben. Nach der Konfiguration begibt sich der die FSM in den State „pause“, in dem 1,3 µs zwischen den Übertragungen gewartet wird.
Anschließend springt die FSM in den State „read_data“. Hier wird das Register „INT_SOURCE“ mit der Adresse „0x30“ ausgelesen. Das Register zeigt an, welche Features einen Interrupt ausgelöst haben. Diese Informationen werden in diesem Projekt nicht verwendet, da für das Auslesen der Interrupts die physikalischen Pins INT1 und INT2 des Sensors verwendet wurden. Dennoch ist das Lesen des Registers zwingend notwendig, damit die Interrupts zurückgesetzt werden.
Abb. 3: Finite State Machine, Konfiguration und Kommunikation mit ADXL345 über I²C
Vom State „read_data“ wird in den State „output_result“ gesprungen. Dieser State dient als Platzhalter für einen zweiten Lösungsansatz des Projektes. Anschließend wird wieder in den State „pause“ gesprungen. Somit befindet sich die FSM nach der Konfiguration zyklisch in den States „pause“, „read_data“ und „output_result“.Die durch den Sensor erzeugten Interrupts werden über die INT-Pins ausgegeben. Diese Pins werden mit GPIO-Pins des Altera DE2-115 Boards verbunden und eingelesen, um sie anschließend weiterzuverarbeiten.
6. Auslesen und Interpretation der Interruptsignale
Je nachdem, ob der ADXL345 einen Single- oder einen Double-Tap erkennt, können folgende Signalkonstellationen an den GPIO-Pins anliegen:
- Single Tap: INT1 = 1 und INT2 = 0
- Double Tap: INT1 = 1 und INT2 = 1
Diese Signale sollen nun in der Entity „Tap_button_generator“ eingelesen und interpretiert werden. Dabei ist es wichtig, dass die Eingabe des Morsecodes über das Tippen nur ein zusätzliches Add-On des Decoders darstellen und seine eigentliche Funktionsweise nicht beeinflussen soll. Die Verarbeitung eines Tastendrucks erfolgt beim ursprünglichen Morsede- und Encoder in der Entity „press_duration“. Diese misst die Länge des Tastendrucks und interpretiert diese in ein kurzes oder langes Morsesignal. Um auf diesem Funktionsprinzip aufzubauen, erzeugt die Entity „Tap_button_generator“ ein Ausgangssignal, was exakt dem eines Morsetasters entspricht. Der Vorteil dieser Herangehensweise ist, dass dieses Signal nun wie ein Betätigen eines Tasters von der „press_duration“ Entity eingelesen und verarbeitet werden kann. Realisiert wird dies mit einer Finite State Machine.
Abb. 4: FSM der Entity "Tap_button_generator"
Im Startzustand „measure“ werden die GPIO-Pins kontinuierlich und aufgrund der zeitlichen Kürze der Interruptsignale mit dem Systemtakt von 50 MHz eingelesen. Während dieses Zustandes befindet sich das Ausgangssignal der Entity „button“ bei einer logischen 1. Wenn nun ein Single- oder Double-Tap erkannt wird, geht die FSM in den dafür vorgesehenen Zustand „short“ bzw. „long“ über, in dem das „button“-Signal auf eine logische 0 gebracht wird. Nach der Signaldauer eines kurzen bzw. langen Morsesignals bei der eingestellten Morsefrequenz geht die FSM wieder in den Ausgangszustand „measure“ über, in der der Zustand von „button“ wieder zurückgesetzt wird. Diese Dauer wird mithilfe eines Counters realisiert, dessen Limit sich anhand der eingestellten WPM errechnet. Ein kurzes Morsesignal entspricht dabei 2, ein langes Signal 7 Takte der entsprechenden Morsefrequenz. Durch diese Vorgehensweise entspricht das Verhalten des Ausgangs „button“ dem eines low-aktiven Morsetasters.
7. Einbindung in Top-Level Entity „morse“
Um die Möglichkeit zur Eingabe des Morsecodes in die bestehende Top-Level Entity „morse“ zu integrieren, wird diese um Ports für die Pins INT1 und INT2, sowie für die Daten- und Taktleitung (SDA, SCL) für die I²C-Kommunikation mit dem Sensor erweitert. Zusätzlich wird ein Switch „choice_tap_detection“ am FPGA-Board genutzt, um zwischen der Eingabe per Taster oder mittels des Beschleunigungssensors umzuschalten. Der eingestellte Modus wird dem Benutzer über eine 7-Segment-Anzeige angezeigt. Des Weiteren ist es in der Top-Level Entity notwendig die Komponenten „ADXL345I2C“ und „Tap_button_generator“ zu deklarieren und anschließend zu instanziieren. Auf diese Weise werden deren Ein- und Ausgänge mit den nötigen Ports bzw. Signalen verknüpft. Dem Signal „button“, das den Input für die „press_duration“ Entity darstellt, wird nun abhängig von „choice_tap_detection“ entweder das Signal eines Morsetasters oder das Ausgangssignal der Entity „Tap_button_generator“ zugewiesen.
8. Alternativer Lösungsansatz mittels Tap-Detection auf der X- und Y-Achse
Die Eingabe des Morsecodes durch Single- und Double-Taps in der Z-Achse des Sensors funktioniert sehr zuverlässig bei einer Morsegeschwindigkeit von 5 WPM. Bei Anhebung der Morsegeschwindigkeit wird die Eingabe von langen Signalen in Form von Double-Taps zunehmend unkomfortabler und unsicherer. Als Lösung des Problems wurde ein weiterer Ansatz geprüft, in dem die Eingabe von kurzen und langen Signalen mithilfe von Single-Taps auf zwei unterschiedlichen Achsen des Sensors geschieht. Dazu wurde der Sensor so konfiguriert, dass nur die X- und Y-Achse an der Erkennung von Taps involviert sind. In Versuchen stellte sich heraus, dass beim Tippen in einer der Achsen auch immer die andere Achse ein Tippen erkannte. Um eindeutig die Achse zu identifizieren, auf der das Tippen stattgefunden hat, wurde ebenfalls die Beschleunigungsdaten der X- und Y-Achse ausgelesen und miteinander verglichen.
Die Achse, in der das Tippen stattgefunden hat, erfährt eine größere Beschleunigung. Das Ergebnis des Vergleichs wird beim Auftreten eines Interrupts in die Verarbeitung und die Generierung der Signale „short“ und „long“ miteinbezogen. Die Z-Achse wurde bei diesem Lösungsansatz ausgeschlossen, da sie durch die Ausrichtung des Sensors durchgehend von der Gravitation überlagert wird. Bei der Konfiguration des Sensors wurde auf der X-Achse ein minimaler Offset korrigiert, um einer Verfälschung der Messdaten vorzubeugen. Der Offset-Wert wurde in vorausgegangenen Messungen des Ruhezustands des Sensors ermittelt.
9. Morse-Takt-Trainer per Ansteuerung der LEDs
Um ein Gefühl für die verschiedenen Morsegeschwindigkeiten zu bekommen, wurden zwei LEDs des FPGA-Boards so angesteuert, dass sie die Länge von Dits (zwei Taktperioden) und Dahs (sieben Taktperioden) bei der ausgewählten Morsegeschwindigkeit über ein periodisches Ein- und Ausschalten signalisieren. Die LEDs lassen sich jeweils über die unter den LEDs gelegenen Schalter zuschalten.
10. Fazit und Ausblick
In Rahmen dieser Projektarbeit ist es uns gelungen den bereits bestehenden Morsede- und Encoder um zwei alternative Eingabemöglichkeiten des Morsecodes mittels der Tap-Detection eines Beschleunigungssensors zu erweitern. Dabei wurden alle Funktionen vollständig in synthesefähigem VHDL-Code geschrieben und ausgiebig auf einem FPGA-Board getestet.
Die Eingabe des Morsecodes über Single- und Double-Taps in der Z-Achse des Sensors mithilfe der Tap-Detection hat sich als zuverlässige Methode für langsame Morsegeschwindigkeiten erwiesen. Bei höheren Morsegeschwindigkeiten wird diese Art der Eingabe zunehmend unpraktischer. Um diesem Problem zu entgehen, wurde der alternative Ansatz über zwei Messachsen ausprobiert. Dieser Ansatz weist aufgrund der Anregung des Gesamtsystems eine geringere Zuverlässigkeit auf. In künftigen Versuchen könnte ein mechanischer Aufbau, der die X- und Y-Achse größtenteils voneinander entkoppelt, aufgebaut und erprobt werden.
Autoren: Raphael Parsiegel und Lino Feldmann
Gelsenkirchen 2023