Decoder

Nachdem wir uns mit dem Löten von Bauteilen und der Funktionsweise von Mikrocontrollern vertraut gemacht haben, ging es darum, sich zu überlegen, welche Funktionen der Decoder haben soll und wie man diese umsetzen kann. Dabei war es zuallererst nötig, ein Programmflussdiagramm zu erstellen und sich vor Augen zu führen, in welchen Schritten das Eingangssignal von uns verarbeitet werden soll. Im Betrieb soll der Mikrocontroller auf ein Eingangssignal warten und dieses beim Eingangs-Event in einen binären Morse-Code umwandeln. Dabei wird eine 1 ein „Dit“ repräsentieren. Der entstandene Code wird dann auf einen Speicher geschrieben, von wo er auf Knopfdruck an die Lautsprecher- und Lichtgruppe weitergegeben wird, bzw. in richtige Buchstaben decodet und an die Displaygruppe weitergeleitet wird. Das Einlesen des Signales und die Umwandlung in einen entsprechend verwendbaren Code konnte bereits realisiert werden. Dabei erwarten wir ein Rechtecksignal als Eingang, welches eine Dit-Länge von 4kHz hat. Dieses wird mit 5-Facher Abtastfrequenz abgetastet und ein Algorithmus entscheidet, ob es sich beim vorliegenden Signal um eine „1“ oder um eine „0“ handelt. Das naheliegende Ziel ist nun den umgewandelten Code zu Speichern und wieder abzurufen. Danach wird die Entwicklung des Algorithmus zum Decoden des Morse-Codes in Buchstaben erfolgen.

 

Unser Projektlabor startete in den ersten Wochen mit einem kleineren Projekt. Dieses Projekt hatte das Thema: Verstärker. Das Projekt ist in 3 Gruppen aufgeteilt worden. Der Vorverstärker wurde mir zugeteilt, nachdem wir alle Widerstände berechnet haben fingen wir an zu Löten. Als letztes gab es, einen Stöpsel Termin. Dieser verlief ohne Probleme, wir hatten danach die Möglichkeit den Verstärker zu testen. Als nächsten haben wir angefangen über unser Projekt nachzudenken, wie sich dieses realisieren lässt. Mit ein Flussdiagramm haben wir einen groben Plan aufgestellt wie wir die Schaltung realisieren können. Durch die Informationen aus dem Flussdiagramm haben wir erste Erkenntnisse entnehmen können, welche Bauteile wir für unser Projekt benötigen und was für ein Programm wir schreiben müssen. Im nächsten Termin, haben wir angefangen mit einem Mikrocontroller zu experimentieren. Unser Erster erfolg stellte ein Programmcode da, dieser hat es uns ermöglicht ein Eingangssignal abzuspeichern und dieses mithilfe einer LED darzustellen. Im nächsten schritt haben wir das Signal in ein Binärcode umgewandelt um es als Nächstes decodieren zu können. In den Folgeterminen beginnen wir mit der Programmierung für die Decodierung der morse Zeichen.

Nach den Informationen der Encoder Gruppe entspricht das Eingangssignal für den Decoder eines 5V Rechtecksignals. Für ein „Dit“ ist dabei eine Frequenz von 4kHz, also eine Signaldauer von 250 µs vorgesehen. Mit dem Wissen über die Zusammensetzung vom Morse-Code, dass also zum Beispiel ein „Dah“ 3 „Dit“ entspricht, ließ sich der Algorithmus zur erfolgreichen Abtastung dieses Signals entwickeln. Laut Abtasttheorem von Shannon muss ein Signal mit mindestens doppelter Abtastfrequenz abgetastet werden, um erfolgreich rekonstruiert zu werden. Der verwendete Code tastet hierbei 5 Mal pro „Dit“ ab, also alle 50 µs. Liegen nach 5 Abtastungen, also nach einer vollständigen „Dit“-Länge, mehr gemessene High’s (bzw. „1“) als Low’s (bzw „0“) vor, so wird dieser Signalteil als eine „1“ im Speicher hinterlegt. Umgekehrt wird folglich eine „0“ gespeichert. Wenn das Signal vorbei ist, also für eine festgelegte Zeit keine „1“ mehr sendet oder der Speicher des Mikroprozessors voll ist, wird das ausgelesene Signal zurückgegeben. Die aufgenommenen Daten sind dabei in einem uint8t – Array mit 7000 möglichen Einträgen gespeichert. Eine „1“ repräsentiert dabei ein „Dit“ und eine „0“ die kürzeste mögliche Pause. Die Einträge dieses Arrays können dann auf Abruf zum einen decodiert und an das Display weitergeleitet und zum anderen unverändert an das Lauflicht geschickt und ausgegeben werden. Im laufenden Betrieb wartet das System auf ein signaleingangsindizierendes „High“, welches den Decodierungsprozess initiiert. Da es auch möglich ist, dass zeitgleich über beide Eingangs-Kanäle ein Signal ausgelesen werden muss, ist das Programm so ausgelegt, dass es beide Signale gleichzeitig auslesen und einzeln abspeichern kann. Dabei konnte es bislang passieren, dass wegen dem dann nicht mehr unerheblichen Zeitaufwand der Rechenoperationen des Mikrocontrollers, Lesefehler entstehen. Die Kompensation solcher Lesefehler, bzw. die Anpassung des Codes ist für die restliche Zeit angedacht. Das Eagle Layout für die Hauptplatine gestaltete sich nicht ganz so einfach. Bereits zu Beginn ergaben sich Schwierigkeiten, da Informationen zur Pin-Belegung fehlten. Dennoch ist frühzeitig mit dem ersten Entwurf für die Hauptplatinen begonnen worden. Zunächst wurde hierbei mit zwei Mikrocontrollern gearbeitet, was sich jedoch als zu kompliziert darstellte. Da die Zeit fehlte, um herauszufinden, wie sich die Mikrocontroller untereinander verständigen können, wurde letztlich nur einen Mikrocontroller verbaut. Zeitgleich entstand in der Display-Gruppe die Befürchtung, dass 4 Pins für die Ansteuerung des Displays nicht ausreichen würden. Die Lauflicht-Gruppe beanspruchte bereits 20 Pins und da der Mikrocontroller nur 32 Pins hat, würde der Entwurf mit einem Mikrocontroller möglicherweise nicht ausreichen. Dieses Problem löste sich jedoch schon nach kurzer Zeit, da die Display-Gruppe nur 4 Pins brauchte. Zusammen mit den 20 Pins der Lauflicht-Gruppe gab es somit keine fehlenden Pins mehr. Im nächsten Schritt konnte nun die Anzahl der Knöpfe bzw. der Status der LED’s bestimmt werden. Nachdem all diese Probleme behoben waren und die gesamte Anzahl der verwendeten Pins bekannt war, ist das Eagle Layout entstanden. Bei der Erstellung des Eagle Layouts ergaben sich keine weiteren Probleme, es wurde nur beschlossen, dass zwei Platinen anfertigen werden. Während Frank und Joe die Hauptplatine designten, hat Tianjing die Frontplatine mit den Knöpfen und Status LED’s angefertigt. Durch gutes Zeitmanagement ist es der Gruppe gelungen, die Hauptplatine bereits zum frühstmöglichen Ätztermin fertigzustellen. Noch in der selben Woche ist die Platine im vorletzten Schritt gebohrt und gelötet worden, wobei jedoch ein Designfehler aufgetaucht ist. Es ist vergessen worden, Pull-Up-Widerstände für das Display in die Schaltung einzubinden. Dieses Problem ist durch eine zweite Miniplatine von Facundo und Joe gelöst worden. Im letzten Schritt sind die Platinen und all ihre Pins fehlerfrei auf Leitfähigkeit getestet worden, woraufhin der Programmcode auf den Mikrocontroller geflashed und alle Steckverbinder mit der Frontplatine verbunden wurden.

Die Decoder-Gruppe soll die eingegebene Signale dekodieren und übersetzen. Sie bekommt zwei Arten von Signalen, ein optisches und ein Funk-Signal. Dafür werden zwei Pins benötigt. Die Gruppe entschied sich beide Signale zu speichern und dem Benutzer die Wahl geben welches von beide er anzeigen lassen will. Dazu werden insgesamt 4 Knöpfe verwendet (on-off, Option up, Option down, enter). Zusätzlich werden 3 Status Lichter benutzt. Eine Arbeit war den Speicher-Code zu programmieren. Dafür habe ich mich entschieden die Bibliothek „AVR EEPROM“ zu verwenden. Das Signal wird aufgenommen und in Binärcode(MoreseCode) dekodiert. Durch die Funktion storeSignal() wird das dekodierte Signal in einem spezifischen Platz auf dem EEPROM gespeichert. Wir haben uns entschieden den Speicher (1 Kbyte) in vier Teile zu teilen (250mBytes) da wir letztendlich vier gleich lang Signale speichern wollen. Das dekodierte Signal wird als bool array eingegeben. Um möglichst wenig Speicherplatz zu verwenden (jeder Bool-Element ist 8 Bit lang) werden alle 8 Bool-Elemente des Bool-Arrays innerhalb der Funktion storeSignal() erstmal in ein Element eines uint8 array gespeichert. Damit verwenden wir also 8mal weniger Speicherplatz. Letztendlich wird das uint8 array im Speicherplatz gespeichert. Dazu haben wir noch eine Funktion getSignal(n) wobei n der Index unseres aufgerufenes Signals ist (n zwischen 1 und 4) geschrieben. Damit kann der Mikrocontroller direkt an der Stelle angreifen wo das Signal gespseichert ist und das Signal ablesen. Analog wie bei storeSignal(), getSignal() liest das Signal ab, wandelt es in einem Bool-Array zurück und erst dann gibt es diesen Array zurück. Andere Arbeit war den Übersetzen-Code zu Programmieren. Das aufnehmende Signal wird in Binärcode(Morsecode) dekodiert. Der Code(String) besteht aus 0 und 1. Eins bedeutet dit in Morsezeichen, drei aufeinanderfolgenden Eins bedeutet dah, und Null bedeutet Pause. Zwei aufeinanderfolgenden Null ist Pause zwischen zwei Buchstaben. Drei aufeinanderfolgenden Null ist Pause Zwischen zwei Wörter. Vier aufeinanderfolgende Null bedeutet das Ende des Satz. Mit der While-Schleife wird die String(Binärcode) von jeder Buchstabe und Wort getrennt. Dann wird der Binärcode zu Dezimalcode umwandelt, um Speicherkapazität zu sparen. Jede Buchstabe, Zahl und Zeichen hat jeweilige String(Dezimalcode). Mit der Switch-Case-Anweisung kann das Code zur Buchstabe, Zahl und Zeichen umwandelt werden (Zum Beispiel 2310 ist A).Für Default zeigt die Zeichen #. Zum Schluss mit dem Code von Facu kommt der übergesetzte Satz und wird in Display angezeigt.