Bildwechsel mit GPIO-Vibrationssensor

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
bastler171819
User
Beiträge: 3
Registriert: Sonntag 21. Mai 2017, 22:02

Hallo!
Also ich bin ein blutiger Anfänger in Python und hoffe hier kann mir jemand helfen ohne dass ich gleich die ganze Programmiersprache lernen muss. Eigentlich hab ich mir ja den Raspberry Pi als Retrokonsole zugelegt und das hat ja auch super funktioniert und setzt nicht wirklich Programmierkenntnisse voraus. Habe auch schon vor 13 Jahren in der Schule ein wenig programmiert und im Laufe der Zeit immer wieder diverse Sprachen versucht zu lernen, allerdings ist bei mir die fehlende Freizeit das Problem. Grundverständnis für den Code ist noch ein klein wenig vorhanden.

Ich hätte gerne einen Code für folgendes Programm:

Raspberry Pi 3 Model B mit Vibrationssensor "Seeedstudio Grove - Piezo Vibration Sensor" an die GPIO'S angeschlossen. (Alle sind frei)

Ich schliesse einen Bildschirm per HDMI an.
Wenn sich der Pi hochfährt soll sich das Programm automatisch starten. (Da gibt es wie ich schon erfahren habe einen Ordner im Raspian, wo ich die *.py Datei reinschiebe)
Ich habe 2 Bilder in der Auflösung 1920x1080, welche für eine Vollbildanzeige des Bildschirmes gerichtet sind..
Reagiert der Vibrationssensor nicht, soll eines der Bilder als Screensaver (.gif-Datei) agieren.
Wird eine Reaktion vom Vibrationssensor festgestellt, soll das 2. Bild für 3 Minuten angezeigt werden.
Danach soll wieder das erste Bild als Screensaver agieren.

Habe mich schon ein wenig damit auseinandergesetzt und komme nicht wirklich auf einen grünen Zweig.
Das Programm ist ja auch nicht sonderlich kompliziert, vlt. kann mir hier wer helfen...? :K

mfg
BlackJack

@bastler171819: Weil hier noch keiner geantwortet hat: Die meisten hier wollen Leuten beim programmieren lernen helfen, aber eher nicht auf Zuruf für andere Programme schreiben. Das kann mal der Fall sein wenn das Problem für jemanden interessant genug ist, dass er sich damit sowies so mal auseinandersetzen möchte, aber Du schreibst ja selbst das das hier nicht so wirklich kompliziert ist. Das sollte schnell umgesetzt sein, für jemanden der programmieren kann. Wären da nicht die Hardware-Abhängigkeiten. Denn das ist zwar ein kleines Programm, man kann es ohne die entsprechende Hardware aber nicht testen, weiss also nicht ob es wirklich funktionieren wird.

Die Umsetzung hängt ausserdem davon ab mit welcher Bibliothek die Anzeige umgesetzt werden soll. Wie man beispielsweise die Grafik anzeigt, oder die drei Minuten abwartet, unterscheidet sich zwischen Gtk, Kivy, PyGame, Qt, Tk, …
bastler171819
User
Beiträge: 3
Registriert: Sonntag 21. Mai 2017, 22:02

Danke @BlackJack für die Antwort...
Ich habe fast mit so einer Antwort gerechnet. :wink: :mrgreen:

Ja genau das ist mein Problem mit der Hardwareabfrage...Habe das Programm soweit, dass ich ein Bild mit Tkinter Anzeige, und wenn man auf einen Button drückt, kommt das 2. Bild. Den Button würd ich eben jetzt gern gegen den Vibrationssensor ersetzen. Danach brauch ich noch dass das bild sich nach 3 Minuten wieder zurücksetzt. Wenn ich am Abend mal Zeit hab diese Woche, kann ich ja mal den Code, welchen ich bis jetzt zusammen habe hier posten.

Oder bin ich mit meiner Denkweise eh am Holzweg?!?

Hab mir gedacht eine If-Funktion, welche den betreffendne GPIO überwacht und wenn dieser True ist dann soll das Bild wechseln.
Dann mit time.sleep(ms) die 3 Minuten einstellen...Dann soll das Bild wieder verschwinden, was ja dann normalerweise von allein passiert wenn die Zeit abgelaufen ist.
BlackJack

@bastler171819: `time.sleep()` verträgt sich nicht mit Tk, weil die GUI solange wie man in einer Rückruffunktion schläft, nicht reagieren kann. Um zeitverzögert etwas zu machen, gibt es in Tk die `after()`-Methode auf jedem `Widget`. Die würde man auch für die regelmässige Abfrage der Hardware zu hilfe nehmen.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Tkinter da rein zu bringen halte ich fuer einen Fehler. Das hilft einem nicht beim abfragen der GPIOs, und das was es kann braucht man fuer die Darstellung von Bildern alles eigentlich nicht.

Stattdessen zB pygame, das eh eine eigene Ereignisschleife hat, und darin dann zyklisch den Taster abfragen sollte fuers erste einfacher sein.
BlackJack

@__deets__: Pygame hilft auch nicht bei der GPIO-Abfrage und ob man nun `Widget.after()` verwendet oder in Pygame Timer-Events erzeugt ist jetzt auch nicht so ein grosser Unterschied. Pygame hat im Gegensatz zu Tk eben keine vollständige Ereignisschleife — man muss die sich ja dort halb selbst schreiben.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

@BlackJack: ich denke die Schleife ist immer noch einfacher, als den Code auf after aufzuteilen. Und die Anforderung "Vollbild" ist mit pygame IHMO ebenfalls deutlich einfacher umzusetzen.
BlackJack

@__deets__: Okay, gemessen an der Zeilenanzahl ist es in Tk dreimal so schwer. :-)

Code: Alles auswählen

root = tk.Tk()
root.overrideredirect(True)
root.attributes('-fullscreen', True)

# vs.

screen = pygame.display.set_mode(size, pygame.FULLSCREEN)
bastler171819
User
Beiträge: 3
Registriert: Sonntag 21. Mai 2017, 22:02

Hallo wiedermal...

Habe die oben beschriebene Problematik jetzt neu angegangen, allerdings mache ich es jetzt mit einem PIR-Bewegungsmelder Sensor.

Der Code funktioniert aber leider immer noch nicht.

Also ich bekomm es inzwischen hin, dass sich ein Bild im Vollbild öffnet und angezeigt wird sobald ich das Programm starte.
Jetzt wollte ich den PIR-Sensor einbinden und das wechselnde Bild. Habe mit dem Code gespielt und viel Google-Recherche gemacht.
Ergebnis sieht man unten.
Im moment kann ich es nicht testen, aber ich glaube die Fehlermeldung war irgendwas wie no object tkinter oder so ähnlich.

Link zum PIR-Sensor:

https://jankarres.de/2015/02/raspberry- ... -arbeiten/


Kann mir vlt. wer helfen? :?:

Code: Alles auswählen

from tkinter import *

root = Tk()
root.overrideredirect(True)
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(), root.winfo_screenheight()))

#!/usr/bin/python
import time, sys
import RPi.GPIO as GPIO


img1 = PhotoImage (file="1.png")
img2 = PhotoImage (file="2.png")
img3 = PhotoImage (file="3.png")


lab1 = Label (root, image=img2)
lab2 = Label (root, image=img1)
lab3 = Label (root, image=img3)


# Pin of PIR OUT
PIR = 25

# Init PIR for input
def initPIR(PIR):
    lab1.pack()
    while GPIO.input(PIR) == 1:
        lab2.pack()
        return 0
 

# Bewegung erkannt
def motion():
    lab1.pack()
    time.sleep(180)
    return
 
# Bewegung ist fort
def motionGone():
    lab2.pack()
    time.sleep(3)
    lab3.pack()
    return



GPIO.setmode(GPIO.BCM)
GPIO.setup(PIR, GPIO.IN)
 
PirPreviousState = 0
PirCurrentState = initPIR(PIR)
 
try:
    while True:
        PirCurrentState = GPIO.input(PIR)
        
        if PirCurrentState == 1 and PirPreviousState == 0:
           # PIR geschaltet
           motion()
           PirPreviousState=1
        elif PirCurrentState == 0 and PirPreviousState == 1:
           # PIR nicht geschaltet
           motionGone()
           PirPreviousState=0
           
        time.sleep(0.1)

except KeyboardInterrupt:
	GPIO.cleanup()
	exit()
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die hier zu Beginn genannten Lösungsansätze gelten immer noch. While Schleife in Tkinter geht nicht. Das ist hier im Forum schon wirklich sehr, sehr oft durch dekliniert worden - zb gerade gestern: viewtopic.php?t=41305
Antworten