Hallo zusammen,
ich habe das Problem, dass ich mehrere Taster welche an meinem GPIO angeschlossen sind auswerten möchte. Unter anderem auch ein ADC der über I2C angeschlossen ist.
Ich habe bisher viel mit C gearbeitet. Hier war es möglich einen Timer zu starten, der alle x ms ein Interrupt auslöst und dann die GPIOs abfragt.
Gibt es in Python auch die Möglichkeit? Habe bisher nichts passendes gefunden. Bin nur auf Threading gestoßen, da bin ich mir aber nicht sicher, ob es das ist was ich brauche.
Oder wie realisiere ich es am besten, dass alle x ms meine GPIO und mein ADC abgefragt werden?
Timer interrupt abfrage GPIO
meinst du ich soll extern einen Taktgeber an den Pi anschließen und diesen pin dann mittels Interrupt abfragen?
Ich war bisher am überlegen, einen Thread zu erstellen, in dem eine Whileschleife ist und die GPIOs überwacht und dann die entsprechenden Funktionen aus dem Hauptprogramm ausführt.
edit: ich habe keine gui
Ich war bisher am überlegen, einen Thread zu erstellen, in dem eine Whileschleife ist und die GPIOs überwacht und dann die entsprechenden Funktionen aus dem Hauptprogramm ausführt.
edit: ich habe keine gui
Das weiß ich auch noch nicht so genau. Es sollen halt Taster und ein ADC abgefragt werden. Ich denke alle 10ms ist ein guter Wert, um keinen Tastendruck zu verschlafen?
Genau das ist ja auch geplant. Ich hätte quasi ein Thread, der mir alle 10ms meine GPIOs und meinen ADC abfragt.
Ich versteh momentan leider nur nicht wie ich dann die gewonnenen Informationen weiterverarbeiten kann. Also rufe ich aus meinem Thread dann einfach eine Funktion auf, oder macht man das so, dass man aus dem Hauptthread die Werte aus dem Thread abfragt?
10ms ist ziemlich sportlich und viel zu viel. Es gibt fuer GPIOs "Interrupts", durch die du von Tastendruecken in Kenntnis gesetzt wirst. Die sollten diese Tatsache per queue.Queue an den Main-Thread kommunizieren, und der wertet das dann gesammelt aus.
wenn der gesamte Code nicht sehr komplex ist, würde ich das so realisieren:
Gruss Peter
Code: Alles auswählen
import time
def bastis_code():
while True:
nano_sek = time.time_ns()
milli_sek = int(nano_sek / 1000000)
if milli_sek % 2000 == 1:
print(" 2 Sekunden", milli_sek)
taster_auslesen()
else:
bastis_weiterer_code()
def taster_auslesen():
pass
def bastis_weiterer_code():
pass
if __name__ == "__main__":
bastis_code()
Dazu gibt es Mittel und Wege, wie zB bouncetime Argumente eben fuer dieses Verhalten. Oder sich das selbst zu programmieren, indem man Ereignisse eine gewisse Weile lang ignoriert. Das ist alles zielfuehrender, als schlussendlich zu pollen.
nichts destotrotz brauche ich das periodische Abfragen für meinen ADC.
Und da ist eben die Frage, wie man das richtig macht. Also die Werteübergabe vom Thread in den Hauptthread? Dazu finde ich nicht wirklich was. Nur leute die das mit globalen Variablen machen...
Und da ist eben die Frage, wie man das richtig macht. Also die Werteübergabe vom Thread in den Hauptthread? Dazu finde ich nicht wirklich was. Nur leute die das mit globalen Variablen machen...
Zuletzt geändert von basti2s am Freitag 11. Dezember 2020, 14:35, insgesamt 1-mal geändert.
Nachtrag: ich habe schon queue.Queue erwaehnt, und damit macht man die Uebergabe zwischen Threads. Und mit functools.partial auch ohne globale Variablen.
Code: Alles auswählen
import time
import queue
import threading
def background_loop(q):
while True:
time.sleep(.1)
q.put("pillepalle")
def main():
q = queue.Queue()
t = threading.Thread(target=background_loop, args=(q, ))
t.daemon = False
t.start()
while True:
print(q.get())
if __name__ == '__main__':
main()
Okay, ich komme leider noch nicht ganz mit den queues zurecht.
Ich würde dann quasi in dem background_loop die zustände meines GPIOs oder meines ADCs schreiben. Und dann kann ich den Zustand im Mainthread mittels if abfragen bzw. weiter verwenden?
Wieso nehme ich nicht einfach eine Liste? Ich möchte ja nur die zustände meines background_loop auslesen. Es soll ja kein anderer thread die Werte verändern. Also sollte das doch trotz liste Multithreading sicher sein?
Ich würde dann quasi in dem background_loop die zustände meines GPIOs oder meines ADCs schreiben. Und dann kann ich den Zustand im Mainthread mittels if abfragen bzw. weiter verwenden?
Wieso nehme ich nicht einfach eine Liste? Ich möchte ja nur die zustände meines background_loop auslesen. Es soll ja kein anderer thread die Werte verändern. Also sollte das doch trotz liste Multithreading sicher sein?
Warum willst du denn eine Liste? Die queue kenn put und get, und kuemmert sich dann selbst um's aufraeumen. Ausserdem kann das get entweder blockieren, oder definiert warten, bevor es weiter macht, falls nichts drin ist. Das willst du also muehselig alles selbst zusammenfrickeln?
Und was heisst dieses "komme nicht klar"? Du redest viel darueber, was so alles geht und nicht geht, aber zeigst keinen Code und keine Fehlermeldungen. Damit kann man halt auch nix anfangen.
Und was heisst dieses "komme nicht klar"? Du redest viel darueber, was so alles geht und nicht geht, aber zeigst keinen Code und keine Fehlermeldungen. Damit kann man halt auch nix anfangen.
mir geht es gerade vielmehr um das prinzipielle verständnis.
Angenommen ich möchte zwei ADC Kanäle und zwei GPIO Eingänge in dem Thread überwachen lassen. Dann hätte ich das so gemacht:
In dem Backgroundloop würde ich dann noch für jeden ADC Kanal eine queue erstellen. Den zusätzlichen GPIO pin kann ich ja mit auf die Queue q legen. Ist das totaler quatsch oder kann man das so machen?
Angenommen ich möchte zwei ADC Kanäle und zwei GPIO Eingänge in dem Thread überwachen lassen. Dann hätte ich das so gemacht:
Code: Alles auswählen
import time
import queue
import threading
import RPi.GPIO as GPIO
def background_loop(q):
GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
while True:
if GPIO.input(12):
q.put ("12on")
q = queue.Queue()
t = threading.Thread(target=background_loop, args= (q, ))
t.deamon = False
t.start()
while True:
if (str(q.get()) == "12on"):
print ("Pin 12 ist high")
alles klar. Jetzt stellt sich mir nurnoch die Frage, ob es schlauer wäre anstelle der while-Schleife in dem Thread periodisch aufzurufen (alle 50 ms oder so).
Ich hatte da mal was von einem Treadingtimer gelesen. Finde leider nicht mehr das entsprechende Codeschnipsel
Ich hatte da mal was von einem Treadingtimer gelesen. Finde leider nicht mehr das entsprechende Codeschnipsel
- __blackjack__
- User
- Beiträge: 13938
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Was meinst Du mit anstelle der while-Schleife? Da würde man doch einfach nur ein 50ms `sleep()` in die Schleife schreiben. Oder mit Berechnung der vergangenen Zeit seit dem letzten Schlafen etwas weniger als 50ms.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware