Hall Sensor und erstes Programm

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
unique24
User
Beiträge: 69
Registriert: Donnerstag 5. Juli 2018, 14:51

Hallo,

ich schreibe mir ein Programm zur Steuerung eines Hühnerstalls und scheitere schon an den ersten Zeilen.
Ich habe 2 von diesen Hall Sensor:
https://joy-it.net/de/products/SEN-KY003HMS


Ich möchte detektieren, ob der obere, untere oder keine geschlossen ist.
Mein Code soweit:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Benoetigte Module werden importiert und eingerichtet
import RPi.GPIO as GPIO
import time
 
OPENED_PIN = 21
LOCKED_PIN = 12

# Diese AusgabeFunktion wird bei Signaldetektion ausgefuehrt
def DoorStatus(channel):   
    print GPIO.input(OPENED_PIN)
    print GPIO.input(LOCKED_PIN)
    if GPIO.input(OPENED_PIN) and GPIO.input(LOCKED_PIN):
        # Tür in der Mitte
        print("Tür steht in der Mitte (geöffnet aber nicht ganz oben)")
 
    if not GPIO.input(OPENED_PIN) and GPIO.input(LOCKED_PIN):
        # Tür ganz geöffnet
        print("Tür ganz geöffnet")
        
    if GPIO.input(OPENED_PIN) and not GPIO.input(LOCKED_PIN):
        # Tür geschlossen und verriegelt
        print("Tür geschlossen un verriegelt")
 
def main():

    # Initial
    DoorStatus('test')
    
    try:
        # Loop until users quits with CTRL-C
        while True :
            time.sleep(0.1)

    except KeyboardInterrupt:
        # Reset GPIO settings
        GPIO.cleanup()

# Tell GPIO library to use GPIO references
GPIO.setmode(GPIO.BCM)

# Set Switch GPIO as input
# Pull high by default
GPIO.setup(OPENED_PIN , GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(OPENED_PIN, GPIO.BOTH, callback=DoorStatus, bouncetime=200)

GPIO.setup(LOCKED_PIN , GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(LOCKED_PIN, GPIO.BOTH, callback=DoorStatus, bouncetime=200)

if __name__=="__main__":
   main()
Ich habe zum testen nur einen Hall Sensor angeschlossen!

Die Platine hat eine LED und diese ist immer korrekt. Aber wenn ich das Programm starte, erhalte ich nicht immer eine korrekte Ausgabe. Manchmal zeigt er offen an, obwohl geschlossen, usw.

Hab ich den Hall Sensor falsch eingebettet?

Danke!
unique24
User
Beiträge: 69
Registriert: Donnerstag 5. Juli 2018, 14:51

Frage zu Bounce:
Sollte das nicht die Zeit sein, wie lange ein Signal sauber und ununterbrochen anliegt?`
Wenn ich das auf 2000 stelle, erhalte ich dennoch immer gleich eine Ausgabe ... aber müsste er nicht 2sek warten?
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Python2 sollte man für neue Programme nicht mehr benutzen, da veraltet.
import-as ist dazu da, um Module umzubenennen, GPIO wird aber gar nicht umbenannt, sollte aber, da Module wie Variablen und Funktionen klein geschrieben werden. Nur Konstanten werden GROSS geschrieben. Warum steht die Initialisierung nicht in `main`?
Im Callback sollte so wenig Code stehen, wie möglich, am besten nur das Füllen einer Queue.
cleanup sollte immer aufgerufen werden, nicht nur bei Ctrl+C.

Code: Alles auswählen

#!/usr/bin/env python3
import RPi.GPIO as gpio
from queue import Queue
import time
 
OPENED_PIN = 21
LOCKED_PIN = 12

def door_status():   
    opened = gpio.input(OPENED_PIN)
    closed = gpio.input(LOCKED_PIN)
    if opened and closed:
        # Tür in der Mitte
        print("Tür steht in der Mitte (geöffnet aber nicht ganz oben)")
    elif not opend and closed:
        print("Tür ganz geöffnet")
    elif opend and not closed:
        print("Tür geschlossen un verriegelt")
 
def main():
    try:
        queue = Queue()
        gpio.setmode(gpio.BCM)
        gpio.setup(OPENED_PIN , gpio.IN, pull_up_down=gpio.PUD_UP)
        gpio.add_event_detect(OPENED_PIN, gpio.BOTH, callback=queue.put, bouncetime=200)
        gpio.setup(LOCKED_PIN , gpio.IN, pull_up_down=gpio.PUD_UP)
        gpio.add_event_detect(LOCKED_PIN, gpio.BOTH, callback=queue.put, bouncetime=200)

        while True:
            door_status()
            # wait for status change
            _ = queue.get()
    except KeyboardInterrupt:
        pass
    finally:
        gpio.cleanup()

if __name__ == "__main__":
   main()
Leide kann man über das Forum schlecht prüfen, ob die Sensoren korrekt funktionieren. Hast Du mal manuell mit einem Magneten getestet?

EDIT: nein, die bouncetime wartet nicht, sondern ignoriert weitere Statusänderungen für 2s.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Gewartet wird da nicht. Da wird 2 Sekunden lang ignoriert, was danach noch so passiert.
unique24
User
Beiträge: 69
Registriert: Donnerstag 5. Juli 2018, 14:51

Hallo,

ok, danke!

mit:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import RPi.GPIO as gpio
from queue import Queue
import time
 
OPENED_PIN = 21
LOCKED_PIN = 12

def door_status():   
    time.sleep(0.3)
    opened = gpio.input(OPENED_PIN)
    closed = gpio.input(LOCKED_PIN)
    if opened and closed:
        # Tür in der Mitte
        print("Tür steht in der Mitte (geöffnet aber nicht ganz oben)")
    elif not opened and closed:
        print("Tür ganz geöffnet")
    elif opened and not closed:
        print("Tür geschlossen und verriegelt")
 
def main():
    try:
        queue = Queue()
        gpio.setmode(gpio.BCM)
        gpio.setup(OPENED_PIN , gpio.IN, pull_up_down=gpio.PUD_UP)
        gpio.add_event_detect(OPENED_PIN, gpio.BOTH, callback=queue.put, bouncetime=200)
        gpio.setup(LOCKED_PIN , gpio.IN, pull_up_down=gpio.PUD_UP)
        gpio.add_event_detect(LOCKED_PIN, gpio.BOTH, callback=queue.put, bouncetime=200)

        while True:
            door_status()
            # wait for status change
            _ = queue.get()
    except KeyboardInterrupt:
        pass
    finally:
        gpio.cleanup()

if __name__ == "__main__":
   main()
passt es etwas besser ... die kleine Pause von 0.3sek nach dem Event hilft etwas.
Aber zuverlässig ist es dennoch noch nicht, oder?

Beispiel:
0ms Kontakt öffnet
(Function wird getriggert und ausgeführt. Eventuell ändert sich der Zustand bis die IF Abfrage erreicht wird)
10ms Kontakt schließt (wird durch bounce ignoriert)

Nun wird aber "Türl" offen ausgegeben ... wo der Kontakt aber 10ms danach geschlossen hat und geschlossen bleibt.

Ich finde, korrekt wäre es, wenn die Function erst getriggert wird, wenn ein Input mind. 50ms den Zustand behält ... so wird auch immer der letztendliche Zustand gemeldet!

Gibt es hierfür etwas fertiges?

Vielen Dank!
Antworten