Ein Webserver für den Raspberry Pi (apache, lighthttpd, nginx)

Bisher war für mich klar, ich verwende Apache als Webserver. Seit über 15 Jahren leistet dieser Webserver auf Millionen Webseiten gute Dienste. Warum also überhaupt an eine alternative denken? In den letzten Monaten las ich jedoch immer wieder von anderen Webservern (nginx & lighttpd). Dies hat mich dazu bewogen doch einmal etwas genauer zu recherchieren. Hier meine Ergebnisse:

  • Apache, der klassische Webserver. Lange Konfigurationsdateien. Hoher Speicherverbrauch durch viele Prozesse. Zum Apache Webserver findet man sehr viele Anleitungen im Internet.
  • nginx, ein neuer Webserver. Ngix wird auf einigen großen Seiten eingesetzt. Konfiguration etwas aufwendiger.
  • lighttpd, ein leichtgewichtiger Webserver. Einfach zu Konfigurieren und für kleine Seiten geeignet.

Daher habe ich mich dazu entschieden lighthttpd als Webserver für den Raspberry Pi zu testen.

lighttpd

Die installation ist mit sudo apt-get install lighttpd schnell erledigt. Jedoch unterstützt der Webserver per Default kein php. PHP muss in der Konfigurations-Datei eingerichtet werden. Der Pfad der Konfigurations-Datei ist: /etc/lighttpd/lighttpd.conf. So sieht die Datei mit aktivierten PHP-Support aus:

View the code on Gist.


Das war die Einrichtung von lighttpd, nun kann der Webserver genutzt werden.

Weiterführende Links:

Exit-Code eines Programm in der Shell ermitteln

Das Linux Shell-Script ist eine großartige Sache, leider ist es für mich etwas fremd, da ich aus der Java-Ecke komme. Somit habe ich noch viel zum Shell-Script zu lernen. Meine neuste Erkenntnis ist, wie ich den Exit-Code eines Programms heraus finde. Der Exit-Code einer Anwendung gibt an, ob diese ohne Fehler beendet wurde. Null bedeutet dabei, es sind keine Fehler aufgetreten. Alle Werte größer Null deuten auf ein oder mehrere Fehler hin. Das folgende Listing zeigt wie man sich den Exit-Code in der Konsole anzeigen lässt:

View the code on Gist.

Die Kamera-API von Android

Mittlerweile sind die Kameras von Smartphones duraus brauchbar. Die Apps für die Kamera vermitteln allerdings kein professiones Kamerafeeling. Ich hätte gerne eine App die sich am Interface einer DSLR anlehnt. Bei der entwicklung der App musste sich jedoch feststellen, dass man normale Einstellungen wie ISO oder Verschlusszeit, nicht über die API einstellen kann. Den Vorschlag für das Feature gab es schon 2009. Leider ist bis jetzt nichts passiert. Somit muss ich mich wohl mit verfügbaren Parameter zufrieden geben, schade drum.

Welche Sprache soll ich nehmen?

 

Für die allermeisten Probleme sind mehrere Sprachen gleich gut geeignet.

Nun eine kleine Übersicht (ohne Anspruch auf Vollständigkeit) über die gängigen Sprachen:


Höhere Scriptsprachen: Python, (evtl. Groovy)

Diese Sprachen zeichnen sich u.a. durch eine kurze Syntax aus (D.h. Man schreibt weniger Quellcode). Für Anfänger ist Python eine gute Wahl. Mit Python kann man sowohl kleine Programm als auch größere sehr gut schreiben.


Programmiersprachen: Java, C#

Diese Sprachen sind dazu gedacht um größere Programme zu schreiben. Deswegen ist der Overhead für kleine Programme (im Vergleich zu Python) groß. Jedoch kann man mit diesen Sprachen sehr strukturiert und systematisch arbeiten. Durch die starke Typisierung dieser Sprachen lassen sich bereits geschriebene Quelltext sehr gut wiederverwenden. Aufgrund der sehr hohen Verbreitung dieser Sprachen sind die Entwicklungstool für Java und C# sehr gut (erfordern allerdings auch etwas Einarbeitungszeit).


C/C++ (und auch Go)

C/C++ sollte man in betracht ziehen, wenn man hardwarenah programmieren möchte und/oder viel Performance braucht. Für Anfänger halte ich C/C++ nicht sehr geeignet. Oft sind Fehlermeldungen irreführend. Auch muss man sich um sehr viel mehr Dinge kümmern als bei Python, Java und C# (z.B. Speichermanagment).


Websprachen: PHP, Ruby

Bei PHP und Ruby handelt es sich um höhere Schriptsprachen die darauf ausgelegt sind in Webanwendungen benutzt zu werden. Will man nur Webanwendungen erstellen sind diese Sprachen natürlich eine gute Wahl.


Funktionale Spachen: Haskell, F#, Clojure, (evtl. Skala)

Im Gegensatz zu den bisher genannten Sprachen unterscheidet sich das Konzept der Funktionalen Sprachen Grundlegend von bisher genannten Imperativen Sprachen!  Will man eine wirklich neue Sprache lernen und beherrscht breits eine andere Programmiertsprache, dann kann man sich überlege, ob man nicht eine funktionale Sprache lernen will. Bei Funktionalen Sprachen muss man wenig Quelltext schreiben. Ich habe festgestellt das Mathematik Studenten die funktionale Sprache Haskell leicht lernen können.


Spezial Sprachen: R, Prolog, Matlab

Diese Sprachen sind auf eine eingegrenzte Problemdomäne spezialisiert. Mit R kann man beispielsweise sehr gut Statistische Berechnungen anstellen. Benutzeroberflächen und alles andere wird mit R aber zu Aufwendig. Wenn man nur ein Problem lösen will ist eine spezial Sprache oft der einfachste Weg.

OSC

OSC [Open Sound Control] ist ein Protokoll zur Steuerung von (Musik-)Geräten. Es wird jedoch auch generell zur Steuerung eingesetzt. OSC kann über merhere Kanäle wie z.B. seriell, Netzwerk(UDP) übertragen werden.

In einem Projekt muss ich einen Steuerung mit OSC per Netzwerk realisieren. Leider hat die Suche nach dem genauen Aufbau des OSC Protokoll keinen großen erfolg ergeben. Jedoch habe ich per Reverse Engineering einiges über das OSC Protokoll gelernt:

  • OSC ist eine Mischung aus Text und Binär Codierten Daten

Eine OSC Nachricht sieht z.B. wiefolgt aus (Unten einmal Hexadezimal codiert):

/a/b    ,ii    ☺   A
2f 61 2f 62 0 0 0 0 2c 69 69 0 0 0 0 1 0 0 0 41

 photo osc_raw.png

Dabei handelte es sich um die Nachricht das Gerät /a/b auf die beiden Integers 1 und 65 einzustellen.

Will man sich jedoch nicht mit dem genauen Aufbau beschäftigen gibt es auch Bibliotheken wie Ventuz OSC für .NET bzw. C#. Diese machen den Umgang sehr einfach.

Senden geht wie folgt:

var writer = new UdpWriter("127.0.0.1", 9000);
var elem = new OscElement("/a/b", 1, 65);
writer.Send(elem);

Links:

Webcam unter Java mit OpenCV nutzen

An die Bilder einer Webcam zu kommen ist gar nicht so einfach. Ein wirklich gute Standardisierte API gibt es dafür leider nicht. Deswegen bleibt nur der Weg über eine Bibliothek. Nach einem Test der Processing API habe ich mich nun für OpenCV entschieden. OpenCV ist eine sehr weit verbreitete Bildverarbeitungsbibliothek aus dem C++ Umfeld. Mittlerweile gibt es auch ein offizielles Build für Android und Java SE. OpenCV ermöglicht ein zuverlässiges und schnelles auslesen der Webcam. Das folgende Listing zeigt wie man ein Bild von der Webcam ausliest und in einer Datei speichert:

View the code on Gist.

Um OpenCV nutzen zu können muss noch eine DLL für die entsprechende CPU Architektur (32- oder 64 Bit) geladen werden.

OpenCV auf dem Raspberry Pi kompilieren

OpenCV ist eine sehr leistungsfähige freie Bildverarbeitungsbibliothek. In diesem kleinen Tutorial möchte ich zeigen wie man OpenCV auf dem Raspberry Pi einrichtet. Und C++-Programme mit OpenCV erstellt. Da Bildverbeitung ein rechenintensiver Vorgang  und der RPi nicht grade über viel Rechenleistung Verfügt ist C++ die Sprache der Wahl.
Um OpenCV auf dem Raspi nutzen zu können benötigt man eine kompilierte Variante, da es bisher kein fertiges Build für den Raspberry Pi gibt. Beim kompilieren gibt es 2 Möglichkeiten:
  • Man kompiliert auf einen anderen Rechner für den Pi
    • Schnell, aber man braucht einen Rechner mit Cross-Compiler
  • Man kompiliert auf dem Raspberry selbst
    • Dauert etwas mehr als 7 Stunden.
Ich habe mich dafür Entschieden auf dem Raspberry Pi zu kompilieren. Für das Kompilieren auf einem Linux-System gibt es auf der OpenCV-Seite ein Tutorial (http://docs.opencv.org/doc/tutorials/introduction/linux_install/linux_install.html). Ich habe auf dem Raspberry Pi Raspian laufen. Damit das kompilieren ohne Fehler laufen kann, müssen die nötigen Pakete installiert werden. Das geht mit:

View the code on Gist.

An der Abhängigkeit libgtk2.0-dev sieht man, dass es ohne X-Server zu Problemen kommen könnte.
Das kompilieren von OpenCV kann mit folgenden Script ausgeführt werden (Achtung das Script benötigt etwas mehr als 7 Stunden um OpenCV zu kompilieren):

View the code on Gist.

Danach ist OpenCV hoffentlich richtig installiert und man kann mit dem Entwickeln anfangen. Auch dafür gibt es ein offizielles OpenCV Tutorial für Linux:
Da ich meinen Raspberry Pi als Server ohne Monitor nutze habe ich das Program so umgeschireben, dass man ein Ergebnis auch ohne am Raspberry Pi angeschlossen en Monitor sehen kann. Folgendes Programm lädt ein Bild und passt Kontrast und Helligkeit an. Das Programm dient nur dazu um festzustellen ob OpenCV funktionsfähig ist, schönere Bilder darf man sich davon nicht erhoffen 😉

View the code on Gist.

Der Quelltext muss in der Datei DisplayImage.cpp gespeichert werden. Danach geht es ans kompilieren unseres Programms. OpenCV nutzt cmake als Helfer für den Build. Bei eigenen Projekten sollte man deshalb auch cmake benutzen. Um cmake nutzen zu können benötigen wir eine CMakeLists.txt mit folgenden Inhalt:

View the code on Gist.

Wie man der Datei entnehmen kann ist es wichtig das unsere Quellcode-Datei den Namen DisplayImage.cpp trägt. Durch aufruf von cmake . erzeugt cmake die eigentlich Builddatei im gewohnten make Format, also den Makefile. Nun kann man das Programm mit dem Befehl make kompilieren.
Danach kann man endlich das fertige Programm ausführen. Dazu benötigt man natürlich eine Bilddatei. Das Ergebnis kann man sich das per SCP oder ähnlichen Programmen auf den Rechner hohlen und angucken.

View the code on Gist.