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 😉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
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 indicators
Die 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 🙂