Arduino über Adobe AIR steuern
Ich habe mich letztens wieder einmal mit dem Arduino-Board beschäftigt und bin dabei auf folgende Aufgabenstellung gestoßen:
Ich habe ein Arduino-Board, das über einen Digitalen Ausgang ein Relay steuert welches wiederrum einen Türöffner aktiviert. Ich hätte gerne ein Webinterface über das ich mit einem einfachen Klick dem Arduino den Befehl zum HIGH-schalten des Ausgangs geben kann, um so die Tür bequem von meinem Computer aus zu öffnen.
Zuerst: Arduino Sourcecode
Da wir eigentlich nur einen Ausgang HIGH oder LOW setzen, sieht der Arduino-Sourcecode recht übersichtlich aus:
- void setup(){
- Serial.begin(19200); // Baudrate merken
- Serial.print("Serial is online"); // mal was über die Serielle Leitung schicken
- pinMode(6, OUTPUT); // auf Pin 6 hängt unser Relais
- }
-
- void loop(){
- if (Serial.available() > 0) {
- char message = Serial.read();
- switch (message) {
- case 'e': // e wie EIN
- digitalWrite(6, HIGH);
- break;
- case 'a': // a wie AUS
- digitalWrite(6, LOW);
- break;
- default: // ansonsten Fehlermeldung
- Serial.print("unknown command");
- }
- }
- delay(100); // bisschen schlafen um ggf. die Serielle Schnittstelle nicht zu überlasten
- }
Zweiter Schritt: Seriell zu TCP
Da das Arduino-Board (Duemilanove) über keinen Netzwerkanschluss verfügt und nur über eine Serielle ansprechbar ist brauchen wir einen Proxy, der die Seriellen Daten in das TCP Protokoll überträgt. Das übernimmt für uns Serproxy. Das kleine Script ist einfach über die serproxy.cfg zu konfigurieren:
# Transform newlines coming from the serial port into nils
newlines_to_nils=true
# der COM-Port des USB2Serial Adapters
comm_ports=6
# Default settings
comm_baud=19200 # wichtig hier die gleiche Baudrate angeben wie im Arduino Sourcecode
comm_databits=8
comm_stopbits=1
comm_parity=none
# Idle time out in seconds
timeout=600
# TCP Port, auf die der Serielle Port weitergeleitet werden soll
net_port6=5331
# zu beachten: net_port6 - die Ziffer hinten muss die gleiche sein wie die Nummer des Serial-Ports
Dann einfach die exe mit genügend Rechten starten und im Hintergrund laufen lassen. In dem Zusammenhang vielleicht erwähnenswert ist das Program runhiddenconsole.exe. Einfach über eine .bat Datei
runhiddenconsole.exe serproxy.exe
ausführen und das Programm läuft bequem im Hintergrund.
Schritt drei: Flex kommt ins Spiel
Um unsere AIR Aplikation zu basteln brauchen wir zuerst ein SDK. Es gibt ein einfachesKonsolenbasiertes von Adobe selbst, aber da ich schon länger mit Eclipse arbeite, habe ich mich für das Aptana AIR Plugin für Eclipse entschieden. Zusätzlich braucht man natürlich (wenn noch nicht vorhanden) die AIR Runtime Umgebung.

Ich habe mich aus Bequemlichkeitsgründen für AIR + JavaScript/HTML entschieden.
Wir starten in Eclipse (auf die Aptana Web Oberfläche wechseln) ein neues Projekt (Web / Adobe AIR Projekt) zuerst können wir ein paar allgemeine Angaben machen.
Nach einem klick auf Next gelangen wir auf die Seite wo Namespace und die default-Icons angegeben werden. Die Icons kann man ruhig derzeit auf ihren Voreinstellungen belassen und einfach später im Projektverzeichniss austauschen.

Jetzt sollten wir das Projekt links im Projects Verzeichniss sehen und öffnen mal die Control.html (oder wie auch immer ihr eure Start-Datei benannt habt), ändern den Titel und erstellen eine onload Funktion.
<html>
<head>
<title>Arduino Control</title>
<script type="text/javascript" src="lib/air/AIRAliases.js"></script>
<script type="text/javascript">
function doLoad() {
}
</script>
</head>
<body onload="doLoad();">
<input type="button" onclick="ein();" value="ein">
<input type="button" onclick="aus();" value="aus">
</body>
</html>
Zwischendurch können wir unsere App immer wieder mit Str-F11 starten und testen ob noch alles läuft.
Der nächste Schritt ist der aufbau einer Socket Verbindung auf den Socket, den wir in Serproxy angegeben haben:
<html>
<head>
<title>Arduino Control</title>
<script type="text/javascript" src="lib/air/AIRAliases.js"></script>
<script type="text/javascript">
function doLoad() {
// socket verbindung aufbauen
conn = new air.Socket();
conn.connect( 'localhost', 5331 ); // erster Parameter ist der Host, zweiter der Port der Verbindung
conn.addEventListener( air.DataEvent.DATA, doData );
}
function doData(e) {}
</script>
</head>
<body onload="doLoad();">
<input type="button" onclick="ein();" value="ein">
<input type="button" onclick="aus();" value="aus">
</body>
</html>
doData ist der Event-Handler, der bei einkommenden Daten aufgerufen wird. Hier könnten wir später zum Beispiel responses von Arduino auswerten und ggf. Fehlermeldungen anzeigen, oder man wertet Sensordaten aus.
Jetzt noch die ein und aus Funktionen und schon sind wir fertig:
<html>
<head>
<title>Arduino Control</title>
<script type="text/javascript" src="lib/air/AIRAliases.js"></script>
<script type="text/javascript">
function doLoad() {
// socket verbindung aufbauen
conn = new air.Socket();
conn.connect( 'localhost', 5331 ); // erster Parameter ist der Host, zweiter der Port der Verbindung
conn.addEventListener( air.DataEvent.DATA, doData );
}
function doData(e) {}
function ein() {
conn.writeUTF("e");
conn.flush();
}
function aus() {
conn.writeUTF("a");
conn.flush();
}
</script>
</head>
<body onload="doLoad();">
<input type="button" onclick="ein();" value="ein">
<input type="button" onclick="aus();" value="aus">
</body>
</html>
Wenn wir jetzt auf die Buttons klicken, sollte sich der Ausgang HIGH oder LOW setzten. Testweise kann man ja bei Arduino auf den Ausgang 13 (die interne LED) setzen.
Wenn man diese Fehlermeldung bekommt ist Serproxy nicht richtig konfiguriert oder läuft nicht:

Die application.xml ist sicherlich noch einen Blick wert. Dort kann man Startposition, minimale/maximale Größe des Fensters und andere witzige Sachen angeben.
Wenn alles läuft kann man über diesen Button das ganze als AIR Paket exportieren und einfach auf jedem AIR fähigem Computer ausführen.
Viel Spass beim weitertüfteln.
So sieht der Serproxy Screen aus wenn man die Applikation zweimal geöffnet hat:
