Step 7 Modbus RTU - Comm_LOAD Fehler 81AA - falsche Betriebsart

SNCS_MarkusKarl

Level-1
Beiträge
4
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe eine Siemens S7-1215C DC/DC/DC (6ES7215-1AG40-0XB0) Firmware 20.0.0.2 und verwende hier ein Kommunikationsboard CB 1241 RS485 (6ES7241-1CH30-1XB0). Ich möchte eine Modbus Kommunikation für den Electromen EM-282D DC-Motor Controller with Modbus RS485 herstellen. In den Einstellungen des DC-Motor Controllers habe ich den RS485 Port auf den Standardeinstellungen belassen: 9600bps 8N1. Es werden zwei DC-Motor Controller verwendet. Die erste Slave Adresse ist 1 und die zweite 2.

Der DC-Motor-Controller hat 3 Pins für die RS485 Schnittstelle:
17 = GND
18 = A
19 = B

Ich habe den Pin 17 mit dem Eingang "M" des CB1241 verbunden. Den Pin 18 mit dem Eingang T/RA und den Pin 19 mit dem T/RB Eingang. Außerdem habe ich den T/RA Eingang auf den TA und den T/RB auf den TB Eingang gebrückt. Dazu ein habe ich eine geschirmte 3x0,34 Datenleitung verwendet. Außerdem sind die Pins 17, 18 und 19 zwischen den beiden DC-Motor Controller durchgebrückt.

Das ist mein SCL-Programm:

IF #inEnableComm THEN

CASE #State OF

//---------------------------------------------------
// INIT Kommunikation
//---------------------------------------------------
0:

#MIDB_Modbus_Comm_Load(REQ:= "FirstScan",
"PORT":="Local~CB_1241_(RS485)",
BAUD:=9600,
RESP_TO:=1000,
DONE=>#CommDone,
ERROR=>#CommError,
STATUS=>#CommStatus,
MB_DB:=#MIDB_Modbus_Master.MB_DB);
IF #CommError THEN
"DB61_Modbus_RTU".CommError := #CommStatus;
END_IF;

IF #CommDone THEN
#State := 10;
END_IF;


//---------------------------------------------------
// Controller 1 Status lesen
//---------------------------------------------------
10:

IF NOT #MIDB_Modbus_Master.BUSY THEN

#MIDB_Modbus_Master(
REQ := "Clock_10Hz" AND #CommDone,
MODE := 0, // READ
MB_ADDR := 1,
DATA_ADDR := 41101,
DATA_LEN := 10,
DATA_PTR := P#DB61.DBX0.0 WORD 10,
DONE => #ModbusDone,
ERROR => #ModbusError,
STATUS => #ModbusStatus);

#State := 11;
END_IF;


11:

IF #ModbusDone THEN
#ModbusDone := FALSE;
#State := 20;

ELSIF #ModbusError THEN
#State := 10;
END_IF;


//---------------------------------------------------
// Controller 2 Status lesen
//---------------------------------------------------
20:

IF NOT #MIDB_Modbus_Master.BUSY THEN

#MIDB_Modbus_Master(
REQ := "Clock_10Hz" AND #CommDone,
MODE := 0,
MB_ADDR := 2,
DATA_ADDR := 41101,
DATA_LEN := 10,
DATA_PTR := P#DB61.DBX20.0 WORD 10,
DONE => #ModbusDone,
ERROR => #ModbusError);

#State := 21;
END_IF;


21:

IF #ModbusDone THEN
#ModbusDone := FALSE;
#State := 30;

ELSIF #ModbusError THEN
#State := 20;
END_IF;


//---------------------------------------------------
// Controller 1 Parameter lesen
//---------------------------------------------------
30:

IF NOT #MIDB_Modbus_Master.BUSY THEN

#MIDB_Modbus_Master(
REQ := "Clock_10Hz" AND #CommDone,
MODE := 0,
MB_ADDR := 1,
DATA_ADDR := 40101,
DATA_LEN := 24,
DATA_PTR := P#DB61.DBX40.0 WORD 24,
DONE => #ModbusDone,
ERROR => #ModbusError);

#State := 31;
END_IF;


31:

IF #ModbusDone THEN
#ModbusDone := FALSE;
#State := 40;

ELSIF #ModbusError THEN
#State := 30;
END_IF;


//---------------------------------------------------
// Controller 2 Parameter lesen
//---------------------------------------------------
40:

IF NOT #MIDB_Modbus_Master.BUSY THEN

#MIDB_Modbus_Master(
REQ := "Clock_10Hz" AND #CommDone,
MODE := 0,
MB_ADDR := 2,
DATA_ADDR := 40101,
DATA_LEN := 24,
DATA_PTR := P#DB61.DBX88.0 WORD 24,
DONE => #ModbusDone,
ERROR => #ModbusError);

#State := 41;
END_IF;


41:

IF #ModbusDone THEN
#ModbusDone := FALSE;
#State := 50;

ELSIF #ModbusError THEN
#State := 40;
END_IF;


//---------------------------------------------------
// EVENTS
//---------------------------------------------------
50:

IF #inWriteCtrl1Req THEN
#State := 100;

ELSIF #inWriteCtrl2Req THEN
#State := 200;

ELSE
#State := 10;
END_IF;


//---------------------------------------------------
// Controller 1 Parameter schreiben
//---------------------------------------------------
100:

IF NOT #MIDB_Modbus_Master.BUSY THEN

#MIDB_Modbus_Master(
REQ := "Clock_10Hz" AND #CommDone,
MODE := 1,
MB_ADDR := 1,
DATA_ADDR := 40101,
DATA_LEN := 24,
DATA_PTR := P#DB61.DBX40.0 WORD 24,
DONE => #ModbusDone,
ERROR => #ModbusError);

#State := 101;
END_IF;


101:

IF #ModbusDone THEN
#ModbusDone := FALSE;
#State := 30;

ELSIF #ModbusError THEN
#State := 900;
END_IF;


//---------------------------------------------------
// Controller 2 Parameter schreiben
//---------------------------------------------------
200:

IF NOT #MIDB_Modbus_Master.BUSY THEN

#MIDB_Modbus_Master(
REQ := "Clock_10Hz" AND #CommDone,
MODE := 1,
MB_ADDR := 2,
DATA_ADDR := 40101,
DATA_LEN := 24,
DATA_PTR := P#DB61.DBX88.0 WORD 24,
DONE => #ModbusDone,
ERROR => #ModbusError);

#State := 201;
END_IF;


201:

IF #ModbusDone THEN
#ModbusDone := FALSE;
#State := 10;

ELSIF #ModbusError THEN
#State := 900;
END_IF;


//---------------------------------------------------
// ERROR
//---------------------------------------------------
900:

#State := 10;

END_CASE;

ELSE
#State := 0;
END_IF;

Port-Konfiguration:
1773591346984.png

Port:
1773591383269.png

Ich bekomme nun einen Fehler bei der Initialisierung des Modbus_Comm_Load Bausteins. Der Fehlercode ist 16#81AA -> falsche Betriebsart ausgewählt.

Woran kann das liegen?

Vielen Dank im Voraus.

Freundliche Grüße
Markus
 
Du must warscheinlich auf Mode 4

Und die Registeradressen Hexadezimal vorgeben

Betriebsart

Zulässige Betriebsarten sind:

0 = Vollduplex (RS232)

1 = Vollduplex (RS422) Vierdraht-Betrieb (Punkt-zu-Punkt)

2 = Vollduplex (RS422) Vierdraht-Betrieb (Mehrpunkt Master, CM PtP (ET 200SP))

3 = Vollduplex (RS422) Vierdraht-Betrieb (Mehrpunkt Slave, CM PtP (ET 200SP))

4 = Halbduplex (RS485) Zweidraht-Betrieb 1)
 
So meine ich.
Ist Quick and dirty aus eine 1500er

Code:
REGION Initialisieren Modbus Anbindung mit Modbus Comm LOAD
    
    #Modbus_Comm_Load_Instance.MODE := 4;
    #"Initialisieren Modbus Load"(IN:="FirstScan",
                                         PT:=t#5s);
          
           IF #"Initialisieren Modbus Load".Q THEN
               #Modbus_Comm_Load_Instance(REQ := true,
                                          "PORT" := "Local~Modbus_RTU_Slave",
                                          BAUD := 9600,
                                          PARITY := 0,
                                          RESP_TO := 2000,
                                          STATUS => #Status_Com_Load,
                                          MB_DB := #Modbus_Slave_Instance.MB_DB);
           END_IF;
END_REGION

Mein Programmcode für Slave

Code:
REGION Kommunizieren mit Modbus Slave
 
     #Modbus_Slave_Instance.HR_Start_Offset := 16#12C;    // Startoffset Modbusregister auf Register 40300 (HEX vorgabe)
  
     #Modbus_Slave_Instance(MB_ADDR := 49,
                            STATUS => #Status_Slave,
                            MB_HOLD_REG := "Modbus_ABB_Symphony");
 END_REGION


Nackische code für Master

Code:
 "Modbus_Master_DB"(REQ:=_bool_in_,
                    MB_ADDR:=_uint_in_,
                    MODE:=_usint_in_,
                    DATA_ADDR:=_udint_in_,
                    DATA_LEN:=_uint_in_,
                    DONE=>_bool_out_,
                    BUSY=>_bool_out_,
                    ERROR=>_bool_out_,
                    STATUS=>_word_out_,
                    DATA_PTR:=_variant_inout_);
 
Danke das hat funktioniert der Commload Baustein ist jetzt initialisiert, hat den Status 16#0000 und CommDone ist True. Allerdings kommuniziert mein Modbus Master jetzt nicht... Er hat Status 16#7001 und Busy ist dauerhaft True...

Woran kann das liegen?

Modbus Master:
1773661378062.png

1773661505350.png

SCL Baustein
1773661589167.png
1773661552546.png

Commload Baustein:
1773661627144.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Den Modbus Master bedingt aufzurufen ist nicht einfach, der braucht wahrscheinlich eine Flanke an seinem REQ Eingang. Die bekommt er so nicht mit. Da müsstest du im Schritt 0 wenn der Done kommt, einmalig den Master mit False auf dem REQ aufrufen, damit er in Schritt 10 die Flanke sehen kann.
 
Zurück
Oben