0% found this document useful (0 votes)
327 views

Serial & Modbus Example Example

The document describes examples of implementing Modbus RTU and TCP slave devices in C#. It shows how to create data tables to handle register and coil reads and writes, and start the server. It also demonstrates optional support for input registers and Enron mode.

Uploaded by

bhageshl
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
327 views

Serial & Modbus Example Example

The document describes examples of implementing Modbus RTU and TCP slave devices in C#. It shows how to create data tables to handle register and coil reads and writes, and start the server. It also demonstrates optional support for input registers and Enron mode.

Uploaded by

bhageshl
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

Serial Example

The following example tinyslave.cpp shows how to implement a small Modbus RTU slave:
C#
VB
Copy

//
// @file tinyslave.cs
//
// A simple Modbus RTU slave program.
//
// @if NOTICE
//
// Copyright (c) proconX Pty Ltd. All rights reserved.
//
// The following source file constitutes example program code and is
// intended merely to illustrate useful programming techniques. The user
// is responsible for applying the code correctly.
//
// THIS SOFTWARE IS PROVIDED BY PROCONX AND CONTRIBUTORS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PROCONX OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// @endif
//

using System;
using FieldTalk.Modbus.Slave;

class MyDatatable: MbusDataTableInterface


{
private short[] localRegisters = new short[1000];
private bool[] localCoils = new bool[1000];

protected override bool readHoldingRegistersTable(Int32 startRef, Int16[]


regArr)
{
Console.WriteLine("readHoldingRegisters from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + regArr.Length > localRegisters.Length)
{
return false;
}
// Copy registers from local data array to Modbus
for (int i = 0; i < regArr.Length; i++)
{
regArr[i] = localRegisters[startRef + i];
}
return true;
}

protected override bool writeHoldingRegistersTable(Int32 startRef, Int16[]


regArr)
{
Console.WriteLine("writeHoldingRegisters from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + regArr.Length > localRegisters.Length)
{
return false;
}
// Copy registers from Modbus to local data block
for (int i = 0; i < regArr.Length; i++)
{
localRegisters[startRef + i] = regArr[i];
}
return true;
}

class TcpSlaveApp
{
private MbusRtuSlaveProtocol mbusServer = new MbusRtuSlaveProtocol();
private MyDatatable dataTable = new MyDatatable();

private void startupServer()


{
int result;

result = mbusServer.addDataTable(1, dataTable); // Unit ID is 1


if (result == BusProtocolErrors.FTALK_SUCCESS)
{
result = mbusServer.startupServer("COM1:", // The colon is important
under CE!
19200, // Baudrate
MbusSerialSlaveProtocol.SER_DATABITS_8,
MbusSerialSlaveProtocol.SER_STOPBITS_1,

MbusSerialSlaveProtocol.SER_PARITY_EVEN);
}
if (result != BusProtocolErrors.FTALK_SUCCESS)
{
Console.WriteLine(BusProtocolErrors.getBusProtocolErrorText(result));
Environment.Exit(result);
}
Console.WriteLine("Modbus server started on serial interface " +
mbusServer.portName);
}

private void shutdownServer()


{
mbusServer.shutdownServer();
}

private void runServer()


{
int result;

do
{
result = mbusServer.serverLoop();
} while (!(result != BusProtocolErrors.FTALK_SUCCESS));
if (result != BusProtocolErrors.FTALK_SUCCESS)
{
Console.WriteLine(BusProtocolErrors.getBusProtocolErrorText(result));
}
}

public static void Main()


{
TcpSlaveApp app = new TcpSlaveApp();
app.startupServer();
app.runServer();
app.shutdownServer();
}

MODBUS/TCP Example
The following example tcpslave.cpp shows how to implement a small Modbus/TCP slave:
C#
VB
Copy

//
// @file tcpslave.cs
//
// A simple console based example using FieldTalk in Modbus/TCP slave mode

// @if NOTICE
//
// Copyright (c) proconX Pty Ltd. All rights reserved.
//
// The following source file constitutes example program code and is
// intended merely to illustrate useful programming techniques. The user
// is responsible for applying the code correctly.
//
// THIS SOFTWARE IS PROVIDED BY PROCONX AND CONTRIBUTORS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PROCONX OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// @endif
//

using System;
using FieldTalk.Modbus.Slave;

class MyDatatable: MbusDataTableInterface


{
private short[] localRegisters = new short[1000];
private bool[] localCoils = new bool[1000];

protected override bool readHoldingRegistersTable(Int32 startRef, Int16[]


regArr)
{
Console.WriteLine("readHoldingRegisters from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + regArr.Length > localRegisters.Length)
{
return false;
}
// Copy registers from local data array to Modbus
for (int i = 0; i < regArr.Length; i++)
{
regArr[i] = localRegisters[startRef + i];
}
return true;
}

#if ENABLE_INPUT_REGS // Set to true if input registers shall be supported


protected override bool readInputRegistersTable(Int32 startRef, Int16[]
regArr)
{
Console.WriteLine("readInputRegistersTable from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + regArr.Length > localRegisters.Length)
{
return false;
}
// Copy registers from local data array to Modbus
for (int i = 0; i < regArr.Length; i++)
{
regArr[i] = localRegisters[startRef + i];
}
return true;
}
#endif

protected override bool writeHoldingRegistersTable(Int32 startRef, Int16[]


regArr)
{
Console.WriteLine("writeHoldingRegisters from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + regArr.Length > localRegisters.Length)
{
return false;
}
// Copy registers from Modbus to local data block
for (int i = 0; i < regArr.Length; i++)
{
localRegisters[startRef + i] = regArr[i];
}
return true;
}

protected override bool readCoilsTable(Int32 startRef, bool[] bitArr)


{
Console.WriteLine("readCoilsTable from " + startRef + ", " + bitArr.Length
+ " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + bitArr.Length > localCoils.Length)
{
return false;
}
// Copy registers from local data array to Modbus
for (int i = 0; i < bitArr.Length; i++)
{
bitArr[i] = localCoils[startRef + i];
}
return true;
}

protected override bool writeCoilsTable(Int32 startRef, bool[] bitArr)


{
Console.WriteLine("writeCoilsTable from " + startRef + ", " +
bitArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;
// Validate range
if (startRef + bitArr.Length > localCoils.Length)
{
return false;
}
// Copy registers from Modbus to local data block
for (int i = 0; i < bitArr.Length; i++)
{
localCoils[startRef + i] = bitArr[i];
}
return true;
}

#if ENABLE_ENRON_REGS // Set to true if Enron mode is required


private Int32[] enronData = new Int32[4000];

protected override bool readEnronRegistersTable(int startRef, Int32[] regArr)


{
Console.WriteLine("readEnronRegistersTable from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;

//
// Validate start address range
// Note: In this example, we have 2000 references at 5000 and 2000
references at 7000.
//
if ((startRef < 5000) || (startRef >= 9000))
return false;
else
startRef -=5000;
if (startRef + regArr.Length > enronData.Length)
{
return false;
}
// Copy registers from local data array to Modbus
for (int i = 0; i < regArr.Length; i++)
{
regArr[i] = enronData[startRef + i];
}
return true;
}

protected override bool writeEnronRegistersTable(Int32 startRef, Int32[]


regArr)
{
Console.WriteLine("writeEnronRegistersTable from " + startRef + ", " +
regArr.Length + " references");
// Adjust Modbus reference counting from 1-based to 0-based
startRef--;

//
// Validate start address range
// Note: In this example, we have 2000 references at 5000 and 2000
references at 7000.
//
if ((startRef < 5000) || (startRef >= 9000))
return false;
else
startRef -= 5000;
if (startRef + regArr.Length > enronData.Length)
{
return false;
}
// Copy registers from Modbus to local data block
for (int i = 0; i < regArr.Length; i++)
{
enronData[startRef + i] = regArr[i];
}
return true;
}
#endif

class TcpSlaveApp
{
private MbusTcpSlaveProtocol mbusServer = new MbusTcpSlaveProtocol();
private MyDatatable dataTable = new MyDatatable();

private void startupServer()


{
int result;

result = mbusServer.addDataTable(1, dataTable); // Unit ID is 1


if (result == BusProtocolErrors.FTALK_SUCCESS)
{
result = mbusServer.startupServer();
}
if (result != BusProtocolErrors.FTALK_SUCCESS)
{
Console.WriteLine(BusProtocolErrors.getBusProtocolErrorText(result));
Environment.Exit(result);
}
Console.WriteLine("Modbus server started on TCP interface.");
}

private void shutdownServer()


{
mbusServer.shutdownServer();
}

private void runServer()


{
int result;

do
{
result = mbusServer.serverLoop();
} while (!(result != BusProtocolErrors.FTALK_SUCCESS));
if (result != BusProtocolErrors.FTALK_SUCCESS)
{
Console.WriteLine(BusProtocolErrors.getBusProtocolErrorText(result));
}
}

public static void Main()


{
TcpSlaveApp app = new TcpSlaveApp();
app.startupServer();
app.runServer();
app.shutdownServer();
}

You might also like