How to use ModbusSlaveRequestReceived

1,125 views
Skip to first unread message

jani.g...@gmail.com

unread,
Aug 28, 2008, 2:42:46 AM8/28/08
to NModbus

Hi,

I have problem to use ModbusSlaveRequestReceived event. Can you help
me with some sample code or working example.


Best regards and thanx in advance,

Jani

Scott Alexander

unread,
Aug 28, 2008, 9:29:58 AM8/28/08
to NModbus...@googlegroups.com
slave.ModbusSlaveRequestReceived += (obj, args) => { // do something };

obj is the slave
args is the IModbusMessage

Do you have a specific question?

jani.g...@gmail.com

unread,
Aug 29, 2008, 6:02:04 AM8/29/08
to NModbus
I do not understand what I have to input as args? I do not know what
is IModbusMessage in my example. I use PLC controller which is Modbus
master. PLC is writing single register to PC which is Modbus slave. I
created another Modbus master on PC which need to read value change
when it arrives from PLC.

Jani

On 28 avg., 15:29, "Scott Alexander" <sja...@gmail.com> wrote:
> slave.ModbusSlaveRequestReceived += (obj, args) => { // do something };
>
> obj is the slave
> args is the IModbusMessage
>
> Do you have a specific question?
>

Scott Alexander

unread,
Aug 29, 2008, 11:14:22 AM8/29/08
to NModbus...@googlegroups.com
The ModbusSlaveRequestReceived event is fired by the NModbus slave
whenever a request is received (whenever your PLC writes to the
NModbus slave). If you are subcribed to this event you can look at the
'args' argument for the public interface of the request that was
received. That interface exposes the contents of the message through a
variety of properties - FunctionCode, SlaveAddress,
ProtocolDataUnit,etc. In order to use this event for your scenario you
will require some parsing of the byte[] message content... (since the
public IModbusMessage interface is too generic)

I think you'd be better off using the DataStoreWrittenTo event.This
would not require another NModbusMaster or any parsing. Let me know if
you have any more questions.

Scott

jani.g...@gmail.com

unread,
Sep 1, 2008, 1:51:59 AM9/1/08
to NModbus
Hi Scott,

Thank you for your help. I do not have very much experience in C#
programming. Can you help me to include in my code basic example of
how to call DataStoreWrittenTo event. The PLC is writting on register
1 address of slave (PC). The plc object in my code is from PLC custom
class.


Thanx & Best regards,

Jani

The code is next:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

using Modbus;
using Modbus.Device;
using Modbus.Data;
using System.Net;
using System.Net.Sockets;

namespace TwidoNModbus
{

public partial class MainForm : Form
{
private PLC plc;

private TcpListener slaveTcpListener;
private ModbusSlave slave;
private byte unitId = 1;
private ushort address = 1;
private ushort numOfPoints = 1;

private TcpClient masterTcpClient;
private ModbusIpMaster master;


public MainForm()
{
InitializeComponent();

plc = new PLC();

int port = 502;
IPAddress address = new IPAddress(new byte[] { 10, 1, 15, 49 });

slaveTcpListener = new TcpListener(address, port);
slaveTcpListener.Start();

slave = ModbusTcpSlave.CreateTcp(unitId, slaveTcpListener);
slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
}


void Button1Click(object sender, EventArgs e)
{
plc.ConnectToPLC("10.1.15.180", 502);
}

void Button2Click(object sender, EventArgs e)
{
plc.SetTime(11, 11);
}

void Button3Click(object sender, EventArgs e)
{
slave.Listen();
}

void MainFormFormClosing(object sender, FormClosingEventArgs e)
{
plc.DisconnectFromPLC();
slaveTcpListener.Stop();
}

}
}



On 29 avg., 17:14, "Scott Alexander" <sja...@gmail.com> wrote:
> The ModbusSlaveRequestReceived event is fired by the NModbus slave
> whenever a request is received (whenever your PLC writes to the
> NModbus slave). If you are subcribed to this event you can look at the
> 'args' argument for the public interface of the request that was
> received. That interface exposes the contents of the message through a
> variety of properties - FunctionCode, SlaveAddress,
> ProtocolDataUnit,etc. In order to use this event for your scenario you
> will require some parsing of the byte[] message content... (since the
> public IModbusMessage interface is too generic)
>
> I think you'd be better off using the DataStoreWrittenTo event.This
> would not require another NModbusMaster or any parsing. Let me know if
> you have any more questions.
>
> Scott
>

Scott Alexander

unread,
Sep 1, 2008, 9:19:54 AM9/1/08
to NModbus...@googlegroups.com
first you need the event handler, something like the following

void dataStore_DataStoreWrittenTo(object sender, DataStoreEventArgs e)
{
if (e.Data.Option == DiscriminatedUnionOption.A)
{
Console.WriteLine(String.Format("Coil values {0} written starting at
address {1}",
String.Join(", ", e.Data.A.Select(d => d.ToString()).ToArray()),
e.StartAddress));
}
else
{
Console.WriteLine(String.Format("Holding register values {0} written
starting at address {1}",
String.Join(", ", e.Data.A.Select(r => r.ToString()).ToArray()),
e.StartAddress));
}
}

then you need to hook up to the data store event

dataStore.DataStoreWrittenTo += new
EventHandler<DataStoreEventArgs>(dataStore_DataStoreWrittenTo);


Scott

jani.g...@gmail.com

unread,
Sep 3, 2008, 2:21:29 AM9/3/08
to NModbus
Hi,

If I understand you well e.Data.A is an object of DataTable type. But
how are defined d and r in your code? Do I need some specific
definition of dataStore object. In my case dataStore object is defined
as dataStore = DataStoreFactory.CreateDefaultDataStore();

Thanx,

Jani



On 1 sep., 15:19, "Scott Alexander" <sja...@gmail.com> wrote:
> first you need the event handler, something like the following
>
> void dataStore_DataStoreWrittenTo(object sender, DataStoreEventArgs e)
> {
>         if (e.Data.Option == DiscriminatedUnionOption.A)
>         {
>                 Console.WriteLine(String.Format("Coil values {0} written starting at
> address {1}",
>                         String.Join(", ", e.Data.A.Select(d => d.ToString()).ToArray()),
> e.StartAddress));
>         }
>         else
>         {
>                 Console.WriteLine(String.Format("Holding register values {0} written
> starting at address {1}",
>                         String.Join(", ", e.Data.A.Select(r => r.ToString()).ToArray()),
> e.StartAddress));
>         }
>
> }
>
> then you need to hook up to the data store event
>
> dataStore.DataStoreWrittenTo += new
> EventHandler<DataStoreEventArgs>(dataStore_DataStoreWrittenTo);
>
> Scott
>

Scott Alexander

unread,
Sep 3, 2008, 10:14:33 AM9/3/08
to NModbus...@googlegroups.com
Oops, I made a typo. In the sample code, the value in the else block
should be e.Data.B, not e.Data.A.

e.Data.A is a ReadOnlyCollection<bool> representing the coil values
written to the DataStore.
e.Data.B is a ReadOnlyCollection<ushort> representing the holding
register values written to the DataStore.

In the sample code d and r represent e.Data.A and e.Data.B
respectively as lambda expression arguments provided to the Select
extension method.

Whether or not you need to create a custom DataStore object is up to
you. The DataStore object is intended to be set up to model a Modbus
device's memory map (e.g. 1000 holding registers, 500 input registers,
etc.)

Scott

jani.g...@gmail.com

unread,
Sep 4, 2008, 5:36:07 AM9/4/08
to NModbus
Hi Scott,

Now it is working. Thank you for your help and code examples.
I am very happy that now I can get values in my application from PLC
which is Modbus master.

Thanx&Best regards,

Jani


On 3 sep., 16:14, "Scott Alexander" <sja...@gmail.com> wrote:
> Oops, I made a typo. In the sample code, the value in the else block
> should be e.Data.B, not e.Data.A.
>
> e.Data.A is a ReadOnlyCollection<bool> representing the coil values
> written to the DataStore.
> e.Data.B is a ReadOnlyCollection<ushort> representing the holding
> register values written to the DataStore.
>
> In the sample code d and r represent e.Data.A and e.Data.B
> respectively as lambda expression arguments provided to the Select
> extension method.
>
> Whether or not you need to create a custom DataStore object is up to
> you. The DataStore object is intended to be set up to model a Modbus
> device's memory map (e.g. 1000 holding registers, 500 input registers,
> etc.)
>
> Scott
>
Reply all
Reply to author
Forward
0 new messages