Für Programmierer
Grundlegendes
Um das System zum Laufen zu bekommen, braucht man zwei Programme. Zum ersten muss da natürlich ein Programm sein, das auf dem PC oder auf einem Tablet läuft und das der Schüler bedient. Damit das möglich ist, braucht man ein zweites Programm, nämlich eine spezielle Firmware für den Arduino. Beide Programme kommunizieren nun über ein bestimmtes Protokoll.
Möchte man selbst Programme schreiben, muss man also das Protokoll kennen. Im Kapitel über die Firmware ist dies beschrieben. Für erste Experimente braucht man keine Änderungen an der Firmware vorzunehmen.
Die Kommunikation erfolgt klassisch seriell mit 115200 Baud. Es werden also Bytes über die serielle Schnittstelle geschickt. Somit ist jede Umgebung zur Programmierung geeignet, die serielle Kommunikation ermöglicht.
Die Firmware
Wie arbeitet das Programm?
Der Arduino startet nach dem Einschalten ein Programm, sofern das gespeichert wurde. Programme liegen im EEPROM, können also nicht zu groß sein. Aber er reagiert auch auf ein Anklopfen (BF_ANKLOPFEN). Damit sagt ein Gerät, dass es mit dem Arduino kommunizieren will. Je nach Art des Gerätes schaltet dann der Arduino in den Bluetooth- oder Seriell-Modus und gibt eine Antwort (‘B’ für Bluetooth oder ‘U’ für USB) zurück.
Dann können Befehle entgegen genommen werden. Befehle sind jeweils nur ein Byte. Es können aber noch Daten folgen, z.B. wenn ein Befehl gespeichert werden soll. Die Konstanten BF_xxx geben die Befehle an. Für den Anfang reicht das Abfragen der Sensoren (BF_GIB_SENSORDATEN) oder das sofortige Ausführen eines Befehls (BF_BEFEHLABARBEITEN_A).
Befehl | Beschreibung |
---|---|
BF_ANKLOPFEN | Kommunikationsart festlegen, Bestätigung wird zurück gesendet. |
BF_INTERAKTIV | Der Modus zur Programmabarbeitung wird verlassen. |
BF_PROGRAMMABARBEITEN | Ein Programm wird abgearbeitet. Weil man dann davon ausgehen kann, dass alle Kommandos übertragen wurden, wird es auch im EEPROM gespeichert. |
BF_GIB_SENSORDATEN | Die Sensordaten werden geliefert. Das sind 4 Bytes in Folge. Obwohl SimpleProg im Bereich von 0 bis 100 arbeitet, schöpfen diese Werte den Bereich bis 255 aus. |
BF_SPEICHERE_BEFEHL_A | Legt den folgenden Befehl der Sorte A im Befehlesspeicher ab. |
BF_SPEICHERE_BEFEHL_B | Speichert einen Befehl der Sorte B im internen Befehlsspeicher. |
BF_LOESCHE_PROGRAMM | Löscht das Programm aus dem internen Befehlsspeicher. |
BF_BEFEHLABARBEITEN_A | Sofortiges Abarbeiten des Befehls der Sorte A. |
BF_BEFEHLABARBEITEN_B | Sofortiges Abarbeiten des Befehls der Sorte B. |
BF_ALLES_AUS | Schaltet alles aus, auch Töne. |
Was ist der Unterschied zwischen Befehlen der Sorten A und B?
Ursprünglich gab es nur Befehle der Sorte A. Später wurde mit zustandsbasierten Programmen experimentiert (StateProg), die aber die gleiche Firmware nutzen sollten. In diesem Falle sind aber zwei zusätzliche Bytes notwendig. Zum einen ist der Befehl an einen Zustand gebunden, zum zweiten muss ein Folgezustand angegeben werden, der nach der Bearbeitung gesetzt wird.
Wer mit eigenen Experimenten beginnen will, nimmt somit immer Befehle der Sorte A.
Wie ist ein Befehl der Sorte A aufgebaut?
Ein Befehl der Sorte A kann immer ausgeführt werden oder an eine bzw. zwei Bedingungen geknüpft sein. Typische Beispiele sind also:
IMMER LAMPE1 = 0
WENN EINGABE0 < 50 LAMPE1 = 0
WENN EINGABE0 < 50 ODER EINGABE1 > 100 LAMPE1 = 0
Dies alles muss in Bytes gepackt werden. Ein Befehl der Sorte A hat somit 11 Bytes. Es werden also 12 Bytes übertragen. Das erste Byte sagt, ob der Befehl gespeichert oder sofort abgearbeitet werden soll. Dann folgen die Bedingungen und die Aktionen. Jeder Eintrag der folgenden Tabelle steht für ein Byte.
Byte | Inhalt |
---|---|
Was soll mit dem folgenden Befehl gemacht werden? | BF_SPEICHERE_BEFEHL_A oder BF_BEFEHLABARBEITEN_A |
Wie soll der Befehl ausgeführt werden? | COND_IMMER, COND_WENN |
Welcher Eingang wird verglichen? | 0…3, also die Nummer |
0 oder 1 | Die Relation, 0 - kleiner, 1 - größer; ≤, ≥ oder = gibt es nicht. |
Vergleichswert | 0…255 |
Gibt es noch eine zweite Bedingung? | 0 - nein, 1 - Oder-Verknüpfung, 2 - Und-Verknüpfung |
Eingang für den zweiten Vergleich | 0…3 |
Relation für den zweiten Vergleich | 0 oder 1 |
Vergleichswert | 0…255 |
Befehl | Siehe CMD_xyz |
Parameter1 | 0…255, z.B. der Port |
Parameter2 | 0…255 z.B. der Ausgabewert |
Die Offsets finden sich auch im Quelltext. Suche nach OFFSET_xyz.
Wie ist ein Befehl der Sorte B aufgebaut?
Es kommen zwei Bytes für Zustände hinzu. Zum ersten muss gesagt werden, an welchen Zustand der Befehl gekoppelt ist. Dieser Zustand muss an den Anfang, im Byte-Array also an die zweite Stelle nach BF_BEFEHLABARBEITEN_B oder BF_SPEICHERE_BEFEHL_B. Der Zustand, der bei Abarbeitung als nächster gesetzt wird, steht ganz am Ende. Somit werden 14 Bytes übertragen.
Aus welchen Befehlen kann ein Programm bestehen?
Folgende Befehle sind vorbereitet. Im Quelltext findet man sie unter CMD_xyz.
Befehl | Beschreibung |
---|---|
CMD_SETZE_OUTPUT | Setzt das Pin (Parameter1) auf Ausgabe. |
CMD_SETZE_INPUT | Setzt das Pin (Parameter1) auf Eingabe. |
CMD_SETZE_LOW | Setzt das Pin (Parameter1) auf 0V. |
CMD_SETZE_HIGH | Setzt das Pin (Parameter1) auf 5V. |
CMD_SETZE_WERT | Setzt das Pin (Parameter1) auf einen Wert (Parameter2). Ist nur bei PWM-Pins sinnvoll. Sowohl Männchen als auch die Box nutzen zur Ausgabe aber nur PWN-Pins. |
CMD_MOTOR | Setzt den Winkel (Parameter2) eines Servo-Motors am Pin von Parameter1. |
CMD_TON | Setzt die Frequenz des Lautsprechers an Pin von Parameter1. Die Frequenz ist das Zehnfache von Parameter2. |
CMD_TON_AUS | Schaltet den Ton am entsprechenden Pin aus. |
CMD_WARTE | Wartet das Zehnfache des in Parameter1 übergebenen Wertes in ms. Achtung, bitte keine hohen Werte verwenden, sonst ist der Arduino immer im Wartemodus! |
CMD_BLINKEN | Die LED am Pin (Parameter1) blinkt Parameter2-Mal. |
Wie viele Befehle kann der Arduino im Programmspeicher speichern?
Für die Sorte A sind 15 Plätze reserviert. Das reicht, da SimpleProg nur 12 Plätze hat. Für StateProg sind es 38. Das liegt daran, dass der Uno nur 512 Byte EEPROM hat. Theoretischerweise kann man den (flüchtigen) Speicher hochsetzen. Davon rate ich ab, da dann halbe Programme im EEPROM liegen.
Wie kann man die Verbindungsart, wenn sie einmal gesetzt ist, ändern?
Ausschalten. Einschalten.