DRV_mbus used for Modbus RTU slave of Modbus RTU 3rd party master

Hello,

I would like to “emulate” a Modbus RTU slave. We know the FC used by the master and the address indicated by the master.

The idea is to use a PLC with serial interface and write a code using the library “DRV_mbus” on the slave side.
I am a little it in doubt about how to write in the code the registry adress of the variable in my slave software.

Example:
3rd party Modbus RTU master use FC3 for read data from slave device with Module ID 1 on adress “0000h”.
On the B&R Modbus RTU slave, how can I associate the data to the adress “0000h”?
I read on AS help the “MBSOpen” description but I didn’t understand how configure “pCoilStat”, “pInputStat”, “pInputReg”, pHoldingReg".
I only found out that if I set such values to 0, based on the FC used by the master, I have to declare global array MB0[x], MB1[x], MB3[x] and MB4[x].

Thanks for the support!

Regards,

Giovanni

Hi @Giovanni_Boschello ,
From Internet, few notes for Modbus

As you already found in the Help to simulate Modbus variables on our System you have to define 4 different arrays with exactly the same name MB0,MB1,MB3,MB4 for those 4 tables.

Ciao
Valerio

Thanks Valerio for your answer but it doesn’t works at all.

The 3rd party Modbus RTU master uses RS485. I connect the RS485 interface to an external 3rd party converter which converts the signal to an RS232 and it goes to an

X20CP3684.
I thought that the converter could be the problem but I also tried to simulate the Modbus slave with a software installed on my PC and it works (so the converter is not the

problem).

Master use FC4 to read 2 input register at address 30005 on slave (so adress 30005 and 30006).

Master make requests to the slave every 200 ms more or less.
If I understand well if I leave “0” at MBSOpen_0.pInputReg I can define global MB3 array and MB3[0] should correspond to Input register at address 30001 and so on, right?

This is the code and variable declaration:

image

PROGRAM _INIT
(* init program *)
Slave.S1 := 0;

//MB4[0] := 0;
//MB4[1] := 0;
//MB4[2] := 0;

MB3[4]	:= -10000;
MB3[5]	:= -1;


Slave.MBSOpen_0.enable		:= TRUE;
Slave.MBSOpen_0.pDevice 	:= ADR('IF1');  (* Device description string *)
Slave.MBSOpen_0.pMode 		:= ADR('/PHY=RS232 /PA=N /DB=8 /SB=1 /BD=9600');  (* Mode description string *)
Slave.MBSOpen_0.pCoilStat	:= 0;  (* Coil Status (Modbus simulation variable) *)
Slave.MBSOpen_0.pInputStat	:= 0;  (* Input Status (Modbus simulation variable) *)
Slave.MBSOpen_0.pInputReg	:= 0;  (* Input Register (Modbus simulation variable) *)
Slave.MBSOpen_0.pHoldingReg	:= 0;  (* Holding Register (Modbus simulation variable) *)
Slave.MBSOpen_0.own_ID		:= 1;  (* Own node number *)
Slave.MBSOpen_0.timeout		:= 5000;  (* Timeout in milliseconds (the value must be a multiple of 10 and >250ms) *)
Slave.MBSOpen_0();

Slave.MBSlave_0.enable	:= TRUE;
Slave.MBSlave_0.ident	:= Slave.MBSOpen_0.ident;

END_PROGRAM

PROGRAM _CYCLIC
(* cyclic program *)


Slave.MBSlave_0();

(*When the command S1 is TRUE, then the driver environment is closed*)
IF (Slave.S1 = TRUE) THEN			
	Slave.MBSClose_0.enable	:= TRUE;
	Slave.MBSClose_0.ident	:= Slave.MBSOpen_0.ident;
	Slave.MBSClose_0();
END_IF

END_PROGRAM

Thanks for the help,

Regards,

Giovanni

I add the log of the communication with software that emulates Modbus RTU slave on my PC:

Register are 30005 and 30006 with such values:

Thanks to everyone that will answer!

>If I understand well if I leave “0” at MBSOpen_0.pInputReg I can define global MB3 array and MB3[0] should correspond to Input register at address 30001 and so on, right?

(MBSOpen()) Correct, as you found in the help:

let me see the messages:

If I understand correctly your simulator of Modbus slave (installed on your PC) has received this request:
RX:

and it has provided this answer:
TX:

At least so far we see the Modbus Master has sent message in correct format

Back to your original settings, do you have serial sniffer to connect to your pc? it will be nice to grab again rx/tx messages displayed for example with RealTerm

Plus:

Sometimes we have an offset on the registers so first on my test I read multi registers (20 for example) starting from address 0 just to find some values and understand in a second step the offset.
Ciao
Valerio

At least so far we see the Modbus Master has sent message in correct way

Yes, that is why in my opinion there is something wrong on slave side with PLC B&R (with slave on my PC there are no problems).
Some questions:

  1. Requests from the master are every 200 ms. MBSlave() answers only on master requests or answers cyclically (with the task class in which the task of MBSlave() is inserted)?
  2. In case MBSlave() answers only on master’s requests, if requests are every 200ms which is the right task class for the MBSlave() FB?

Thanks

if I’m you I will just focus on grabbing one read request ( Function Code=3: Read Holding Registers, so I will play with MB4[]) and the answer:
From Master side (in the example below I’m reading 24 registers in one request, and 0 offset), the code below is running every 50 ms (I don’t think the time is too important for the moment):

INIT:

CYCLIC:

Clear all messages on RealTerm + send a single request (fMCmd = 1 by Watch Window) + check messages you see on RealTerm.

===============================
On the Slave side, for MBSlave(), monitor these variables too:

Ciao
Valerio

Thanks Valerio but I have just one B&R PLC, so I have to decide to act as master or slave.
Now I found out the way to analyse Modbus traffic between master (3rd party device) and slave (B&R PLC).
The very strange thing is that when I write NEGATIVE values on the slave the master seems to be more “stable” (I write 2 values, -1000 and -1) :

On the other end when I write on the slave POSITIVE values the master read values that are completely out (I write -10000 and 0 and especially for the register 0 the master
read very wrong values and fluctuated a lot) :

I find out that when I modified parameter of MBSOpen() /RIT /TIT the situation change a little bit.
What’s the meaning of such parameters? Could be the road to success or not? Frankly speaking I am a little bit in doubt..

Thanks!

Hi Giovanni,

What’s the meaning of such parameters?

there was a discussion in the past regarding the parameters for serial communication:
Matching Serial Port Parameters on SG3 and SG4 PLCs - Ask Questions / B&R Software & Runtime - B&R Community

For what I see you have wrong checksum on the message so we can’t consider valid the data inside the frame.

>Could be the road to success or not? Frankly speaking I am a little bit in doubt..

Think positive, at the end the cause of the problem could be related to wrong or missing parameters on MBSOpen()

FRM_xopen()

======================================
Around 20 years ago I did something similar on what you are doing, in my case I used 2 X20 CPU and I installed the 2 examples you see in the help Examples in ANSI C.
In that moment I didn’t have a serial sniffer in the office, I configured in the mode RS232 and worked with no issue. We use DRV_mbus library in many projects so I don’t think there
is an issue on that.

Ciao
Valerio

Hi,

just as a side note without digging deeper into the whole topic from my side (I haven’t the chance right now to do so) :
please be aware, that the sign of an integer (negative or positive) is defined by the highest bit of the 16bit value.
So if negative values seem to be “more stable” then positive ones, I think that could be an indicator for a physical / timing problem between sender and receiver, because it would mean that the first bit is most often true, independent of the value. That the behavior changes when playing around with RIT / TIT also points into that direction.
So even if the converter is working with your PC, I don’t think we can rule it out with 100% as root cause.

If possible, I would try to use a RS485 interface on the PLC, and using the bus termination resistors specified for RS485, because even with very short cables I’ve seen misbehavior in past when termination of the bus wasn’t used as specified.

Best regards.

Thank you very much @alexander.hefner for your answer. I also think it is a “field” problem (terminating resistor over all that I can’t put in an RS23 line).

I don’t understand when you say this:

So even if the converter is working with your PC, I don’t think we can rule it out with 100% as root cause.

Why?

For sure I have to try with a native RS485 interface.

Thanks

Hi,

You’re right, I just forgot to explain why I mentioned that.

As you’re using a converter, both of the interfaces RS485 and RS232 could possibly cause a physical issue.
As it works on your PC, the converter seems to be okay for this setup. But still, there could be some incompatibilities / interferences between the converter and the PLC serial chipsets.
I’ve worked a lot with serial interfaces very long ago in past, and here and there I’ve seen strange behaviors in some combinations, even if it worked in others. Sometimes, the reason was a different timing and buffering behavior of the chipsets/drivers, sometimes it was based on voltage signals nearby the specified minimum or a floating ground between the 2 serial voltage signals, and also a long time ago it got even worse when the chipset manufacturers started using 3.3 TTL based chips instead of the 5V chips that were used before, and when USB based RS converters were replacing the chipset integrated RS interfaces on PC side.

All in all, I just wanted to mention that such rare, but real exisiting effects also could cause strange behavior.
Therefore, I always try to eliminate as much signal converting as possible … but as I said, this information is just based on my learnings a long time ago :wink:

Best regards!

Finally we had the possibility to substitute the RS232-RS485 and now everythink works well!
Thanks to all for support and ideas!

Regards,

Giovanni