MFRC522 Türsteuerung mit MCP23017 Portexpander

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Schokolokko!!!
User
Beiträge: 4
Registriert: Montag 6. April 2020, 21:39

Hallo liebe Leute bin am verzweifeln und komme einfach nicht mehr weiter.
Daher bräuchte ich einmal das Schwarmwissen.

Zur funktion:
Die Tür soll entriegelt werden sobal ein RFID TAG erkannt oder die Innere Türentriegelungstaste betätigt wird.
Die Verriegelung erfolgt automatisch sobald über den in der Tür verbauten REED Kontakt die bestätigung kommt das die Tür geschlossen wurde.

DAS PROBLEM:

Sobald das Script gestartet wurde erkennt es nur einmal einen RFID TAG und danach ist schluss.
Dieser wird aber auch nur erkannt, wenn man nicht zuvor auf die innere Türentriegelungstaste drückt.

Komischerweise läuft das Script über die innere Türentriegelungstaste ohne Probleme, selbst wenn man bei der ersten Entriegelung einen RFID TAG benutzt hat.

Hab natürlich rumexperementiert und alles rausgenommen was mit dem MCP23017 Portexpander zu tun hat.
Dabei habe ich festgestellt das sobald ein Befehl an den Portexpander rausgeht funktioniert der MFRC Reader nicht mehr.

Hier nochmal das Script.
Hoffe das mir jemand weiterhelfen kann.

#!/usr/bin/env python
# -*- coding: utf8 -*-
import RPi.GPIO as GPIO
import MFRC522
import signal
import fhem
import logging
import time
import smbus

bus = smbus.SMBus(1)

DEVICE = 0x21
IODIRA = 0x00
IODIRB = 0x01
OLATB = 0x15
OLATA = 0x14
GPIOB = 0x13

#bus.write_byte_data(0x21,0x00,0x00)
bus.write_byte_data(0x21,0x01,0xf0)
bus.write_byte_data(0x21,0x0d,0xf0)

continue_reading = True

# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
global continue_reading
print "Ctrl+C captured, ending read."
continue_reading = False
GPIO.cleanup()

# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)

# Create an object of the class MFRC522
MIFAREReader = MFRC522.MFRC522()

while continue_reading:

# Scan for cards
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)

# Get the UID of the card
(status,uid) = MIFAREReader.MFRC522_Anticoll()

Taster = bus.read_byte_data(DEVICE,GPIOB)

if (uid[:4] == [xxx,xxx,xx,xx] or not(Taster & 0b10000000 == 0b10000000)) and not(Taster & 0b01000000 == 0b01000000) and not (Taster & 0b00100000 == 0b00100000):
print "START"

# Magnetfreigabe für Motorgetriebe
bus.write_byte_data(DEVICE,OLATB,1)
time.sleep(3)

# Motor dreht Schloss auf
bus.write_byte_data(DEVICE,OLATB,5)

print "Tür wird aufgeschlossen"

# Motor dreht solange bis Endschalter "auf" betätigt wird
auf = True

while auf == True:
Taster = bus.read_byte_data(DEVICE,GPIOB)
if (Taster & 0b00100000 == 0b00100000):
print "Tür ist aufgechlossen"
bus.write_byte_data(DEVICE,OLATB,0)

# Motorgetriebe lockerung
time.sleep(2)
bus.write_byte_data(DEVICE,OLATB,2)
time.sleep(0.1)
bus.write_byte_data(DEVICE,OLATB,0)
auf = False

# Motor dreht Schloss zu
offen = True

while offen == True:
Taster = bus.read_byte_data(DEVICE,GPIOB)
if not(Taster & 0b01000000 == 0b01000000) and not (Taster & 0b00010000 ==0b00010000):

bus.write_byte_data(DEVICE,OLATB,1)

time.sleep(1.5)

bus.write_byte_data(DEVICE,OLATB,2)
print"Tür wird abgeschlossen"
offen = False
# Motor dreht solange bis Endschalter "zu" betätigt wird
zu = True

while zu == True:
Taster = bus.read_byte_data(DEVICE,GPIOB)
if (Taster & 0b00010000 == 0b00010000):
print "Tür ist abgechlossen"
time.sleep(1.5)

bus.write_byte_data(DEVICE,OLATB,0)

# Motorgetriebe lockerung
time.sleep(2)
bus.write_byte_data(DEVICE,OLATB,4)
time.sleep(0.1)
bus.write_byte_data(DEVICE,OLATB,0)
zu = False

print "ENDE 2"
time.sleep(2)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Python2 ist veraltet, steige auf Python3 um

Irgendjemand kommt auf die bescheuerte Idee, einen Signal-Handler zu definieren, der nichts sinnvolles macht, und dann wird es kopiert und kopiert, von Leuten, die genauso wenig Ahnung haben, und man bekommt es nicht mehr los.

›not (a==b)‹ schreibt man einfacher als ›a != b‹ oder hier, oft als Spezialfall taster & d == 0.

Alle while-Schleifen sind while-True-Schleifen, das spart die Flags, bei denen man nicht explizit auf True prüfen bräuchte.

Das Programm kann einige Funktionen ertragen.

Code: Alles auswählen

#!/usr/bin/env python3
import RPi.GPIO as gpio
import MFRC522
import time
import smbus

DEVICE = 0x21
IODIRA = 0x00
IODIRB = 0x01
OLATB = 0x15
OLATA = 0x14
GPIOB = 0x13

def initialize():
    bus = smbus.SMBus(1)
    #bus.write_byte_data(0x21,0x00,0x00)
    bus.write_byte_data(0x21,0x01,0xf0)
    bus.write_byte_data(0x21,0x0d,0xf0)
    reader = MFRC522.MFRC522()
    return bus, reader


def tuer_auf(bus):
    print("Tür wird aufgeschlossen")

    # Motor dreht solange bis Endschalter "auf" betätigt wird
    while True:
        taster = bus.read_byte_data(DEVICE,GPIOB)
        if taster & 0b00100000 == 0:
            break
    print("Tür ist aufgechlossen")
    bus.write_byte_data(DEVICE,OLATB,0)

    # Motorgetriebe lockerung
    time.sleep(2)
    bus.write_byte_data(DEVICE,OLATB,2)
    time.sleep(0.1)
    bus.write_byte_data(DEVICE,OLATB,0)


def tuer_offen(bus):
    # Motor dreht Schloss zu
    while True:
        taster = bus.read_byte_data(DEVICE,GPIOB)
        if taster & 0b01010000 == 0:
            break
    bus.write_byte_data(DEVICE,OLATB,1)
    time.sleep(1.5)
    bus.write_byte_data(DEVICE,OLATB,2)
    print("Tür wird abgeschlossen")


def tuer_zu(bus):
    # Motor dreht solange bis Endschalter "zu" betätigt wird
    while True:
        taster = bus.read_byte_data(DEVICE,GPIOB)
        if taster & 0b00010000:
            break
    print("Tür ist abgechlossen")
    time.sleep(1.5)
    bus.write_byte_data(DEVICE,OLATB,0)
    # Motorgetriebe lockerung
    time.sleep(2)
    bus.write_byte_data(DEVICE,OLATB,4)
    time.sleep(0.1)
    bus.write_byte_data(DEVICE,OLATB,0)


def main():
    try:
        bus, reader = initialize()
        while True:
            # Scan for cards
            (status,TagType) = reader.MFRC522_Request(reader.PICC_REQIDL)
            # Get the UID of the card
            (status,uid) = reader.MFRC522_Anticoll()
            taster = bus.read_byte_data(DEVICE,GPIOB)
            if (uid[:4] == [xxx,xxx,xx,xx] or taster & 0b10000000 == 0) and taster & 0b01100000 == 0:
                print("START")

                # Magnetfreigabe für Motorgetriebe
                bus.write_byte_data(DEVICE,OLATB,1)
                time.sleep(3)
                # Motor dreht Schloss auf
                bus.write_byte_data(DEVICE,OLATB,5)

                tuer_auf(bus)
                tuer_offen(bus)
                tuer_zu(bus)

            print("ENDE 2")
            time.sleep(2)
    except KeyboardInterrupt:
        pass
    finally:
        gpio.cleanup()

if __name__ == '__main__':
    main()
Da ist jetzt nichts an der Funktionalität anders. Der RFID-Code ist stark zusammengekürzt vom Beispielcode. Den Status sollte man auf jeden Fall prüfen. Dass man zwei Sekunden warten muß, bis etwas reagiert, ist vielleicht ein bißchen lang. Parallel auf verschiedene Eingänge zu reagieren, ist nicht gerade einfach.

Ein Raspi ist für solche Sachen auch nicht wirklich geeignet. Ein Arduino oder ähnliches ist deutlich besser.
Schokolokko!!!
User
Beiträge: 4
Registriert: Montag 6. April 2020, 21:39

Erstmal vielen Dank für die schnelle Hilfe.

das Problem ist aber immer noch das selbe.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Schrieb ich ja auch. Tut denn der RFID-Leser für sich alleine?
Schokolokko!!!
User
Beiträge: 4
Registriert: Montag 6. April 2020, 21:39

Code: Alles auswählen

def main():
    try:
        bus, reader = initialize()
        while True:
            # Scan for cards
            (status,TagType) = reader.MFRC522_Request(reader.PICC_REQIDL)
            # Get the UID of the card
            (status,uid) = reader.MFRC522_Anticoll()
            taster = bus.read_byte_data(DEVICE,GPIOB)
            if (uid[:4] == [xxx,xxx,xx,xx] or taster & 0b10000000 == 0) and taster & 0b01100000 == 0:
                print ("START")

                # Magnetfreigabe für Motorgetriebe
                #bus.write_byte_data(DEVICE,OLATB,0)
                #time.sleep(3)
                # Motor dreht Schloss auf
                #bus.write_byte_data(DEVICE,OLATB,4)

                #tuer_auf(bus)
                #tuer_offen(bus)
                #tuer_zu(bus)

                #bus.write_byte_data(DEVICE,OLATB,1)

            print ("ENDE 2")
            time.sleep(0.5)
    except KeyboardInterrupt:
        pass
    finally:
        gpio.cleanup()

if __name__ == '__main__':
    main()

Jep.
Aber nur solange bis ich den Inneren Türentriegelungstaster drücke.
Und wenn ich die ganze Portexpander Ansteuerung rausnehme.
Schokolokko!!!
User
Beiträge: 4
Registriert: Montag 6. April 2020, 21:39

Code: Alles auswählen

ENDE 2
START
ENDE 2
ENDE 2
START
ENDE 2
ENDE 2
START
ENDE 2
ENDE 2
START
ENDE 2
ENDE 2
START
ENDE 2
ENDE 2
ENDE 2
ENDE 2
ENDE 2
Antworten