Android mit Arduinoâ„¢ Due. Manuel di Cerbo
man rohe Byte-Daten mit dem Hammer-Terminal (http://www.der-hammer.info/terminal/) versenden. Dazu wählt man als Type »DEC« und kann nun Zahlen zwischen 0 und 255 eingeben.
Genau dieser Sketch kann später auch zusammen mit einem Android-Gerät verwendet werden, vorausgesetzt das Android-Gerät verfügt über USB-Host-Funktionalität. Damit die Kommunikation auch über Android Accessory Mode funktioniert, wird der Sketch noch etwas erweitert.
2.7 LED-Intensität steuern über serielle Konsole und Android Accessory Mode
Der nachfolgende Sketch wurde erweitert, damit die Lichtintensität auch über den Android USB Accessory Mode eingestellt werden kann.
#include <adk.h>
#include <Scheduler.h>
#define LED 13
#define RCVSIZE 128
char model[] = "HelloWorldModel";
char description[] = "A Hello World Accessory";
char company[] = "Hello Inc";
char versionNumber[] = "1.2";
char serialNumber[] = "1";
char url[] = "http://www.osciprime.com";
USBHost Usb;
ADK adk(&Usb, company, model, description,versionNumber,url,serialNumber);
void setup()
{
cpu_irq_enable();
pinMode(LED, OUTPUT);
Serial.begin(9600);
delay(200);
Scheduler.startLoop(adkLoop);
Scheduler.startLoop(serialLoop);
}
void loop(){
yield();
}
void serialLoop(){
uint8_t cmd = 0;
if(Serial.available()){
cmd = Serial.read();
analogWrite(LED,cmd);
}
yield();
}
void adkLoop()
{
uint8_t buf[RCVSIZE];
uint32_t nbread = 0;
uint8_t cmd = 0;
Usb.Task();
if (adk.isReady()){
adk.read(&nbread, RCVSIZE, buf);
if (nbread > 0){
cmd = buf[0];
analogWrite(LED,cmd);
}
}
yield();
}
Die Definitionen zu Beginn wie model, description, company etc. dienen dazu, das Android Accessory zu beschreiben. Besonders bei diesem Sketch ist, dass zwei Loops gleichzeitig ausgeführt werden. In der setup()-Funktion sieht man, dass zwei Loops gestartet werden mit Scheduler.startLoop(). Die Scheduler Library ist eine Besonderheit des Arduino Due, andere Boards mit AVR-Mikrocontrollern unterstützen diese Funktionalität (noch) nicht. Die beiden Loops laufen quasi unabhängig voneinander. Der serialLoop kümmert sich um die serielle Kommunikation und der adkLoop um den Android Accessory Mode. Es fallen die yield()-Aufrufe auf. Die Funktion yield() gibt die Kontrolle zwischenzeitlich an andere Tasks bzw. Loops ab und sollte im Zusammenhang mit dem Scheduler mehrfach gebraucht werden.
Die Anweisungen innerhalb des adkLoop sind quasi analog zu serialLoop. Ein Beispiel zum Android Accessory Mode findet man übrigens auch unter File > Examples > USBHost > ADKTerminalTest.
Der obige Sketch wird später für die Kommunikation zwischen Android-Gerät und Arduino Due verwendet. Sowohl für Kommunikation via Android-USB-Host als auch via Android Accessory Mode.
3 Android
3.1 Betriebssystem Android
Um alle Bestandteile dieses Buches zu verstehen, macht es Sinn, zuerst einen Überblick über Android zu erhalten. Android ist ein Betriebssystem, das Gebrauch vom Linux-Kernel macht.
Android ist für mobile Systeme ausgelegt. Insbesondere heißt das, es ist für Energieeffizienz und beschränkte Ressourcen (niedrige CPU-Taktfrequenz, niedrige Speicherkapazität, kleines RAM etc.) konzipiert worden. Da Android für den mobilen Einsatz gedacht ist, wurde auch an das Verwalten von Batterie, Wi-Fi, Bluetooth, Kamera etc. schon von Anfang an gedacht, speziell auch daran, dass gewisse Teile, wie Grafik- und Kamera-Treiber, »Closed Source« vom Hardware-Hersteller (OEM) geliefert werden.
Open Source heißt, der Source-Code von Android kann von jedem inspiziert und modifiziert werden. Die Weiterentwicklung des Systems findet allerdings zum größten Teil bei Google intern statt, dabei werden »Major Releases« (größere Versionen) von Android dann wieder für die Öffentlichkeit freigegeben.
Um eine bessere Übersicht über das System zu bekommen, studieren wir Bild 3.1. In dieser Illustration sehen wir, aus welchen Schichten das Betriebssystem zusammengesetzt ist. Architektonisch bietet Android nämlich so einige Einzigartigkeiten und unterscheidet sich stark von seinen »nächsten« Verwandten (Embedded Linux, iOS, Windows Mobile). Das Modell veranschaulicht hardwarenahe Teile des Systems (im unteren Bereich des Modells) und eher hardwareferne Elemente (oben).
Bild 3.1: Der Aufbau des Android-Betriebssystems.
3.1.1 Kernel
Der Kernel ist der Teil des Betriebssystems, der direkt auf der Hardware aufsetzt. Android verwendet dazu den Linux-Kernel, welcher unter der Open-Source-Lizenz GPL verfügbar ist. Hardware-Treiber werden so durch den Kernel verwendet, wobei gewisse Treiber »closed source« vom OEM geliefert werden, die dann außerhalb des Kernels agieren (Video Codec, Audio, Kamera etc.). Dies ist einer der größten Schwachpunkte des Systems. Für die Entwickler gibt es so nämlich eine massive Hürde, ein Update für eine bestehende Hardware zu erstellen, weil sie jeweils auf die Aktualisierung der »closed« Treiber durch den OEM angewiesen sind. Der Kernel stellt auch die Funktionalität von USB zur Verfügung, was wir später in einem Versuch noch genauer betrachten werden.
3.1.2 Native Daemons
Sobald der Kernel gestartet ist, übernehmen Daemons den Lebenszyklus des Systems. Der berühmteste darunter ist »init«: der erste Prozess des Systems. Init startet zusätzliche wichtige Daemons (netd, vold, rild, …). Ein anderer für Android spezifischer Daemon ist der »system_server«. Er stellt das Herzstück des Systems dar und bietet die Basis für die verschiedenen »services«, welche auf dem System aufsetzen.
3.1.3 Libraries
Ein wichtiger Bestandteil sind die Bibliotheken (Libraries), welche für ein vielseitiges Spektrum an Aufgaben im System verwendet werden. Darunter befinden sich auch viele Open-Source-Libraries wie z. B. libpng für das Erstellen von PNG-Bildern oder auch libsqlite, welche für SQL-Datenbanken verwendet wird. Ein weiterer Bestandteil der Libraries ist auch die Bionic Libc, eine Sprachlibrary für C, welche sich von der Linux-Library glibc in Art und Lizenz unterscheidet und von den Android-Entwicklern selbst erstellt wurde. Einen weiteren Teil stellen Framework-Bibliotheken für Android dar, welche zur Laufzeit eingebettet werden und Funktionalität für das Zusammenspiel von Android mit Hardwaretreibern implementieren und des weiteren Kernfunktionalität für das Betriebssystem liefern. Proprietäre (oder closed source) Libraries werden vom OEM zur Verfügung gestellt und ermöglichen so Kommunikation mit angeschlossener Hardware