Minimalmodbus read_register/read_float T3-PT10

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
cybermailer
User
Beiträge: 4
Registriert: Dienstag 21. März 2017, 11:14

Hallo,

ich versuche gerade Temperaturdaten zu lesen. PT100 Sensoren sind verknüft mit einem 10 Kanal Modbus Slave Device (Temco T3-PT10).

Dokumentation:
Address 100~101, Bytes 4
When set INT, 100 will show 0 and 101 show the temperature for channel 1, 250= 25.0C
when set flaot,100 and 101 show 25.0000C
-> Daher lese ich 101 als Adresse aus (103 für den nächsten Kanal usw...)

Minimalmodubs Einstellungen:

Code: Alles auswählen

 instrument = minimalmodbus.Instrument('/dev/ttyUSB0', modbusAddress)
    instrument.serial.baudrate = 9600
    instrument.serial.bytesize = 8
    instrument.serial.parity   = minimalmodbus.serial.PARITY_NONE
    instrument.serial.stopbits = 1
    instrument.serial.timeout  = 3.0
    instrument.debug = False
    instrument.mode = minimalmodbus.MODE_RTU
ich lese wie folgt:

Code: Alles auswählen

#read_float(registeraddress, functioncode=3, numberOfRegisters=2)
temperaturef = instrument.read_float(r, 3, 2)
*Anmerkung wenn ich ich hier mit r,3,1 lese kommen nur minus Werte komischerweise. Sobald ich hier auf 2 gehe scheinen Werte plausibler zu sein.

Code: Alles auswählen

#read_registers(registeraddress,numberOfRegisters,functioncode=3)
temperature = instrument.read_register(r, 1, 3)
Ich bekomme solche Werte retour:
Start Reading P3-PT10 2017-03-21 09:47:12
Channel 1 RegisterValue: 17530 Float: 1000.0
Channel 2 RegisterValue: 50043 Float: -251.279998779
Channel 3 RegisterValue: 16681 Float: 10.5799999237
Channel 4 RegisterValue: 49421 Float: -8.81999969482
Channel 5 RegisterValue: 16685 Float: 10.8524999619
Channel 6 RegisterValue: 16684 Float: 10.7725000381
Channel 7 RegisterValue: 49523 Float: -15.1975002289
Channel 8 RegisterValue: 16692 Float: 11.2600002289
Channel 9 RegisterValue: 16688 Float: 11.0524997711
Channel 10 RegisterValue: 16691 Float: 11.1875009537

Fragen:
Kann ich den Wert des Register umwandeln zu Float? Um zu vergleichen ob das gleich retour kommt?
Lese ich korrekt aus?
BlackJack

@cybermailer: Ob Du korrekt ausliest kann man schlecht sagen weil Du ja nicht zeigst wie Du ausliest. Was ist `r` jeweils?

Und sind die Argumente bei `read_float()` tatsächlich in anderer Reihenfolge als bei `read_registers()` anzugeben?

Das bei `read_float()` zwei Register gelesen werden müssen ist nicht komisch sondern dokumentiert. Man braucht halt vier Bytes für einen Gleitkommawert und nicht bloss zwei.

Vergleichen musst Du das zweite Register als ganze Zahl durch 10 mit dem Gleitkommawert den beide Register als `float` ausmachen. Zudem kannst Du testen ob das erste Register als ganze Zahl immer 0 ist, wie in der zitierten Dokumentation beschrieben.
cybermailer
User
Beiträge: 4
Registriert: Dienstag 21. März 2017, 11:14

r steht für die registeraddresse. In diesem Falle gleichzeitig für das Register jedes einzelnen Kanales. Ich gehe dabei mittels for Schleife alle Adressen durch und lese aus.
Das wären die dazugehörigen Adressen:
registeraddresses = [101,103,105,107,109,111,113,115,117,119]

Bild

bzgl. Reihenfolge lt. API http://minimalmodbus.readthedocs.io/en/ ... odbus.html
read_registers(registeraddress, numberOfRegisters, functioncode=3)
read_float(registeraddress, functioncode=3, numberOfRegisters=2)
Also sollte das mal passen würde ich meinen.

Was ich irritiert ist die Anzahl der Register. Da steht ja 100~101 z.B. das wären 2 Register. Mich interessiert aber ja nur das zweite Register 101 von dem her dachte ich das nur 1 Register gelesen werden soll...? denke ich da falsch?
BlackJack

@cybermailer: Ja Du denkst falsch und das steht doch ganz deutlich da das bei Float *beide Register zusammen* den Wert ausmachen. Bei INT brauchst Du nur jeweils ein Register und zwar das zweite von jedem Paar. Deine Adressenliste ist also für INT. Wenn Du die als Basis für Float nimmst, dann sind die Werte falsch, weil dann das zweite Register von einem Kanal und das erste vom nächsten zu einem Wert zusammengefasst werden.

Edit die Liste braucht man übrigens auch nicht, weil man die Adresse ja direkt aus der Kanalnummer berechnen kann.
cybermailer
User
Beiträge: 4
Registriert: Dienstag 21. März 2017, 11:14

Komischerweise bekomme ich wenn ich als Register Adressen folgende Werte nehme:

Code: Alles auswählen

registeraddresses = [100,102,104,106,108,110,112,114,116,118]
Mit den Funktionen:

Code: Alles auswählen

temperaturef = instrument.read_float(r, 3, 2)
temperature = instrument.read_register(r, 2, 3)
Sehr seltsame Werte retour...
Start Reading P3-PT10 Address 100 2017-03-21 17:34:37
Channel 1 RegisterValue: 0.0 Float: 3.71985862403e-310
Channel 2 RegisterValue: 0.0 Float: 1.0619171443e-309
Channel 3 RegisterValue: 209.72 Float: 4.39114369219e+86
Channel 4 RegisterValue: 157.29 Float: 9.81456721451e-13
Channel 5 RegisterValue: 367.0 Float: -1.11079224476e-234
Channel 6 RegisterValue: 445.64 Float: -1.01817943174e-86
Channel 7 RegisterValue: 396.49 Float: -3.32867604356e-179
Channel 8 RegisterValue: 157.29 Float: 9.80814734984e-13
Channel 9 RegisterValue: 262.14 Float: 1.89124338365e+185
Channel 10 RegisterValue: 262.14 Float: 1.89124805187e+185
BlackJack

@cybermailer: Für die INTs sind's ja schon mal die falschen Adressen und *zwei* Register wo es nur eines sein sollte. Und wie sind die ausgegeben Werte mit den *zwei* Nachkommastellen zustande gekommen?

Edit: Okay, ich weiss jetzt wo die zwei Nachkommastellen her kommen. Und habe auch meinen Fehler mit der Reihenfolge der Argumente verstanden. Es macht übrigens nicht so viel Sinn Defaultwerte noch mal explizit anzugeben.
cybermailer
User
Beiträge: 4
Registriert: Dienstag 21. März 2017, 11:14

Habe das Problem gelöst. Es ist schlichtweg so, dass komische Werte dadurch zu Stande gekommen sind dass anscheinend einige Sensoren defekt sind. Zwischendurch die Werte mit 10,... haben bereits gestimmt.

Dh. im Klartext die Ausgangslage von mir war schon richtig - dürfte die Doku ned ganz stimmen da ich jetzt z.B. die Addresse 101 auslese und dort einfach sage 2 Register WEIL minimalmodubs 16bit ausliest und in diesem Register aber 32bit Informationen drinnen sind daher passt das.

Code: Alles auswählen

registeraddresses = [101,103,105,107,109,111,113,115,117,119]
Habe die Gegenrechnung gemacht und die Register 100+101,102+103 usw. hergenommen und diese zu float umgewandelt kommen die gleichen Werte retour. Dementsprechend vertraue ich diesen nun.

Möchte nicht vorenthalten wie ich das gemacht habe:

Code: Alles auswählen

data = instrument.read_registers(registeraddress=100, numberOfRegisters=20, functioncode=3)
und dann mittels while Schleife die Werte ausgelesen / umgewandelt

Code: Alles auswählen

i = 0
while i < 10:
    w1 = data[i * 2]  # get word 1
    w2 = data[2 * i + 1]  # get word 2 (16 bit word)
    buf = struct.pack('HH', w1, w2)
    value = struct.unpack('f', buf)
     print i, value
     i += 1
Es ist davon auszugehen, dass die Doc entweder schlecht übersetzt ist oder aber ein Fehler sich in dieser befindet.

Danke für die Hilfe. Vielleicht hilft das Ganze ja jemanden weiter...
BlackJack

@cybermailer: Ich sehe nicht warum da ein Fehler in der Dokumentation sein soll. Es kann natürlich sein, aber was Du da machst kann auch einfach nur zufällig das richtige Ergebnis liefern weil bei den zwei Registern die Du da liest das zweite laut Dokumentation ja immer 0 sein muss und wenn dass das ”high word” ist, dann trägt das nichts zum Ergebnis bei. Das macht den Code an sich aber nicht richtig und da die Hardware ja anscheinend am Zugriffsmuster erkennt ob man einen ganzzahligen Wert oder eine Gleitkommazahl haben möchte, ist dieser eigenartige Registerzugriff über Kanalgrenzen hinweg nicht wirklich etwas was ich machen würde.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

cybermailer hat geschrieben:Habe das Problem gelöst. Es ist schlichtweg so, dass komische Werte dadurch zu Stande gekommen sind dass anscheinend einige Sensoren defekt sind. Zwischendurch die Werte mit 10,... haben bereits gestimmt.
Das überprüf bitte nochmal. Ein defekter Sensor ist schon selten, aber mehrere ist unwahrscheinlich (wenn sie denn nicht uralt oder und wirklich schlechter / rauher Umgebung eingesetzt wurden). Teste mal jeden Sensor an dem selben Eingang.

PS so vom überfliegen gefällt mir MinimalModbus nicht, das man die Function Codes zum Beispiel als Zahlen angibt und nicht mit Namen. Guck dir doch mal pyModbus an (https://github.com/bashwork/pymodbus

*edit*
Ich sehe gearde das Problem bei minimalmodbus. read_float arbeitet dort nur mit big-endian.
Antworten