Der Raspberry Pi ist schon seit einigen Jahren auf dem Markt, doch leider konnte ich bis jetzt kein Projekt damit anfangen, was mir auch Spaß machen würde. In letzter Zeit habe ich immer mehr von der Programmierung kleiner GUIs mit Python/Pygame gelesen und da war mein Interesse geweckt. Für den Anfang sollte das eine einfache Schaltfläche sein, mit der man fünf Ausgänge setzen und fünf Eingänge einlesen kann. Ich bin kein bzw. kein guter Programmierer und mit Python bin ich zum ersten mal in Berührung gekommen. Zum Glück gibt es im Netz eine Unmenge an Anleitungen, Tutorials, Open Source Codes usw. Dazu kommt noch, dass der Code ziemlich gut lesbar ist.
Das war quasi ein kleines Projekt für den Anfang. Später will ich mit ein kleines Webradio bauen.
Um das Ganze noch interessanter zu machen, wird die GUI auf dem RPi-Display von Watterott angezeigt und darüber (Touchscreen) bedient.
Hier ist eine kleine Demonstration
Folgende GPIOs sind als Ausgänge definiert: 4, 5, 6, 12, 13
Folgende GPIOs sind als Eingänge definiert: 16, 19, 20, 21, 26
Beim Start sind alle Ausgänge auf „LOW“ (Indikator rot). Wenn man auf einen Button drückt, ändert sich der Pegel auf „HIGH“ und der Indikator wechselt von rot auf grün.
Die Eingänge zeigen bei unbelegtem Zustand den Status „HIGH“. Das liegt daran, dass die Pull-Up-Widerstände aktiviert sind. Wird ein LOW-Pegel angelegt, wechselt der Indikator die Farbe von grün auf rot.
Falls jemand Lust hat, das Projekt nachzubauen, hier ist eine Kurze Bauteilliste und eine grobe Anleitung. Ich bin beim Schreiben der Anleitung nicht auf jede Kleinigkeiten eingegangen (wie z.B. Sprache ändern etc.). Anleitungen dafür gibt es echt mehrfach im Netz, sodass man nur kurz eine Suchmaschine anwerfen muss.
Materialliste
- Raspberry Pi B+
- RPi-Display
- GPIO-Adapter
- Internetverbindung
- Tastatur
- USB-Stick
- Steckbrett + Spielzeug, wie LEDs, Jumper Wires, Taster, was auch immer 🙂
Anleitung
- Skript gpiocontrol.py herunterladen
- Raspbian Image herunterladen https://github.com/watterott/RPi-Display
- mit Win32DiskImager oder dd auf eine SD-Karte flashen
- beim ersten Start:
- einlogen
- Benutzer: pi
- Passwort: raspberry (Die Tasten Y und Z sind vertauscht)
- sudo raspi-config (Bindestrich befindet sich bei Tastaturen mit deutschem Layout bei „?“)
- expand Filesystem
- Wenn nötig, bei Internationalisation, Timezone, Spracheinstellungen und Tastaturlayout anpassen
- einlogen
- sudo reboot
- sudo apt-get update
- sudo apt-get upgrade
- sudo rpi-update
- sudo reboot
- sudo TSLIB_FBDEVICE=/dev/fb1 TSLIB_TSDEVICE=/dev/input/touchscreen ts_calibrate
- die fünf Kreuze nacheinander möglichst genau berühren.
- sudo mkdir /mnt/usb
- sudo mount /dev/sda1 /mnt/usb/
- sudo cp /mnt/usb/gpiocontrol.py ~
- sudo python gpiocontrol.py
Skrpit beim Booten ausführen
- sudo nano /etc/rc.local
- und folgende Zeile über dem „exit 0“ einfügen
- (python /home/pi/gpiocontrol.py)&
- mit Strg + X schließen, mit Y bestätigen und neu starten.
Python Skript
Die Software ist evtl. nicht ganz sauber geschrieben, aber für mich funktioniert es so, wie es ist 😉
import pygame
import time
import RPi.GPIO as GPIO
from pygame.locals import *
import glob
import sys
import os
os.environ["SDL_FBDEV"] = "/dev/fb1"
os.environ["SDL_MOUSEDEV"] = "/dev/input/touchscreen"
os.environ["SDL_MOUSEDRV"] = "TSLIB"
#setup gpio
GPIO.setmode(GPIO.BCM)
GPIO.setup( 4, GPIO.OUT)
GPIO.setup( 5, GPIO.OUT)
GPIO.setup( 6, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
#enable pull-up resistors
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#define some colors
#color R G B
white = (255, 255, 255)
red = (255, 0, 0)
green = ( 0, 255, 0)
blue = ( 0, 0, 255)
black = ( 0, 0, 0)
cyan = ( 0, 255, 255)
#initial state colors for indicators
state_color1 = red
state_color2 = red
state_color3 = red
state_color4 = red
state_color5 = red
state_color6 = red
state_color7 = red
state_color8 = red
state_color9 = red
state_color10 = red
pygame.init()
#screen size
width = 320
height = 240
size = (width, height)
screen = pygame.display.set_mode(size)
#define font
font = pygame.font.Font(None, 20)
#initial output state
gpio_state4 = False
gpio_state5 = False
gpio_state6 = False
gpio_state12 = False
gpio_state13 = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
GPIO.cleanup()
running = 0
if event.type == pygame.KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
#if touchscreen pressed
if event.type == pygame.MOUSEBUTTONDOWN:
#get position
pos = (pygame.mouse.get_pos() [0], pygame.mouse.get_pos() [1])
#print "touched"
#print pos
#check in which area (button) the touchscreen was touched
#each area/button = 55x55px
if 5 <= pos[0] <= 60 and 5 <= pos[1] <= 60:
gpio_state4 = not gpio_state4
if gpio_state4 == True:
GPIO.output(4, GPIO.HIGH)
state_color1 = green
time.sleep(0.2)
else:
GPIO.output(4, GPIO.LOW)
state_color1 = red
time.sleep(0.2)
if 65 <= pos[0] <= 120 and 5 <= pos[1] <= 60:
gpio_state5 = not gpio_state5
if gpio_state5 == True:
GPIO.output(5, GPIO.HIGH)
state_color2 = green
time.sleep(0.2)
else:
GPIO.output(5, GPIO.LOW)
state_color2 = red
time.sleep(0.2)
if 125 <= pos[0] <= 180 and 5 <= pos[1] <= 60:
gpio_state6 = not gpio_state6
if gpio_state6 == True:
GPIO.output(6, GPIO.HIGH)
state_color3 = green
time.sleep(0.2)
else:
GPIO.output(6, GPIO.LOW)
state_color3 = red
time.sleep(0.2)
if 185 <= pos[0] <= 240 and 5 <= pos[1] <= 60:
gpio_state12 = not gpio_state12
if gpio_state12 == True:
GPIO.output(12, GPIO.HIGH)
state_color4 = green
time.sleep(0.2)
else:
GPIO.output(12, GPIO.LOW)
state_color4 = red
time.sleep(0.2)
if 245 <= pos[0] <= 300 and 5 <= pos[1] <= 60:
gpio_state13 = not gpio_state13
if gpio_state13 == True:
GPIO.output(13, GPIO.HIGH)
state_color5 = green
time.sleep(0.2)
else:
GPIO.output(13, GPIO.LOW)
state_color5 = red
time.sleep(0.2)
#change indicator's color if input changes (LOW = red, HIGH = green)
if GPIO.input(16) == 1:
state_color6 = green
else:
state_color6 = red
if GPIO.input(19) == 1:
state_color7 = green
else:
state_color7 = red
if GPIO.input(20) == 1:
state_color8 = green
else:
state_color8 = red
if GPIO.input(21) == 1:
state_color9 = green
else:
state_color9 = red
if GPIO.input(26) == 1:
state_color10 = green
else:
state_color10 = red
#lets draw some buttons and indicators
pygame.draw.rect(screen, cyan , ( 5, 5, 55, 25))
pygame.draw.rect(screen, cyan , ( 65, 5, 55, 25))
pygame.draw.rect(screen, cyan , (125, 5, 55, 25))
pygame.draw.rect(screen, cyan , (185, 5, 55, 25))
pygame.draw.rect(screen, cyan , (245, 5, 55, 25))
pygame.draw.rect(screen, cyan , ( 5, 75, 55, 25))
pygame.draw.rect(screen, cyan , ( 65, 75, 55, 25))
pygame.draw.rect(screen, cyan , (125, 75, 55, 25))
pygame.draw.rect(screen, cyan , (185, 75, 55, 25))
pygame.draw.rect(screen, cyan , (245, 75, 55, 25))
pygame.draw.rect(screen, state_color1 , ( 5, 30, 55, 25))
pygame.draw.rect(screen, state_color2 , ( 65, 30, 55, 25))
pygame.draw.rect(screen, state_color3 , (125, 30, 55, 25))
pygame.draw.rect(screen, state_color4 , (185, 30, 55, 25))
pygame.draw.rect(screen, state_color5 , (245, 30, 55, 25))
pygame.draw.rect(screen, state_color6 , ( 5, 100, 55, 25))
pygame.draw.rect(screen, state_color7 , ( 65, 100, 55, 25))
pygame.draw.rect(screen, state_color8 , (125, 100, 55, 25))
pygame.draw.rect(screen, state_color9 , (185, 100, 55, 25))
pygame.draw.rect(screen, state_color10 , (245, 100, 55, 25))
#create some labels for buttons
label1 = font.render ("OUT 4", 1, black)
label2 = font.render ("OUT 5", 1, black)
label3 = font.render ("OUT 6", 1, black)
label4 = font.render ("OUT 12", 1, black)
label5 = font.render ("OUT 13", 1, black)
label6 = font.render ("IN 16", 1, black)
label7 = font.render ("IN 19", 1, black)
label8 = font.render ("IN 20", 1, black)
label9 = font.render ("IN 21", 1, black)
label10 = font.render ("IN 26", 1, black)
#display labels
screen.blit(label1, ( 5, 5))
screen.blit(label2, ( 65, 5))
screen.blit(label3, (125, 5))
screen.blit(label4, (185, 5))
screen.blit(label5, (245, 5))
screen.blit(label6, ( 5, 75))
screen.blit(label7, ( 65, 75))
screen.blit(label8, (125, 75))
screen.blit(label9, (185, 75))
screen.blit(label10, (245, 75))
#refresh screen
pygame.display.update()
time.sleep(0.01)
Die Software ist eine Beta und diente für mich als ein einfacher Einstieg in Python/Pygame und GUI Programmierung. Ich rate davon ab, die GUI 24/7 zu verwenden, sonst brennt man evtl. das Muster der GUI in das Display ein (siehe http://de.wikipedia.org/wiki/Einbrennen_(Bildschirm)).
Weitere Informationen
RPi-Display:
https://github.com/watterott/RPi-Displayhttps://github.com/watterott/RPi-Display
Pygame:
FBTFT von Notro:
https://github.com/notro/fbtft/wiki

Ah, endlich mal einer, der auch wieder was zurückspeist ins Internetz! (hab mir vorgenommen, die CAN-Bus Geschichte aus dem Space sauber dokumentiert zu posten!)… man profitiert so viel von Foren und Blogs!
Wow! So schnell wurde noch kein meiner Einträge kommentiert. Danke! 🙂
Ja, die Informationen in Blogs und Foren, machten es möglich, das Projekt so schnell umzusetzen 🙂
Danke für die gute Anleitung :-))
🙂
Hi 5-Volt Junkie
Habe dein Script für das C-Berry Touch Display umgeschrieben und bin im Moment dabei, eine Python-Anbindung für die Touch Funktionen zu schreiben.
Sieht vielversprechend aus, habe aber noch Klippen zu umschiffen und weiß nicht ob das ganze taugt um es zu veröffentlichen. Aber wenn, wollte ich dich fragen, ob ich das Script dann in veränderter Form weitergeben kann?
Hi PiLlhipp,
vielen Dank für deine Rückmeldung. Ich höre/lese natürlich immer wieder gern, wenn jemand mit meiner Arbeit was anfangen kann.
Selbstverständlich darfst du den Code verändern und unter gleichen Bedingungen wieder veröffentlichen. Über kleine Erwähnung des Blogs, würde ich mich natürlich auch sehr freuen 🙂
Hi,
Sorry I don’t speak your language. Do you think a similar set-up could be use to activate a motor/pump instead of controlling a LED light ?
Thanks
That should be not difficult at all. You need a relay for every motor / pump you like to control. Those relays cannot be driven by the RasPi directly, instead you will need an relay driver which is an transistor.
See this example: https://www.pololu.com/product/2480
This Board can be controlled with your Pi, and will switch on your motor. It contains the relay as well as the driver transistor.
If you have havy loads like a swamp cooler or some fat compressor, you will like to have much bigger relays due to the havy inrush current when switching on those loads.
Thanks. I’m a newbie but thats what I had in mind.
Hallo 5Vollt Junkie
Erst einmal super Anleitung für dieses Projekt.
Hast du eventuell auch ein Beispiel für eine grafische Anzeige für Druckluftgeber oder Temperaturfühler.
Die anpassung der Spannung von den Fühlern ist nicht das Problem wird mit nem A/D Wandler eingespeisst. aber ich hätte gern eine Analoge Anzeige wie die echten Anzeigen meist Halbkreis, auf dem Bildschirm.
Mit freundlichem Gruss Arno
Hallo Arno,
ich habe leider kein Beispiel dafür. Ich weiß aber, dass es sowas Ähnliches mit einer Weboberfläche realisiert wurde. Frag mal am Besten die Jungs/Mädels im Raspberry-Forum.
Hallo zusammen,
ich versuche gerade das Script „gpiocontrol.py“ auszuführen. Bin genau nach obiger Anleitung vorgegangen.
Leider bekomme ich eine Fehlermeldung, die wie folgt ausschaut:
File „gpiocontrol.py“, line 60, in Screen= pygame.display.set_mode(size)
Pygame.error: Unable to open mouse
Kann mir hier jemand weiterhelfen?
Danke im Voraus
Pingback: Rückblick 2015 – 5Volt-Junkie
Ist es möglich das Script für HDMI Displays umzuschreiben und es dann mit der Maus zu bedienen, wenn ja wie?
Hi,
das Projekt ist schon etwas älter, aber wenn ich mich richtig erinnere, musste man nur die ganzen os.environs rausnehmen. Zeile 11-13.
Hallo junkie 😉
Erst einmal herzlichen Dank für die Einsteiger-Anleitung, die einem Anfänger im Bereich pygame und touch-display schon sehr hilft!
Deine Beschreibung ist zwar schon etwas älter, aber immer noch gut verständlich…
Zwei Fragen habe ich aber noch:
1) (Wie) kann man Dein Script auf das offizielle 7″ Raspi-Touchdisplay anpassen? Ich vermute, dass neben der Anpassung der Bildschirm-Größe ganz einfach die Zeilen 11-13 entfernt werden müssen? (Habe noch kein „offizielles“ Display, sonst hätte ich´s wohl schon heraus gefunden 😉
2) Hast Du einen Tipp, wie man innerhalb des Python-scripts beim Aufbau der Bildschirm-Seite zusätzlich zu den Schaltflächen ggf. auch eigene icons (gifs oder bmp oder so) anzeigen kann? -gibt es da ein empfehlenswertes Tutorial für pygame, dass ich noch nicht gefunden habe?
Vielen Dank für Deine Hilfe!
Heinz
Das Anpassen müsste nicht so schwer sein.
#screen size
width = 320
height = 240
Da musst du die passende Auflösung eintragen. Wenn du größere Schaltflächen haben willst, musst du diese auch dementsprechend anpassen
Das Zeichnen der Rechtecke beginnt ab dieser Zeile
#lets draw some buttons and indicatorsDie Areas für den Touchscreen musst du dann auch anpacken.
Wenn du Grafiken darstellen möchtest, schau dir mal mein Radio Projekt an und lies dir den Code durch. Da kann man was abgucken https://5volt-junkie.net/raspberry-pi-internetradio/
Das offizielle Display habe ich auch noch rumliegen, aber leider nur wenig damit rumgespielt.
Habe mich damals auch nur durch die Doku zum Wunschergebnis gearbeitet.
Ofizielle Pygame und Python Dokus lesen, Foren lesen, evtl. nachfragen und YouTube Video. Das waren so meine Mitteln 😉
https://www.pygame.org/docs/
https://www.python.org/doc/
Wenn du dir eh das große Display holen willst, dann einfach kaufen und anfangen zu spielen. Der Rest ergibt sich schon 😉
pygame gui, python display image etc. sind so die ersten Suchbegriffe, mit denen ich so ziemlich alle Suchergebnisse lila geklickt habe 🙂