Kapitel 1: Grundlagen
Der Kran
Ziel dieses Workshops ist dir einen Einstieg in das Thema Computerprogrammierung zu geben, das dir in deiner Ausbildung, deinem Studium oder deinem Beruf von Nutzen sein kann. Wir werden die Grundlagen der Programmierung anhand eines realen Modellkranes erproben. Dieser Kran besteht aus einem Turm, einem drehbaren Ausleger, einer fahrbaren Laufkatze und einer Seilwinde, die die Kranflasche steuern kann. Der Kran hat einen spezifischen Bewegungsbereich, der durch Ansteuern von Ausleger, Laufkatze und Kranflasche abgedeckt werden kann. Die Steuerzentrale des Krans ist ein Arduino, ein kleiner Computer, auf den wir unseren selbst geschriebenen Code hochladen und somit den Kran steuern können.
Über diesen Workshop
Im Reiter "Workshop", in dem du dich gerade befindest, findest du den Inhalt dieses Workshops untergliedert in einzelne Kapitel. Schritt für Schritt erhältst du so einen Einstieg in die Programmierung. In den Kapiteln findest du interaktive Elemente, in denen du Teile des Programmcodes ergänzen, oder bestimmte Funktionen testen kannst.Der Code-Editor
Am Ende eines jeden Kapitels findest du Übungen, um das gelernte praktisch auszuprobieren. Wechsle dazu in den Reiter "Code-Editor". Dort kannst du selber Code schreiben und testen. Bestimmte Inhalte stehen bereits im Code-Editor. Diese sind wichtig, damit dein Programm auch korrekt funktioniert. Du solltest also nichts davon verändern, sondern nur mit deinem Code ergänzen. Im Code Editor sind bereits zwei Funktionen definiert. Die Funktionsetup()
und die Funktion loop(). Das ist ein typischer Aufbau für ein Programm, das auf einem
Arduino Computer ablaufen soll.Die Funktion
setup() wird einmalig zu Beginn
des Programms ausgeführt. Alles was wir also innerhalb der nachfolgenden "{}"
programmieren wird der Reihe nach einmal ausgeführt. Besonders in den ersten Kapiteln dieses
Workshops wirst du zum Lösen der Übungen innerhalb der setup() Funktion arbeiten müssen.
In den späteren Kapiteln wird es dann etwas komplizierter. Hier kommt die
loop()
Funktion ins Spiel. Diese wird nach dem einmaligen Ausführen der setup() Funktion
immer und immer wieder ausgeführt (daher der Name "loop", englisch für Schleife).Wenn du deinen Code testen möchtest, musst du ihn zuerst "kompilieren". Klicke dazu auf das Zahnradsymbol über dem Code Editor. Wenn alles geklappt hat, erscheint unter dem Code Editor in der Ausgabe "Kompilierung war erfolgreich". Beim Kompilieren wird dein Code in einen maschinenlesbaren Code übersetzt, sodass ein Computer diesen auch ausführen kann. Im Anschluss an eine erfolgreiche Kompilierung startet das Programm automatisch. Mit dem Play bzw. Stop Knopf neben dem Kompilieren-Knopf kannst du die Ausführung deines Programs stoppen und neu starten. Wenn du am Code nichts geändert hast, brauchst du nicht neu kompilieren, sondern kannst damit deinen Code testen.
Neben dem Play bzw. Stop Kopf findest du je einen Knopf zum Teilen und Laden deines Codes. Durch Klicken auf Teilen wird dein Code online gespeichert. Du erhältst ein fünfstelliges Passwort zurück. Mit diesem Passwort kannst du oder eine beliebige andere Person über den Laden-Knopf deinen Code in den Code-Editor hinein laden.
Du kannst deinen Code auch lokal abspeichern. Klicke dazu auf das Speichern Symbol rechts neben dem Laden Knopf. Dein Code wird anschließend heruntergeladen und im Download Ordner deines Computers gespeichert. Um eine lokal gespeicherte Datei wieder in den Code Editor zu laden, klicke auf das Öffnen Symbol rechts neben dem Speichern Knopf. Es öffnet sich ein Datei Explorer, in dem du die gewünschte Datei auswählen kannst.
Steuerung
Im dritten Reiter "Steuerung" kannst du den Kran manuell steuern. Du kannst dazu relative Werte zur aktuellen Position, oder absolute Werte eingeben. Durch Drücken des "Start" Knopfes wird die Bewegung gestartet. Anhand der Schieberegler kannst du die Bewegungsgeschwindigkeit anpassen.Mit den Tasten "WASD" und den Pfeiltasten kannst du den Kran ebenso direkt Steuern. Klicke dazu den rechten Bildschirmteil mit dem Kran an, sodass dieser blau umrandet wird. Im oberen rechten Bildschirmeck findest du zusätzliche Informationen zur aktuellen Position des Krans. Solltest du den Kran einmal aus dem Blickfeld verlieren, kannst du die Ansicht mit dem obersten Symbol am rechten Bildschirmrand wieder einpassen. Mit dem mittleren Symbol kannst du die das Koordinatensystem des Krans ein- und ausblenden. Das unterste Symbol bringt den Kran zurück in seine Startposition.
Kapitel 2: Kran bewegen
Laufkatze fahren
Angetrieben durch einen Zahnriemen kann die Laufkatze am Ausleger entlanggefahren
werden. Der Kran hält hierzu die Methode drive() bereit.
Der Methode muss ein Wert für die gewünschte Distanz in Millimetern übergeben
werden. Ist dieser Wert positiv, bewegt sich die Laufkatze in positiver x-Richtung vom Turm weg.
Ist der Wert negativ, bewegt sich die Laufkatze in negativer x-Richtung zum Turm hin.
Ist der
Wert für die Distanz INFINITY bzw. -INFINITY, dreht sich
der Motor
unendlich. Aufgrund der Bauart des Krans ist jedoch nur eine Auslegung von 110 mm bis
950 mm vom Turmmittelpunk möglich.
Wird der Wert 0 für die Distanz übergeben, stoppt der Kran die aktuelle
Bewegung
der Laufkatze.
Somit bewegt sich zum Beispiel die Laufkatze beim Ausführen von crane.drive(100);
um 100 mm vom Turm weg.
Die Bewegung erfolgt mit einer Standard-Geschwindigkeit.
Optional kann allerdings auch ein zweiter Parameter an die Methode drive()
übergeben werden. Dieser gibt an, in wie vielen Sekunden die Bewegung durchgeführt werden soll.
Die Trennung zwischen zwei Parametern erfolgt mit einem ",".
Beim Ausführen von crane.drive(100, 5); erfolgt also die Bewegung von 100 mm
in 5 Sekunden.
Probiere es einfach selbst aus:
crane.drive();
Ausleger drehen
Der durch einen Drehkranz auf dem Turm montierte Ausleger kann gedreht werden. Der Kran
hält hierzu
die Methode turn() bereit.
Der Methode muss ein Wert für den gewünschten Drehwinkel übergeben werden. Die Angabe des
Winkels
erfolgt im Grad (eine Umdrehung entspricht 360°).
Der Ausleger dreht sich bei positiven
Winkeln gegen den Uhrzeigersinn,
bei negativen Winkeln mit dem Uhrzeigersinn. Ist der Wert für den Drehwinkel
INFINITY
bzw. -INFINTY, dreht sich der Ausleger unendlich.
Wird der Wert 0 für den Drehwinkel übergeben, stoppt der Kran die aktuelle
Drehbewegung.
Beim Ausführen von crane.turn(180); führt der Ausleger beispielsweise eine halbe Drehung aus.
Optional kann auch ein zweiter Parameter an die Methode turn() übergeben
werden, der angibt, in wie vielen Sekunden die Drehung durchgeführt werden soll.
crane.turn(180, 5); führt also zum Beispiel die halbe Drehung in 5 Sekunden durch.
Probiere es einfach selbst aus:
crane.turn();
Winde wickeln
Die Kranfalsche ist über ein Seil mit der Winde verbunden und kann durch Auf- bzw.
Abwickeln der
Winde angehoben oder abgesenkt werden.
Der Kran hält hierzu die Methode wind() bereit. Der Methode muss ein Wert
für den
gewünschten Hub übergeben werden. Ist dieser Wert positiv, hebt sich die Kranflasche in
positiver z-Richtung.
Ist der Wert negativ, senkt sich die Kranflasche in negativer z-Richtung. Ist der Wert
für den Hub
INFINITY bzw. -INFINTY, dreht sich die Winde undendlich.
Aufgrund der Definition des Koordinatensystems befindet sich die Kranflasche bei einer
Höhe von 0 mm am höchsten Punkt.
Wird der Wert 0 für den Hub übergeben, stoppt der Kran die aktuelle Drehung
der Winde.
Um die Kranflasche beispielsweise um 100 mm abzusenken, kann die Aktion crane.wind(-100);
ausgeführt werden.
Optional kann auch ein zweiter Parameter an die Methode wind() übergeben
werden, der angibt in wie vielen Sekunden der Hub durchgeführt werden soll.
crane.wind(-100, 5); senkt also die Kranflasche in 5 Sekunden um 100 mm ab.
Probiere es einfach selbst aus:
crane.wind();
Übung 1
Fahre die Laufkatze um 200 mm nach vorne. Rufe dazu die korrekte Methode in der Funktionsetup(){} des Code-Editors auf.
Übung 2
Drehe den Ausleger unendlich gegen den Uhrzeigersinn.Übung 3
Drehe den Ausleger eine halbe Umdrehung im Uhrzeigersinn.Übung 4
Senke die Kranflasche um 300 mm ab.Übung 5
Fahre die Laufkatze um 150 mm nach vorne, drehe gleichzeitig den Ausleger um 1/4 Umdrehung gegen den Uhrzeigersinn und hebe die Kranflasche um 200 mm an. Benutze den zweiten Parameter in den Methodendrive(), turn() und
wind(), sodass alle drei Bewegungen nach 10 Sekunden
abgeschlossen sind.
Kapitel 3: Variablen
Bisher haben wir die Werte für Distanz, Winkel, Hub und Zeit immer direkt in die jeweilige Methode geschrieben. Beim Programmieren arbeitet man jedoch viel mit Variablen. Eine Variable ist ein Platzhalter, dem ein Wert zugewiesen werden kann. An einer anderen Stelle im Programm kann auf diese Variable zugegriffen werden. Um eine Variable zu definieren, müssen wir ihr zum einen sagen, was für eine Art von Daten sie beinhalten soll, zum anderen müssen wir ihr einen eindeutigen Namen geben. In unserem Programm wollen wir die Zahlenwerte für Distanz, Winkel, Hub und Zeit über Variablen definieren. Ein einfaches Beispiel sieht wie folgt aus:int distanz = 100;Der Ausdruck
int gibt an, dass es sich bei der hier zu definierenden Variable
um einen sog. Integer, also eine Ganzzahl ohne Nachkommastellen handelt. (z.B. 1, 42, 2315737, -5331, 0)
Unsere Variable soll "distanz" heißen, also schreiben wir nach dem Datentypen
int ein
distanz in unseren Code.
Um der Variable distanz jetzt noch den Wert 100 zuzuweisen schreiben wir
= 100.
Wichtig ist es das ";" am Ende nicht zu vergessen, da wir damit dem Computer
mitteilen, dass
wir mit dem Definieren der Variable fertig sind. Ein Befehl zum Fahren der Laufkatze um 100 mm könnte also wie folgt aussehen:
int distanz =100;
crane.drive(distanz);
Neben dem Datentypen
int für Ganzzahlen können wir auch Variablen für Nachkommazahlen definieren.
Um beispielsweise eine Variable für eine Winkelangabe mit Nachkommastellen zu definieren, können wir
Flieskommazahlen (floating-point numbers), kurz float verwenden.
Dezimaltrenner bei floats ist immer ein ".": float winkel = 20.5;
Übung 1
Definiere eine Variable "hoehe" vom Datentypint und weise ihr den Wert -200
zu. Anschließend soll die Methode wind()
mit der Variable "hoehe" als Parameter ausgeführt werden.
Übung 2
Wie in der letzten Übung des vorherigen Kapitels soll der Kran in 10 Sekunden die Laufkatze um 150 mm nach vorne fahren, den Ausleger um eine 1/4 Umdrehung drehen und die Kranflasche um 200 mm anheben. Definiere hierzu die drei Variablen "distanz", "winkel" und "hoehe" mit den korrekten Datentypen und weise ihnen die oberen Werte zu. Definiere zudem die Variable "dauer" und weise ihr den Wert 10 zu. Führe die drei Bewegungen mit den Variablen als Parameter aus.Kapitel 4: Grundrechenarten
Neuer Inhalt
Um mit Werten rechnen zu können, stehen uns die folgenden Symbole für die Grundrechenarten zur Verfügung:+: "Plus"-Zeichen für Addition -: "Minus"-Zeichen für Subtraktion *: "Asterisk"-Zeichen für Multiplikation /: "Schrägstrich"-Zeichen für Division Mit ihnen lassen sich beliebig Variablen und feste Werte miteinander verrechnen.
float i = (1.52 + 3.76) * (1 / 2) - 5;
Übung 1
Der Kran steht am Rand einer Baugrube und soll die Kranflasche bis auf deren Grund absenken. Die Höhe des Krans und somit die Position der Kranflasche beträgt 1050 mm über dem Urgelände, die Baugrube ist 350 mm tief. Definiere dir je eine Variable für die Höhe der Kranflasche und die Tiefe der Baugrube. Senke die Kranflasche mithilfe dieser beiden Variablen auf den Boden der Baugrube ab.Übung 2
Wenn du noch keine Erfahrung mit dem Rechnen mit Sinus, Cosinus und Tangens hast, kannst du diese Übung überspringen.Wir möchten anstelle von Gradmaß den Winkel lieber als Radiantenmaß angeben. Definiere eine Variable für einen Winkel von 0,5*PI in Radiantenmaß. Definiere eine zweite Variable für den Winkel in Gradmaß, rechne die erste Variable von rad in ° um und weise das Ergebnis der zweiten Variable zu. Drehe anschließend den Ausleger mit der zweiten Variable als Parameter.
Übung 3
Wenn du noch keine Erfahrung mit dem Rechnen mit Sinus, Cosinus und Tangens hast, kannst du diese Übung überspringen.Wir möchten den Kran um einen x-Wert und y-Wert bewegen. Dazu müssen wir ein Delta x und Delta y in eine Drehbewegung des Auslegers und das Fahren der Laufkatze umrechnen. Hierzu stehen uns die trigonometrischen Funktionen
sin(),
cos(), tan(),
asin(), acos() und atan(), sowie die Wurzelfunktion
sqrt() zur Verfügung. Hinweis: Das "^" Zeichen hat in dieser
Programmiersprache eine andere
Bedeutung als Potenz. Schreibe Potenzen der Einfachheit halber an dieser Stelle einfach aus
(100²=100*100). Definiere dir zwei Variablen für Delta-X und Delta-Y, führe die
entsprechende Umrechnung in eine Distanz und einen Winkel durch und rufe anschließend die Methoden drive() und turn()
auf. Der Kran soll sich um 200 mm in X und 200 mm in Y Richtung bewegen.
Kapitel 5: Positionsabfrage
Neuer Inhalt
Um den Kran besser steuern zu können, besitzt er drei Methoden, um die Position abfragen zu können.getDistance() gibt die Entfernung der Laufkatze in mm vom Turm an.crane.drive();
float distance = crane.getDistance();
Der Wert der Variable distance für den Abstand der Laufkatze zum Turm beträgt:
getAngle() gibt den Drehwinke des Auslegers im Radiantenmaß an.crane.turn();
float angle = crane.getAngle();
Der Wert der Variable angle für den Drehwinkel des Auslegers beträgt:
getHeight() gibt den Abstand der Kranflasche zur Laufkatze in mm an. crane.wind();
float height = crane.getHeight();
Der Wert der Variable height für den Abstand der Kranflasche beträgt: Durch diese Abfragen ist es möglich absolute Bewegungen auszuführen (z.B. die Kranflasche auf eine Höhe von -300 mm absenken). Bisher haben wir immer nur relative bewegungen ausführen können (z.B. die Kranflsche um -300 mm absenken, unabhängig von ihrer aktuellen Position).
Übung 1
Die Laufkatze soll sich unabhängig von ihrer aktuellen Position auf eine Ausladung von 600 mm bewegen.Übung 2
Der Kran soll sich unabhängig von seiner aktuellen Position zum Lagerplatz auf der Baustelle bewegen. Dieser befindet sich bei einer Ausladung von 300 mm, einem Drehwinkel von 90° und in einer Höhe von -955 mm.Kapitel 6: If-Abfragen
Neuer Inhalt
Bisher läuft unser Programm linear ab. Wie bei einem Kochrezept arbeitet der Computer Schritt für Schritt unsere Zeilen Code ab. Um das Programm dynamischer zu gestalten, gibt es dieif-Abfragen. Diese sehen
wie folgt aus:
if(Bedingung){Code}Ist die Bedingung in den runden Klammern erfüllt, springt das Programm in die geschweiften Klammern und führt den dort geschriebenen Code aus. Ist die Bedingung hingegen nicht erfüllt, wird der Code in den geschweiften Klammern übersprungen. Wir treffen im Zusammenhang mit if-Abfragen auf den Datentyp
bool (oder auch
boolean). Die Bedingung muss von diesem Datentyp sein. Ein Objekt des Datentyps
bool
kann nur zwei Werte annehmen, nämlich true und false. Der Kran
besitzt drei Methoden die einen solchen bool
als Ergebnis zurückgeben. Die Methode isDriving() gibt den Zustand der
Laufkatze in dem Moment in dem die Methode aufgerufen wurde zurück.
Bewegt sich die Laufkatze, während die Methode aufgerufen wird, lautet das zurückgegebene
Ergebnis true. Ansonsten lautet das Ergebnis false.crane.drive();
crane.isDriving();
Das Ergebnis ist:
Die Methode
isTurning() gibt den Zustand des Auslegers in dem Moment, in dem die
Methode aufgerufen wurde zurück.
Dreht sich der Ausleger, während die Methode aufgerufen wird, lautet das zurückgegebene
Ergebnis true. Ansonsten lautet das Ergebnis false.crane.turn();
crane.isTurning();
Das Ergebnis ist:
Die Methode
isWinding() gibt den Zustand der Seilwinde bzw. der Kranflasche in
dem Moment in dem die Methode aufgerufen wurde zurück.
Dreht sich die Winde und bewegt sich somit die Kranflasche, während die Methode aufgerufen
wird, lautet das zurückgegebene Ergebnis true. Ansonsten lautet das Ergebnis
false.crane.wind();
crane.isWinding();
Das Ergebnis ist:
Wenn wir wissen möchten, ob ein
bool nicht zutrifft, können wir ein
"!"-Zeichen voranstellen. Dieser sog. not-Operator dreht das Ergebnis des
bool um.
Aus !true wird also false und aus !false wird
true.Probieren wir unser neu gelerntes Wissen zur
if-Abfrage und dem Datentyp bool
aus: Der untere Code wird nur ausgeführt, wenn der Ausleger sich nicht dreht.
crane.turn();
if(!crane.isTurning()){
crane.turn();
}
if-Abfrage kann ergänzt werden durch einen else-Befehl, oder eine
else if-Abfrage. Diese Kombination von if und else kann
wie folgt aussehen: if(Bedingung1){Code1}else if(Bedingung2){Code2}else if(Bedingung3){Code3}else{Code4}Das Ergebnis sähe wie folgt aus: Ist die
Bedingung1 erfüllt, wird der Code1
ausgeführt und das Programm ist beendet.
Trifft die Bedingung1 jedoch nicht zu, wird als nächstes Bedingung2 überprüft.
Falls diese erfüllt wird, wird Code2 ausgeführt und das Programm beendet.
Trifft Bedingung2 jedoch auch nicht zu, wird Bedingung3
überprüft und Code3 ausgeführt, falls
Bedingung3 erfüllt wird. Sollten jeoch werder Bedingung1,
Bedingung2 oder Bedingung3, erfüllt sein, wird aufgrund des
else-Befehls der Code4 ausgeführt. Es können also an eine if-Abfrage
beliebig viele else if-Abfragen angehängt werden. Am Ende kann jedoch maximal ein
einzelner else-Befehl stehen.
Die Bedingungen von if-Abfragen lassen sich durch die Operatoren && (und) und
|| (oder) kombinieren. Somit lässt sich folgender Ausdruck
if(Bedingung1){
if(Bedingung2){Code1}
}zusammenfassen zu
if(Bedingung1 && Bedingung2){Code1}.Nur wenn
Bedingung1 und Bedingung2 erfüllt sind, wird der Code1 ausgeführt.
Der Ausdruck
if (Bedingung1){Code1}
else if (Bedingung2){Code1}lässt sich hingegen zusammenfassen zu
if (Bedingung1||Bedingung2){Code1}.Falls
Bedingung1 oder Bedingung2 oder beide erfüllt sind,
wird Code1 ausgeführt.
Übung 1
Die Kranflasche soll abwechselnd um 200 mm nach vorne und anschließend um 200 mm zurück Fahren.Übung 2
Zusätzlich zur vorherigen Übung soll die Kranflasche um 200 mm nach vorne fahren und der Ausleger sich um 45° drehen. An dieser Position angekommen soll wieder um 200 mm zurückgefahren werden und um -45° gedreht werden. Dieser Vorgang soll immer wieder wiederholt werden.Übung 3
Zusätzlich zur vorherigen Übung soll auch eine Hubbewegung in die wiederholdene Bewegung eingebaut werden. Die Kranflasche soll sich dazu um 300 mm absenken und im Anschluss wieder um 300 mm anheben.Übung 4
Der Kran soll zu einem absoluten Winkel schwenken. Dabei soll er abhängig von seiner aktuellen Position prüfen, was der kürzeste Schwenkweg ist und dementsprechend mit oder gegen den Uhrzeigersinn schwenken. Als Beispiel soll der Ausleger sich in einem Winkel von 0° gefinden. Um an die Position 15° zu schwenken, ist der kürzeste Weg 15° gegen den Uhrzeigersinn. Um hingegen an eine Position von 350° zu schwenken ist es küzer um 10° mit dem Uhrzeigersinn zu schwenken.Übung 5
Der Kran soll sich wie in der letzten Übung im vorherigen Kapitel zum Lagerplatz bewegen. Dieser befindet sich bei einer Ausladung von 300 mm, einem Drehwinkel von 90° und in einer Höhe von -955 mm. Um beim Schwenken und Fahren nirgends hängenzubleiben, soll er vorab die Laufkatze voll aufwickeln. Erst dann kann der Ausleger gefahrenfrei geschwenkt und die Laufkatze gefahren werden. Wenn sich die Kranflasche im korrekten Winkel und in der richtigen Auslegung befindet, kann die Kranflasche auf die angegebene Höhe von -955 mm abgesenkt werden. Tipp: Für die Lösung dieser Aufgabe musst du in derloop()
Funktion arbeiten und geschickt if-Abfragen miteinander kombinieren.
Übung 2
Wenn du noch keine Erfahrung mit dem Rechnen mit Sinus, Cosinus und Tangens hast, kannst du diese Übung überspringen.Der Kran soll unabhängig von seiner aktuellen Position an absolute x-, y- und z-Koordinaten bewegt werden können. Entwickle hierzu einen Ablauf, der die Koordinaten in die entsprechenden Bewegungsparameter für drive und turn umrechnet. Beachte hierbei, dass Bewegungen in alle x-y-Quadranten möglich sind (I. Quadrant (+x/+y), II. Quadrant (-x/+y), III. Quadrant (-x/-y) IV. Quadrant (+x/-y)
| Ausladung ⟷ [mm] |
Drehwinkel ∡ [°] |
Hubhöhe ↕ [mm] |
||
|---|---|---|---|---|
| Relativ | ||||
| Absolut | ||||
| Korrigieren |