DoIT Posted March 27, 2020 at 08:08 AM Posted March 27, 2020 at 08:08 AM (edited) Hallo Zusammen, ich Versuche eine Python Methode zu schreiben welche über einen eigenen Thread DS18B20 Temperatursensoren ausließt und in eine globale Variable schreibt. Der Code funktioniert auch wenn ich ihn nicht in einen Thread auslagere Vielleicht kann mir jemand sagen was ich falsch mache? Hier der Code: import time import threading from tinkerforge.ip_connection import IPConnection from tinkerforge.bricklet_one_wire import BrickletOneWire HOST = "localhost" PORT = 4223 tempsensors = [ {"sensor": 0, "address": "123", "found": False, "temperature": 0.0, "identifier": 0, "deviceobject": None}, \ {"sensor": 1, "address": "123", "found": False, "temperature": 0.0, "identifier": 0, "deviceobject": None}, \ {"sensor": 2, "address": "3456", "found": False, "temperature": 0.0, "identifier": 0, "deviceobject": None}, \ ] # Hier sollen alle Sensoren die bekannt sind und verwendet werden aufgeführt sein. Achtung das muss händisch erledigt werden tempsensorsnew = [] # Hier sollen alle Sensoren Automatisch eingetragen werden welche noch nicht in die Liste aufgenommen wurden class Rugged: def __init__(self): self.onewire = [] # Liste erzeugen wo die Onewire geräte eingefügt werden self.__threadonewire = threading.Thread(target=self.__getonewire) self.ipcon = IPConnection() # Create IP Connection self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate) # Register Callback self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected) # Register Callback self.ipcon.connect(HOST, PORT) self.ipcon.enumerate() def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): global onewire if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE: if device_identifier == BrickletOneWire.DEVICE_IDENTIFIER: if not self.onewire: self.onewire = [BrickletOneWire(uid, self.ipcon)] time.sleep(0.5) else: for i in self.onewire: if i.get_identity() == uid: break # Wenn das Onewire Modul schon als Object in der Liste ist wird abgebrochen self.onewire.append(BrickletOneWire(uid, self.ipcon)) time.sleep(0.5) if not self.__threadonewire.is_alive(): self.__threadonewire.start() #self.__getonewire() # Wenn die funktion direkt anstatt des Threads ausgeführt wird funktioniert es def cb_connected(self, connected_reason): # Enumerate devices again. If we reconnected, the Bricks/Bricklets # may have been offline and the configuration may be lost. # In this case we don't care for the reason of the connection self.ipcon.enumerate() def __getonewire(self): global tempsensors global tempsensorsnew while True: print(tempsensors) print(tempsensorsnew) for i in self.onewire: i.reset_bus() # setzt den Bus zurück searched = i.search_bus() i.write(78) # WRITE SCRATCHPAD i.write(0) # ALARM H (unused) i.write(0) # ALARM L (unused) i.write(127) # CONFIGURATION: 12-bit mode i.write(68) # CONVERT T (start temperature conversion) time.sleep(1) # Wait for conversion to finish for x in searched[0]: i.write_command(x, 190) # READ SCRATCHPAD t_low = i.read().data t_high = i.read().data temperature = t_low | (t_high << 8) if temperature > 1 << 12: temperature -= 1 << 16 temperature = temperature / 16.0 crc = hex(x)[2:4] family = hex(x)[-2:] address = hex(x)[(2 + len(crc)):(len(hex(x)) - len(family))] #print("Family: " + hex(x)[-2:]) #print("CRC: " + hex(x)[2:4]) #print("Address: " + address.upper()) sensorfound = False for g in tempsensors: if g["address"].upper() == address.upper(): sensorfound = True g["found"] = True g["identifier"] = x g["deviceobject"] = i g["temperature"] = temperature break else: sensorfound = False if not sensorfound: for g in tempsensorsnew: if g["address"].upper() == address.upper(): sensorfound = True g["temperature"] = temperature break else: sensorfound = False if not sensorfound: tempsensorsnew.append({"sensornew": len(tempsensorsnew), "address": address, "temperature": temperature, "identifier": x, "deviceobject": i}) if __name__ == "__main__": Rugged() input('Press key to exit\n') Danke für eure Hilfe. Folgender Fehler kommt: Exception in thread Thread-1: Traceback (most recent call last): File "C:\Program Files (x86)\Python38-32\lib\threading.py", line 932, in _bootstrap_inner self.run() File "C:\Program Files (x86)\Python38-32\lib\threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "C:/...Control.py", line 74, in __getonewire searched = i.search_bus() File "C:\...Control\venv\lib\site-packages\tinkerforge\bricklet_one_wire.py", line 329, in search_bus ret = self.search_bus_low_level() File "C:\...Control\venv\lib\site-packages\tinkerforge\bricklet_one_wire.py", line 122, in search_bus_low_level return SearchBusLowLevel(*self.ipcon.send_request(self, BrickletOneWire.FUNCTION_SEARCH_BUS_LOW_LEVEL, (), '', 'H H 7Q B')) File "C:\...Control\venv\lib\site-packages\tinkerforge\ip_connection.py", line 1220, in send_request raise Error(Error.TIMEOUT, msg, suppress_context=True) tinkerforge.ip_connection.Error: Did not receive response for function 1 in time (-1) Edited March 27, 2020 at 09:13 AM by DoIT Quote
photron Posted March 27, 2020 at 09:27 AM Posted March 27, 2020 at 09:27 AM Ich habe mir das jetzt nicht alles im Detail angesehen, aber zumindest das hier tut nicht das was du denkst: for i in self.onewire: if i.get_identity() == uid: break # Wenn das Onewire Modul schon als Object in der Liste ist wird abgebrochen self.onewire.append(BrickletOneWire(uid, self.ipcon)) Die get_identity() Funktion gibt ein namedtuple zurück. Das mit uid zu vergleichen ist immer False. Du musst uid mit dem uid Feld des namedtuple vergleichen. Dann ist das break da nicht das richtige. Das bricht die for Schleife ab, aber der append() Aufruf danach wird trotzdem ausgeführt. Da muss du ein return verwenden um den gesamten Aufruf von cb_enumerate zu beenden. Etwa so: for i in self.onewire: if i.get_identity().uid == uid: return # Wenn das Onewire Modul schon als Object in der Liste ist wird abgebrochen self.onewire.append(BrickletOneWire(uid, self.ipcon)) So wie du es aktuell hast fügst du das Bricklet zweimal in deine Liste ein. Das könnte schon das ganze Problem sein. Quote
DoIT Posted March 27, 2020 at 09:35 AM Author Posted March 27, 2020 at 09:35 AM Vielen vielen danke. Das war das Problem. Da habe ich jetzt lange gesucht und immer an der falschen Stelle gesucht! Problem erledigt! Danke!😃 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.