Вы находитесь на странице: 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();
}

Вам также может понравиться