Bevor Programmablauf Lichtschranke (GPIO.input) prüfen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Alfi.1998
User
Beiträge: 13
Registriert: Montag 21. Dezember 2020, 18:03

Hey,

Ich würde gerne in folgenden Code

Code: Alles auswählen

#...Programm

from tkinter import *
import RPi.GPIO as GPIO
import time
import neopixel
import board



pixels = neopixel.NeoPixel(board.D18, 24)


def Mischung1():
    pixels.fill((255, 0, 0))
    GPIO.setup(17, GPIO.OUT)
    GPIO.output(17, GPIO.LOW)
    
    time.sleep(2)
    
    GPIO.output(17, GPIO.HIGH)
    
    GPIO.setup(22, GPIO.OUT)
    GPIO.output(22, GPIO.LOW)
    
    time.sleep(8)
    
    GPIO.output(22, GPIO.HIGH)
    pixels.fill((0, 255, 0))
würde ich gerne eine Lichtschranke einbauen. Durch das "def Mischung" werden die Pumpen von einen Automaten angesteuert. Jedoch sollte vor den Ablauf durch eine If Funktion geprüft werden ob die Lichtschranke unterbrochen ist und falls ja erst der Ablauf mit den pumpen beginnen. Ich habe bereits ein Programm für die Lichtschranke geschrieben und mit einem LED Kreis verbunden, dies funktioniert super. Sobald ich die Lichtschranke unterbreche werden die LED Grün. Ich habe aber Probleme diesen Code in den oberen "einzubauen" und alle versuche scheiterten.

Den Ablauf starte ich aus einem anderen Skript mit tkinter und dies Funktioniert auch, die Pumpen reagieren.

Wie ist den die beste herangehensweise?

Ich habe unter den "def" eine If Funktion gestartet aber dies funktionierte nicht.

Hier der Code den ich zur reinen überprüfung der Funktionalität der Schranke verwendet habe:

Code: Alles auswählen

import RPi.GPIO as GPIO
import os, time
import board
import neopixel
import time
from rpi_ws281x import *
import argparse

pixels = neopixel.NeoPixel(board.D18, 24)
 
RECEIVER_PIN = 16

 
def callback_func(channel):
    if GPIO.input(channel):
        time.sleep(0.25)
        pixels.fill((0, 255, 0))

    else:
        pixels.fill((255, 0, 0))

 
    
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
    
GPIO.setup(RECEIVER_PIN, GPIO.IN)
GPIO.add_event_detect(RECEIVER_PIN, GPIO.RISING, callback=callback_func,)
    
try:
    while True:
        time.sleep(0.2)
except:
    GPIO.remove_event_detect(RECEIVER_PIN)

Liebe Grüße
Alfred
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Warnungen sind dazu da, dass man sie behebt, in dem man cleanup aufruft, nicht, dass man sie ignoriert.
Dass Du keine *-Importe benutzen sollst, wurde Dir ja schon gesagt, aber hier wird nichts aus tkinter verwendet. Also kann das sowieso weg.

Aber auch hier gilt, wie bei GUIs, dass wenn man (externe) Ereignisse verarbeiten muß, dass es dann kompliziert wird.

So ein Programm sieht also grundsätzlich so aus (Pseudocode):

Code: Alles auswählen

def main():
    try:
        setup()
        while True:
            event = get_next_event()
            dispatch_event(event)
    finally:
        cleanup()

if __name__ == '__main__':
    main()
So ein Event kann dann entweder das Unterbrechen der Lichtschranke sein, oder ein Knopf, oder ein Timer-Event sein.
Benutzeravatar
Dennis89
User
Beiträge: 1555
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

deine Funktion 'Mischung1' soll ausgeführt werden, wenn die LED's grün werden?
Dann kannst du 'Mischung'1 doch aufrufen, nach dem du die Farbe der LED's gesetzt hast oder verstehe ich dich falsch?

Du solltest übrigends keine *-Importe verwenden. Dadurch holst du dir alle in 'tkinter' definierten Namen in dein Programm. Wenn du davon einen ausversehen für dein Programm verwenden willst, bekommst du unerwartete Fehler. Also zum Beispiel

Code: Alles auswählen

from tkinter import Label
'rpi_ws281x ' kenne ich nicht, aber auch da sollte man angeben, was man importieren will.
Fehler zu ignorieren ( GPIO.setwarnings(False) ) ist auch nicht so das gelbe vom Ei. Über die Motorkontrollleuchte klebst du auch kein Tape, sondern man verhindert das Fehler auftreten. In deinem Fall sollte das Programm mit einem GPIO.cleanup() beendet werden. (Wenn ich mich nicht täusche)


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Alfi.1998
User
Beiträge: 13
Registriert: Montag 21. Dezember 2020, 18:03

@Sirius3 Danke erstmal. :) Das Tkinter steht deswegen "noch" da, weil ich (sofern der Rest dann funktioniert) ein Fenster öffnen will. Auf den Fenster steht dann soetwas wie "Bitte Glas einstellen" oder "kein Glas erkannt". Ich habe dies bei den versuchen ausprobiert und daher kommt noch das Tkinter.

Den import mit den * habe ich bei diesem Skript bisher noch nicht korrigiert steht aber auf der Liste. :)

Wenn ich das richtig verstehe kann ich dann bei dem setup() meine Pumpensteuerung einfügen und nach dem while True: die Lichtschranke.
Ist es auch möglich, dass ich etwas anzeigen lasse (LED Farbe oder eben Fenster) wenn etwas nicht zutrift.

Geht das dann mit den typischen else: ?

Grüße
Alfred
Alfi.1998
User
Beiträge: 13
Registriert: Montag 21. Dezember 2020, 18:03

@Dennis89

Ja, dass mit den * ist alles in Arbeit und duch viele versuche sind noch importe dabei, die aktuell nicht benötigt werden. :)

Fast, aktuell werden vor dem Programmablauf die LED's auf Rot gesetzt und danach auf Grün. Das hat aber mit dem Wunsch der Lichtschranke nicht viel zutun.

Zum Ablauf:
(Raspberry Pi, Linux)

Man startet in der GUI durch einen Button dieses Skript (GUI ist noch im anderen Skript, weil ich eigenes importieren ausprobieren wollte). Das Programm in diesem Code soll vor den starten der Pumpen überprüfen, ob die eingebaute Laserlichtschranke durchbrochen ist. (Dies geschieht über die Änderung an einem GPIO)

wenn die Lichtschranke durchbrochen ist soll das Programm normal ablaufen und die pumpen ansteuern. (Alternativ licht auf grün ändern das bekomme ich aber hin). Falls die Lichtschranke NICHT durchbrochen ist soll angezeigt werden, dass kein Glas erkannt wird (Das geschieht über Tkinter und bekomme ich nach versuchen auch hin).

Ich habe es bisher aber nicht geschafft einen passenden funktionierenden Aufbau / Funktion für das vorherige überprüfen der Lichtschranke zu Finden. Meine versuche mit den klassischen callback / if Funktionen scheiterten.

Grüße
Alfred
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn noch eine GUI dazukommt, dann ist die Eventschleife der GUI zu benutzen, was ja schon in der anderen Frage von Dir erörtert wurde. Zum Helfen ist es immer wichtig alle Randbedingungen zu kennen.
Du mußt erst das Konzept der Event-Steuerung verstanden haben, bevor Du immer neue Funktionen hinzufügen zu wollen. Also erster Schritt wäre, die Lichtschranke in Deiner GUI anzuzeigen.
Antworten