Jump to content

rfid-Bricklet ... callback wird konsequent ausgelöst


derAngler

Recommended Posts

Nabend mal wieder,

 

ich programmiere wie immer in python und bin dabei mir eine Routine zu schreiben die bestimmte Aktionen auslöst.

Im Detail soll das so aussehen das ich eine Karte über das Bricklet ziehe und dann eine Aktion gestartet wird.

Die auszulösende Aktion ist auf der Karte selbst gepeichert.

 

Das Skript funktioniert auch so wie es soll

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

HOST = "192.168.127.84"
PORT = 4223
UID = "owX"
rfid_tag_befehl=""

from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_nfc_rfid import NFCRFID


def cb_state_changed(state, idle):
    global rfid_tag_befehl

    if state == nfc.STATE_REQUEST_TAG_ID_READY:
        ret = nfc.get_tag_id()
        nfc.request_page(5)
    elif state == nfc.STATE_REQUEST_PAGE_READY:
        data = nfc.get_page()
        befehl = (''.join(map(chr, data)))
        if befehl != rfid_tag_befehl:
            rfid_tag_befehl=befehl
            if "led_green" in rfid_tag_befehl:
                print('led_green')
            elif "led_blue" in rfid_tag_befehl:
                print('led_blue')
            elif "led_red" in rfid_tag_befehl:
                print('led_red')
            elif "led_on" in rfid_tag_befehl:
                print('led_on')
            elif "led_off" in rfid_tag_befehl:
                print('led_off')
            else:
                print('Daten ' + rfid_tag_befehl)
            nfc.request_tag_id(nfc.TAG_TYPE_TYPE2)
        else:
            nfc.request_tag_id(nfc.TAG_TYPE_TYPE2)
    else:
        nfc.request_tag_id(nfc.TAG_TYPE_TYPE2)


if __name__ == "__main__":
    ipcon = IPConnection()
    nfc = NFCRFID(UID, ipcon)
    ipcon.connect(HOST, PORT)
    nfc.register_callback(nfc.CALLBACK_STATE_CHANGED,cb_state_changed)
    nfc.request_tag_id(nfc.TAG_TYPE_TYPE2)
    input('Press key to exit\n')
    ipcon.disconnect()

 

Das Problem sehe ich nur darin das die Callback-Funktion konsequent ausgelöst wird.

Ich hatte mir mal den Spass gemacht und jede Möglichkeit für "state" ausgeben lassen und dann gesehen das im Terminal im Millisekunden-Takt Meldungen einliefen.

 

Deswegen frage ich mich ob ich irgendwo etwas falsch gemacht habe?

Link zu diesem Kommentar
Share on other sites

Das ist kein Problem, sondern so arbeitet dein Programm einfach!

 

Du fängst im __main__ Block mit nfc.request_tag_id(nfc.TAG_TYPE_TYPE2) an und löst damit den ersten Callback aus, mit State 2 (STATE_REQUEST_TAG_ID, ein Tag ID Anfrage ist im Gange). Darauf hin fragst du im else Zweig cb_state_changed erneut eine Tag ID an, was vom Bricklet ignoriert wird (denke ich, hab's nicht nachgesehen).

 

Der nächste Callback kommt dann mit State 130 (STATE_REQUEST_TAG_ID_READY, eine Tag ID wurde gefunden) oder State 194 (STATE_REQUEST_TAG_ID_ERROR, keine Tag ID wurde gefunden). Woraufhin du den Inhalt liest und am Ende wieder request_tag_id aufrufst.

 

Wenn kein Tag zu lesen ist, ist dein Programm in einer request_tag_id/Callback-STATE_REQUEST_TAG_ID_ERROR Schleife und wartet darauf, dass ein Tag auftaucht. Daher bekommst du ständig Callbacks, da dein Program ständig nach dem Vorhandensein eins Tags fragt.

Link zu diesem Kommentar
Share on other sites

Hmm, versuche das nachher nochmal zu verstehen.

 

Tatsache ist aber, das ich kein einziges "nfc.request_tag_id" weglassen kann.

 

Nehme ich nur eines raus (egal wo), dann funktioniert das Programm nicht mehr.

 

Wenn kein Tag zu lesen ist, ist dein Programm in einer request_tag_id/Callback-STATE_REQUEST_TAG_ID_ERROR Schleife und wartet darauf, dass ein Tag auftaucht. Daher bekommst du ständig Callbacks, da dein Program ständig nach dem Vorhandensein eins Tags fragt.

Ist doch logisch das das RFID-Bricklet die ganze Zeit auf das auftauchen eines neuen Tags wartet, wie sonst sollte es funktionieren.

 

Was ich störend finde ist, das wenn ich ein Tag auf das Bricklet lege, dieses ständig wieder erkannt wird.

Müsste das Bricklet nicht erkennen das das gleiche Tag aufliegt und dementsprechend keine Änderungen des Status haben?

 

Ich mache mir Gedanken das ich durch das ständige auslösen des Callback Timingprobleme bekomme.

Immerhin sollen in einem späteren Schritt noch die LED-Beleuchtung und Hardware-Interrupts für Tastendrücke hinzukommen.

Link zu diesem Kommentar
Share on other sites

Richtig, du kannst da keinen request_tag_id Aufruf weglassen. Du hast da kein Problem, dein Programm funktioniert richtig.

 

Das NFC/RFID Bricklet sendet dir von sich aus keinen StateChange Callback von sich aus, abgesehen vom Initialization nach Idle Übergang, alles andere danach ist eine Reaktion auf Funktionsaufrufe in deinem Programm.

 

Du rufst request_tag_id/request_page auf. Darauf hin führt das Bricklet intern die angeforderte Aufgabe aus. Da die NFC/RFID Funkkommunikation etwas Zeit dauert, kann das nicht in einem Getter Aufruf passieren, das würde das ganze System blockieren. Die Funktionen starten also eine Aufgabe, die dann im Hintergrund auf dem Bricklet durchgeführt wird. Der Zustand der Durchführung der Aufgabe wird dir per StateChange Callback mitgeteilt:

 

- State ist Idle

- Du rufst request_tag_id

- State ändert sich zu RequestTagID, StateChange Callback wird verschickt

- Tag ID wird per Funk abgefragt

- Entweder klappt die Abfrage oder nicht, der State ändert sich zu RequestTagIDReady oder RequestTagIDError und wir dir per Callback mitgeteilt

- Jetzt kannst du per get_tag_id die letzte gelesene und im Bricklet zwischengespeicherte TagID abfragen

 

Der selbe Ablauf passiert für request_page. StateChange Callback sind immer eine Folge eines Funktionsaufrufs.

 

Der State ist nicht da, um auszusagen ob da in Tag da liegt oder nicht oder ob er sich ändert, sondern der State sagt aus in welchem Zustand eine Aufgabe ist, die du angestoßen hast.

Link zu diesem Kommentar
Share on other sites

  • 2 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...