Mit dem Raspberry Pi morsen / Tieferer Einstieg in Python
Mit der Schaltung mit LED und Buzzer, bei der wir das letzte Mal aufgehört habe, wollen wir jetzt weitermachen. Allerdings bleibt die Schaltung, wie sie ist. Dafür wollen wir dem rudimentären Python-Programm jetzt etwas mehr Funktionalität einhauchen und es dazu bringen, das es via LED und Buzzer morst und das bitte schön auch so, dass man (oder ein entsprechendes Analyse-Programm) es auch verstehen kann.Dazu soll dem Programm ein beliebiger Text übergeben werden können, den dieses in Morsezeichen umsetzt und diese dann auch gleich morst.
Das soll dann so aussehen:


# -*- encoding: utf-8 -*-
# 2018 by Oliver Kuhlemann
# Bei Verwendung freue ich mich über Namensnennung,
# Quellenangabe und Verlinkung
# Quelle: http://cool-web.de/raspberry/
import RPi.GPIO as GPIO # Funktionen für die GPIO-Ansteuerung laden
import time # für sleep() (Pause) nötig
import sys # um die übergebenen Parameter von der Shell abzufragen
GPIO.setmode(GPIO.BCM) # die GPIO-Pins im BCM-Modus ansprechen
led=14 # unsere LED hängt an BCM-Pin 14
GPIO.setup(led, GPIO.OUT) # in den LED-Pin wird "geschrieben"
# Morsecode, siehe https://de.wikipedia.org/wiki/Morsezeichen
einh=0.080 # Länge einer Einheit in Sekunden
dit=einh*1 # Das Dit ist eine Einheit lang
dah=einh*3 # Ein Dah ist dreimal so lang wie ein Dit.
pSymbol=einh*1 # Die Pause zwischen zwei gesendeten Symbolen ist ein Dit lang.
pBuchst=einh*2 # Zwischen Buchstaben in einem Wort wird eine Pause von der
# Länge eines Dah (oder drei Dits) eingeschoben.
pWort=einh*6 # Die Länge der Pause zwischen Wörtern entspricht sieben Dits.
# bei der Pause zwischen Buchstaben und Wörtern wurde ja schon
# eine Pause von Länge 1 Einh gesendet, darum abziehen
# Nachfolgend sind alle Morse-Zeichen in einem sog. Dictionary definiert
morseCode = {" ":"/","A":".-","B":"-...","C":"-.-.","D":"-..","E":".","F":"..-.",
"G":"--.","H":"....","I":"..","J":".---","K":"-.-","L":".-..","M":"--","N":"-.",
"O":"---","P":".--.","Q":"--.-","R":".-.","S":"...","T":"-","U":"..-","V":"...-",
"W":".--","X":"-..-","Y":"-.--","Z":"--..","0":"-----","1":".----","2":"..---",
"3":"...--","4":"....-","5":".....","6":"-....","7":"--...","8":"---..",
"9":"----.","Ä":".--.-","Ö":"---.","Ü":"..--","ä":".--.-","ö":"---.","ü":"..--",
"ß":"...--..",".":".-.-.-",",":"--..--",":":"---...",";":"-.-.-.","?":"..--..",
"-":"-....-","(":"-.--.",")":"-.--.-","'":".----.","=":"-...-","+":".-.-.",
"/":" ","@":".--.-."}
def beep(t): # diese Zeile definiert eine Funktion
GPIO.output(led, GPIO.HIGH) # LED-Pin auf High (+3.3V) setzen = einschalten
time.sleep (t) # t Sekunden warten
GPIO.output(led, GPIO.LOW) # LED-Pin auf Low (0V) setzen = ausschalten
def morse(symbols):
for sym in symbols: # For-Schleife: Gehe alle Zeichen in symbole durch
if sym == ".": # Die Einzelzeichen finden sich dann jeweil in sym
beep (dit)
time.sleep (pSymbol)
elif sym == "-": # elif ist das Else If in Python
beep (dah)
time.sleep (pSymbol)
elif sym == " ":
time.sleep (pBuchst)
elif sym == "/":
time.sleep (pWort)
# ein EndIf gibt es in Python nicht. Ein Block endet,
# wenn die Einrückung endet
def textToMorse(text):
code = ""
for bst in text:
code+= morseCode[bst]+" " # "code += ..." bedeutet das Gleiche wie "code = code + ..."
return code # code ist unser Funktionsergebnis und Rückgabewert
text = "Hallo Welt" # Unser Standardtext, wenn nichts übergeben wird
argc=len(sys.argv) # Anzahl der übergebenen Wörter hinter "python morse.py ..."
if argc > 1: # Falls etwas übergeben... 1. Arg ist immer der Programmname
text = ""
for nr in range (1,argc): # dann werden alle übergebene Werte ...
text += sys.argv[nr] # zu unserem zu morsenden Text
if nr < argc-1:
text += " "
else:
print "Kein Text übergeben, benutze Standard-Text "+text
text=text.upper() # Unser Dictionary kennt nur die Entsprechungen für die
# Großbuchstaben. Darum machen wir den Text GROSS.
# Für Umlaute funktioniert das nicht. Darum stehen die
# kleinen Umlaute auch nochmals im Dictionary
print "Morse den Text: " + text
code=textToMorse (text) # Aufruf der Funktion, die den Text zu Morsezeichen
# übersetzt
print ("Das entspricht: " + code)
morse (code) # Aufruf der Funktion, die das Pipen und Blinken
# bewerkstelligt
GPIO.cleanup() # Programm sauber verlassen und Resourcen wieder freigeben

- Die Angaben von der Kommandozeile als zu morsenden Text entgegennehmen
- Den Text in Morsecode mit Punkten und Strichen umwandeln
- Die einzelnen Symbole im Morsecode (.- etc.) interpretieren und die LED und den Buzzer entsprechend lang ansteuern und symbolabhängigen Pausen machen
Aber noch einmal zum Code ansich: die erste Zeile ist wichtig und sorgt dafür, das Umlaute, die im Windows-Editor gespeichert wurden nicht gleich einen Syntax Fehler im Python Interpreter verursachen.
Nach ein paar Zeilen, die wir schon kennen, folgen dann Definitionen für das Timing mit ein paar Variablen, um die Sache lesbarer und änderbarer zu machen. Wenn man Einh z. B. auf 0.040 setzt, dann morst das Programm doppelt so schnell.
Dann folgt die Definition eines sogenanntes Dictionarys mit morseCode=... In geschweiften Klammern werden hier eine Reihe von Paaren, durch Komma getrennt, angegeben. Jedes Paar im Format "Suche":"Finde". Später kann man dann auf das Dictionary zugreifen und morseCode["A"] würde dann ".-" zurückliefern. Das ist doch sehr viel komfortabler als ewig viele If-Abfragen. Da wir nur Großbuchstaben im Dict haben, aber bei der Suche nach Groß-/Kleinschreibung unterschieden wird, müssen wir später unseren Text mit .upper() groß machen.
mit def beep(t): beginnt unsere erste Funktion, denn so wird eine Funktion in Python definiert. "def" ist das Schlüsselwort für eine Funktionsdefinition, "beep" der Funktionsname und das t in Klammern ist ein Übergabeparameter, den wir beim Aufruf übergeben müssen. In diesem Fall ist t die Zeit, die unser LED-Pin auf High geschaltet bleibt, was zum Leuchten der LED und dem Piepen des Buzzers führt (das kennen wir ja schon aus dem letzten Projekt).

In der folgenden Funktion morse finden wir dann for ... in-Schleife. Das ist auch eine praktische Syntax in Python, um alle Elemente einer Sammlung, hier einer Zeichenkette, durchzugehen. In sym ist dann jeweils ein Zeichen (Punkt, Strich, Leerzeichen, oder "/") zu finden. An der Einrückung erkennt man, was die Schleife umfasst: alles bis zum nächsten def.
Pro Schleifen-Durchlauf wird je nach Symbol etwas anders getan. Das geschieht durch eine bedingte Verzweigung oder auch If-Abfrage genannt. Dabei wird eine Bedingung gestellt und geprüft, ob diese wahr ist. if sym == ".": wird z. B. ausgeführt, wenn das Symbol ein Punkt ist. Ein Punkt ist einer kurzer Ton, also wird beep mit der Zeitspanne dit, der kurzen aufgerufen. Auch if bildet einen Block. Es könnten also auch mehrere Zeilen eingerückt sein, die dann alle ausgeführt würden, wenn die Bedingung war ist.
elif ist Pythons Kürzel für "Else if" und heißt so viel "falls ansonsten aber folgendes zutrifft", bei elif sym == "-": also: "falls sym kein Punkt war, sym aber ein Strich ist". Dann gäbe es noch den Befehl else:, der hier nicht aufgeführt ist, aber für "falls das alles nicht zutrifft, dann aber...". Wollte man z. B. eine Fehlermeldung ausgeben, würde man "else: [Einrückung] print "Das Zeichen " + sym + " wird nicht unterstützt." [Einrückung Ende] schreiben.
In der Funktion textToMorse ist besonders die Zeile code += morseCode[bst] interessant, die aus dem oben definierten Dictionary für jeden Buchstaben des zu morsenden Textes die Morse-Code-Entsprechung holt und an den Morsecode anhängt.
Danach sind alle nötigen Funktionen definiert und das Hauptprogramm beginnt, so wie es ganz oben schon grob beschrieben wurde.