Messanwendung mit dem Raspberry Pi, SHT21, Play!, WebSockets, NVD3.js. Teil 2: Installation des Raspberry Pi und Anpassung des C-Programms
Der Raspberry Pi ist ein ec-kartengroßer Computer, der sich durch einen sehr geringen Energieverbrauch auszeichnet. Das verwendete Modell B verbraucht nur 3,5 Watt.
Betriebssystem installieren und starten:
Das verwendete Betriebssystem heißt Raspian, basiert auf Debian und wurde für den Raspberry Pi optimiert. Das Image kann unter der URL http://www.raspberrypi.org/downloads heruntergeladen werden. Um das Image, mit dem Betriebssystem, auf die SD-Karte kopieren zu können ist für Windows folgender Image Writer zu empfehlen: https://launchpad.net/win32-image-writer. Er ist einfach und intuitiv anwendbar. Nach dem Schreiben des Images auf die SD-Karte kann die SD-Karte im Raspberry Pi eingelegt werden. Zur Konfiguration des Raspberry Pi wird dieser mit einem Router verbunden. Nach dem Anschluß der Stromversorgung startet der Raspberry Pi. Ein Aufbau einer ssh-Verbindung von einem anderen Computer zum Raspberry Pi ist nun möglich.
WLAN:
Die Verbindung mit einem WLAN kann nach der Installation des TightVNC Servers, mit dem Kommando „sudo apt-get install tightvncserver“, bequem über eine graphische Oberfläche erfolgen. Ein TightVNC Client ist hierfür notwendig. Nach Anschluß eines WLAN-Adapters und korrekter WLAN-Konfiguration kann das LAN-Kabel entfernt werden.
Einbindung von der Bibliothek libcURL:
Der SHT21 Sensor, zur Messung der Temperatur und Luftfeuchtigkeit, wurde steckfertig von emsytech gekauft und an den Raspberry Pi angeschlossen. Das Basisprogramm, ebenfalls von emsytech, zum Auslesen der Werte, wurde über WinSCP auf den Raspberry Pi kopiert. Die Bibliothek libcURL wurde in dasselbe Verzeichnis kopiert. Die Datei makefile im source-Verzeichnis des Programms wurde um das Flag „-lcurl“ erweitert.
Anpassung der Anwendung in der Datei main.c:
Die Includes der main.c wurden um zwei Includes erweitert:
#include <string.h>
#include <curl/curl.h>
Folgende Variablen wurden hinzugefügt:
int intervall;
CURL *curl;
CURLcode res;
intervall = 1;
Es wurde die Struktur string (diese wird für die unteren Methoden verwendet) deklariert:
struct string {
char *ptr;
size_t len;
};
Die folgende Funktion init_string initialisiert eine struct string.
void init_string(struct string *s) {
s->len = 0;
s->ptr = malloc(s->len+1);
if (s->ptr == NULL) {
fprintf(stderr,"malloc() failed\n");
exit(EXIT_FAILURE);
}
s->ptr[0] = '';
}
Bei der Bibliothekl libcURL existiert die Callback- Option CURLOPT_WRITEFUNCTION. Mit dieser Option kann festgelegt werden, welche Funktion aufgerufen wird, sobald libcURL Daten empfängt, die gespeichert werden sollen.
size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
size_t new_len = s->len + size*nmemb;
s->ptr = realloc(s->ptr, new_len+1);
if (s->ptr == NULL) {
fprintf(stderr, "realloc() failed\n");
exit(EXIT_FAILURE);
}
memcpy(s->ptr+s->len, ptr, size*nmemb);
s->ptr[new_len] = '';
s->len = new_len;
return size*nmemb;
}
In unserer Anwendung kann der Intervall für die Abfrage der Sensordaten dynamisch gesetzt werden. Der Benutzer hat über die Oberfläche der Webanwendung die Möglichkeit den Intervall einzustellen. Bei jeder Übergabe von Messdaten an die Webanwendung wird der Intervall als Response, von der mit Play! realisierten Webanwendung, zurückgeliefert.
Das Intervall war statisch auf 10 Sekunden eingestellt. Dies wurde in if((TimeCounter % intervall) == 0) verändert.
Der folgende Quelltext ist für den Aufbau der aufzurufenden URL, den cURL Anfrage und die Verarbeitung der Antwort zuständig.
char str[100];
sprintf(str,"http://localhost:80/newValues?hum=%d&temp=%f",Humidity,Temp);
printf(str);
curl = curl_easy_init();
if(curl) {
struct string s;
init_string(&s);
curl_easy_setopt(curl, CURLOPT_URL,str);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
res = curl_easy_perform(curl);
if(res!= CURLE_OK){
fprintf(stderr,"curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}else{
printf("\n%s\n", s.ptr);
intervall = atoi(s.ptr);
free(s.ptr);
curl_easy_cleanup(curl);
}
}