derAngler Posted September 28, 2014 at 11:20 PM Posted September 28, 2014 at 11:20 PM 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? Quote
photron Posted September 29, 2014 at 08:26 AM Posted September 29, 2014 at 08:26 AM 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. Quote
derAngler Posted September 29, 2014 at 10:06 AM Author Posted September 29, 2014 at 10:06 AM 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. Quote
photron Posted September 29, 2014 at 01:20 PM Posted September 29, 2014 at 01:20 PM 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. Quote
CakeBoy Posted June 13, 2017 at 10:52 AM Posted June 13, 2017 at 10:52 AM Gibt es denn eine Möglichkeit die Callbacks so zu nutzen wie der TE es wollte? Ich habe das gleiche Problem und bin so langsam mit meinem Latein am Ende. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.