Aus Raspberry Pi Geek 06/2014

Das C-Berry-Display als Touchscreen (Seite 2)

Abbildung 3: Ausgabe einer Bilddatei mit Fbi auf das C-Berry Touch als Framebuffer-Gerät.

Abbildung 3: Ausgabe einer Bilddatei mit Fbi auf das C-Berry Touch als Framebuffer-Gerät.

Grundsätzlich können Sie auch Videos, eine Konsole oder eine X11-Oberfläche auf einem Framebuffer-Gerät ausgeben. Aus Geschwindigkeitsgründen sollten Sie es dann jedoch als Kernel-Modul einbinden [6]. Wie gut bewegte Bilder funktionieren, zeigt ein Test mit einem Video. So spielt MPlayer mit dem Aufruf aus Listing 4 ein Video über das Framebuffer-Gerät /dev/fb0 ab.

Listing 4

 

$ mplayer -nolirc -vo fbdev2:/dev/fb0 -vf scale=320:-3 Videodatei

Dabei lässt sich gut erkennen, dass sich die Framebuffer-Ausgabe auf dem C-Berry Touch nur bedingt für bewegte Bilder eignet. Während Sie eine Konsole in einer geeigneten Auflösung noch sinnvoll nutzen können, müssen Sie bei einer X11-Oberfläche schon etwas nachhelfen. Auf einen ausführlichen Test haben wir daher an dieser Stelle verzichtet.

Das resistive Touch-Panel des C-Berry Touch verlangt zudem einen ordentlichen Druck auf das Display, sodass die flinke Touch-Bedienung eines X11-Fensters etwas behäbig vonstattengeht. Für Anwendungen mit großen Bedienelementen eignet sich das Display deutlich besser. Eine solche stellen wir daher im nächsten Abschnitt vor.

Die Touch-Funktion in eigenen Programmen nutzen

In unserem letzten Artikel zum C-Berry-LCD [1] haben wir gezeigt, wie Sie das Display programmieren. Dabei diente ein Programm als Beispiel, das Bitmap-Dateien lädt. Im Folgenden zeigen wir, wie Sie das Programm so erweitern, dass es Touch-Eingaben verarbeitet. Als Grundlage dient wieder der QR-Code-Player [7], der aktuell noch mit einer Fernbedienung gesteuert wird. Nun soll das C-Berry Touch deren Funktion übernehmen.

Zunächst erstellten wir eine Bitmap-Datei, die grafische Elemente für die Touch-Eingaben enthält (Abbildung 4). Dabei waren die Programme Gimp und Inkscape sehr hilfreich. Die Bedienelemente entliehen wir aus dem Icon-Fundus von Gnome: Sie fallen groß genug aus, um sie mit einem festen Fingerdruck sicher zu aktivieren.

Abbildung 4: Die Anzeige mit den grafischen Elementen für die Touch-Eingabe.

Abbildung 4: Die Anzeige mit den grafischen Elementen für die Touch-Eingabe.

Das Programm load_gui.c in Listing 5 bringt die Bitmap auf das Display und definiert gleichzeitig Bildschirmabschnitte für die Lage der Bedienelemente. So legt die folgende Zeile etwa die Lage des Kamera-Icons fest:

int cam_area[] = {35, 55, 50, 95};

Hier sehen Sie, dass die Koordinaten auf dem Touch-Panel nicht mit den Koordinaten der Bildschirmpixel übereinstimmen: Zwar weist das Display eine Auflösung von 320 x 240 Pixeln auf, doch liefert das Touch-Panel x- und y-Werte zwischen 20 und 180. Die Lage der grafischen Bedienelemente finden Sie am einfachsten durch Ausprobieren heraus. Dafür findet sich in den Zeilen 39 bis 41 eine Ausgabe, die Sie bei Bedarf auskommentieren. Dazu entfernen Sie die Kommmentaranweisungen “/*” und “*/” in den Zeilen 37 und 42.

Listing 5

 

#include <bcm2835.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include "tft.h"
#include "RAIO8870.h"
#include "bmp.h"
int in_area(int x, int y, int area[4]) {
  /* area => [x1, x2, y1, y2] */
  if ((x > area[0]) && (x < area[1]) && (y > area[2]) && (y < area[3]))
    return 1;
  return 0;
}
void Touch_gui () {
  int i=0, rt;
  int cam_area[] = {35, 55, 50, 95};
  int prev_area[] = {45, 70, 120, 140};
  int pause_area[] = {80, 95, 120, 140};
  int play_area[] = {105, 125, 120, 140};
  int next_area[] = {130, 150, 120, 140};
  int vol_up_area[] = {150, 175, 25, 55};
  int vol_down_area[] = {150, 175, 75, 115};
  uint8_t btn_old_state = up;
  int state = 3;
  int x = 0, y = 0;
  while(1) {
    rt = RAIO_gettouch();
    state = my_touch.state;
    x = my_touch.touch_x;
    y = my_touch.touch_y;
    /*
    // Zeige Touch-Werte und -Status auf der Konsole
    printf( "\n.... x=%d", my_touch.touch_x );
    printf( "\n.... y=%d", my_touch.touch_y );
    printf( "\n state = %d", my_touch.state );
    */
    if((state == pressed) && (btn_old_state != state)) {
      btn_old_state = state;
      if (in_area(x, y, cam_area)) {
        printf("Camera\n");
        i = system("sudo -u pi \
        zbarcam --nodisplay -Sdisable -Sqrcode.enable \
        --prescale=320x240 -Sposition=disable /dev/video0 | \
        /home/pi/QRMusic/rbar.sh");
      }
      else if(in_area(x, y, prev_area)) {
        printf("Previous\n");
        i = system("sudo -u pi xmms2 prev");
      }
      else if(in_area(x, y, pause_area)) {
        printf("Pause\n");
        i = system("sudo -u pi xmms2 pause");
      }
      else if(in_area(x, y, play_area)) {
        printf("Play\n");
        i =  system("sudo -u pi xmms2 toggle");
      }
      else if(in_area(x, y, next_area)) {
        printf("Next\n");
        i = system("sudo -u pi xmms2 next");
      }
      else if(in_area(x, y, vol_up_area)) {
        printf("Volume up\n");
        i = system("sudo -u pi xmms2 server volume +5");
      }
      else if(in_area(x, y, vol_down_area)) {
        printf("Volume down\n");
        i = system("sudo -u pi xmms2 server volume -5");
      }
    }
    else if ((my_touch.state == no_touch) && (btn_old_state != my_touch.state)) {
      btn_old_state = my_touch.state;
    }
    bcm2835_delayMicroseconds( 100000 );
  }
}
int main( int argc, char iargv ) {
  if (!bcm2835_init()) return 1;
  TFT_init_board();
  TFT_hard_reset();
  RAIO_init();
  uint16_t picture[1][ PICTURE_PIXELS ];
  Read_bmp2memory ( "SplashCam.bmp", &picture[0][ PICTURE_PIXELS-1 ] );
  RAIO_Write_Picture ( &picture[0][0], PICTURE_PIXELS );
  Touch_gui();
  bcm2835_close();
  return 0;
}

Zum Kompilieren des Programms benötigen Sie einige Dateien des Beispielcodes: tft.c, tft.h, RAIO8870.c, RAIO887.h, bmp.c sowie bmp.h. Sie übersetzen das Programm dann mit den Aufrufen aus Listing 6. Als Ergebnis erhalten Sie das Programm load_gui, das mit dem Aufruf sudo ./load_gui die Touch-Anwendung auf den Schirm holt.

Listing 6

 

$ gcc -Os -c load_gui.c
$ gcc -Os -c tft.c
$ gcc -Os -c RAIO8870.c
$ gcc -Os -c bmp.c
$ gcc load_gui.o tft.o RAIO8870.o bmp.o -lbcm2835 -lrt -lm -o load_gui

Drücken Sie auf ein Bedienelement in der Anzeige, dann ruft das Programm den Mediaplayer Xmms2 mit der entsprechenden Option auf. Dabei sorgt ein sudo vor dem Aufruf dafür, dass dieser mit den Rechten des Benutzers pi ausgeführt wird. Ein Druck auf das Gebiet prev_area startet also folgendes Kommando:

$ sudo -u pi xmms2 prev

Damit springt der Player einen Titel zurück. Das Gleiche passiert analog bei den Bedienelementen für Pause, Play, Next und lauter (vol_up_area) respektive leiser (vol_down_area).

Für das Aktivieren der Webcam gilt es, aufgrund der zahlreichen Optionen ein längeres Kommando zu konstruieren. Dieses liest einen QR-Code per Webcam ein und übergibt das Ergebnis an das Skript /home/pi/QRMusic/rbar.sh. Von da an läuft alles wie gehabt.

Fazit

Das C-Berry Touch erweist sich als praktische Ergänzung des RasPi für das Präsentieren grafischer Ausgaben und eignet sich dank der Framebuffer-Unterstützung auch gut als Mini-Konsole. Zusammen mit einer Tastatur mutiert der RasPi damit schon zum vollständigen Rechner, der nicht auf eine Bedienung über das Netzwerk angewiesen ist.

RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben