Modbus-RTU - HILFE!

OB82

Level-1
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin allerseits!

Ein verzweifelter Hilfeschrei... :wink:

Ich möchte / soll eine Verbindung über Modbus-RTU herstellen und habe mich soweit auch schon eingearbeitet. Unsere Programmiersoftware ist das TIA Portal V12 SP1. So weit, so gut oder auch nicht. Die Bausteine MB_COMM_LOAD und MB_MASTER sind auch ins Projekt, in eine Funktion (FC) eingepflegt und wird bei einer bestimmten Bedingung aufgerufen. Dabei meldet der Baustein kurz BUSY == TRUE, DONE und ERROR bleiben aber FALSE und STATUS bleibt 0. Meine Frage hierbei ist, was ich bei DATA_ADDR für ein Register eintragen muss, welche Länge bei DATA_LEN und wie ich DATA_PTR konfigurieren muss, um etwas aus dem Slave auszulesen?

Aus der PDF werde ich auch nicht so ganz schlau, welche DATA_ADDR, DATA_LEN und DATA_PTR ich am MB_MASTER verwenden/eintragen muss...
http://www.orientalmotor.com/products/pdfs/opmanuals/HM-5114-2E.pdf

Folgende Eckdaten..

Master: SIMATIC S7-1200 (1212C) mit CM1241 RS-422/485
Slave: Orientalmotor BLVD20KM (Driver)

Ich hoffe mir kann jemand Hilfestellung leisten! :confused:
 
Meine Frage hierbei ist, was ich bei DATA_ADDR für ein Register eintragen muss, welche Länge bei DATA_LEN und wie ich DATA_PTR konfigurieren muss, um etwas aus dem Slave auszulesen?
Modbus überträgt 8 bzw. 16 Bit Größen (1 oder 2 Byte).
Jetzt hängt es vom Datentyp ab, wie viele Byte benötigt werden.
Coils kommen mit 1 Bit aus.
In 1 Byte passen also 8 Coils.
Und 1 Register hat 16 Bit, also 2 Byte.

Jetzt muss die Anzahl der Coils/Register berücksichtigt werden.
Bei 10 Coils in einem Zyklus würdest Du z.B. DATA_LEN=2 haben (8 coils im 1 byte, 2 coils im 2ten byte).
Bei 10 Register in einem Zyklus würdest Du DATA_LEN=20 haben.

Hier ist der Quellcode unserer Modbus Klasse.
Wenn Du das durchliest, verstehst Du das evtl. besser.
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlModbus.html

 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Aha! Okay, vielen Dank!

Aus der Beschreibung meiner Steuergeräte entnehme ich diese Tabelle:


Code:
------------------------------------
| Reg.-Addr   Bits |7|6|5|4|3|2|1|0|
------------------------------------
|  007C  |  Upper  |-|-|-|-|-|-|-|-|
|  007C  |  Lower  |-|-|-|-|-|-|-|-|
------------------------------------
|  007D  |  Upper  |0|0|0|0|0|0|0|0|
|  007D  |  Lower  |0|0|0|0|1|0|0|0|
------------------------------------

Mein benötigtes Register ist das 007D (125 Dez). In dem habe ich demnach 2x8Bit=2Byte. Nun möchte ich das Bit 3 aktivieren, also muss ich in das Byte eine 8 schreiben, richtig? Demnach erstelle ich so ein Array von Byte:
Code:
-----------
| [0] = 0 |
| [1] = 8 |
-----------

Somit ist meine "DATA_LEN: 2" und der DATA_PTR schaut auf mein Array von Byte, richtig?
 
Das sind die Modbus "Function Codes"
enum ModbusFunctionCodes {
ReadCoilStatus = 1, ReadInputStatus = 2, ReadHoldingRegisters = 3, ReadInputRegisters = 4,
ForceSingleCoil = 5, PresetSingleRegister = 6, ReadExceptionStatus = 7, FetchCommEventCtr = 11,
FetchCommEventLog = 12, ForceMultipleCoils = 15, PresetMultipleRegs = 16, ReportSlaveID = 17,
ReadGeneralReference = 20, WriteGeneralReference = 21, MaskWrite4XRegisters = 22, ReadWrite4XRegisters = 23,
ReadFifoQueue = 24
}

Wenn Du nur 1 Bit beeinflussen möchtest, musst Du
function=5 (ForceSingleCoil) verwenden.

Wenn Du dafür
function=6 (PresetSingleRegister) verwenden würdest, würden ja alle Bits beeinflusst.

Ich nehme an, dass Deine Doku auch eine Tabelle für einzelne Bits (Coils) enthält.

Wenn Du Dir das bei unserer Klasse ansiehst:
http://pvbrowser.org/pvbrowser/sf/m...Modbus.html#a60656255e0053bcaa84c39086b09cf6c
hätte man:
data[0] = (coil_adr / 256) & 0x0ff;

data[1] = coil_adr & 0x0ff;

data[2] = 0;

data[3] = 0;

if(value) data[2] = 0x0ff;

Du brauchst also die coil_adr aus einer Tabelle Deiner Doku.
und data[3] ist entweder 0x0 oder ox0ff.
 
Das Register 0x7D is ein command register, somit wird es seitens des orientak motors nur ausgewertet.
Ein vorheriges Rücklesen ist somit nicht notwendig.
Als Lösung würde ich folgendes vorschalgen:
beim StartUp deines Systems das Register einlesen (dient zur Synchonisation)
den Wert auf eine Variable speichern
die Variable entsprechend manipulieren, also das Bit setzen oder löschen, ohne dabei die anderen Bits zu beinflussen. Geht mit AND und OR
den Wert nach einer Manipulation an das Register senden
 
Zurück
Oben