通過串列埠進行通訊 :

Endv發表於2018-03-27

通過串列埠進行通訊 :

1、將 NMobus 類庫匯入工程中,新增引用、名稱空間。工程屬性必須配置 為 .NET 4.0。

2、建立 SerialPort 類的一個例項,配置引數,開啟串列埠,如:

public SerialPort port = new SerialPort(“ COM1” )//建立串列埠

port.BaudRate = 9600;//配置

port.DataBits = 8;

port.Parity = Parity.None;

port.StopBits = StopBits.One;

port.Open();//開啟串列埠

3、呼叫相應方法建立 Modbus 主站,如:

IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port); //建立 Rtu 傳輸模式、通過串列埠 port 通訊的主站 master IModbusSerialMaster master = ModbusSerialMaster.CreateAscii(port); //ASCII傳輸模式

4、配置引數,如:

master.Transport.ReadTimeout = 1000;//讀取串列埠資料超時為 1000ms master.Transport.WriteTimeout = 1000;//寫入串列埠資料超時

master.Transport.Retries = 3;//重試次數

master.Transport.WaitToRetryMilliSeconds = 250;//重試間隔

5、呼叫相應方法執行功能,如:

try

{

master.WriteMultipleRegisters(slaveId, startAddress, registers); }

有以下幾種功能:

//讀線圈,引數:從站地址 (8位 ) 、起始地址 (16位 ) 、數量 (16位 ) ;返回布林型數 組

bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort numberOfPoints);

//讀輸入離散量,引數:從站地址 (8位 ) 、起始地址 (16位 ) 、數量 (16位 ) ;返回布 爾型陣列

bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort numberOfPoints);

//讀保持暫存器,引數:從站地址 (8位 ) 、起始地址 (16位 ) 、數量 (16位 ) ;返回 16位整型陣列

ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort

numberOfPoints);

//讀輸入暫存器,引數:從站地址 (8位 ) 、起始地址 (16位 ) 、數量 (16位 ) ;返回 16位整型陣列

ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints);

//寫單個線圈,引數:從站地址 (8位 ) ,線圈地址 (16位 ) ,線圈值 (布林型 ) void WriteSingleCoil(byte slaveAddress, ushort coilAddress, bool value);

//寫單個暫存器,引數:從站地址 (8位 ) ,暫存器地址 (16位 ) ,暫存器值 (16位 ) void WriteSingleRegister(byte slaveAddress, ushort registerAddress, ushort value);

//寫多個暫存器,引數:從站地址 (8位 ) ,起始地址 (16位 ) ,暫存器值 (16位整型 陣列 )

void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] data);

//寫多個線圈,引數:從站地址 (8位 ) ,起始地址 (16位 ) ,線圈值 (布林型陣列 ) void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] data);

//讀寫多個暫存器,引數:從站地址 (8位 ) ,讀起始地址 (16位 ) ,數量 (16位 ) ,寫 起始地址 (16位 ) ,寫入值 (16位整型陣列 ) ;返回 16位整型陣列

ushort[] ReadWriteMultipleRegisters(byte slaveAddress, ushort startReadAddress, ushort numberOfPointsToRead, ushort startWriteAddress, ushort[] writeData);

6、使用 catch 語句捕捉異常:

如果執行沒有出錯,則不丟擲異常,如果是執行讀操作則能得到相應的 返回值。

響應超時會丟擲 TimeoutException 型別的異常 ;

接收到從站的異常響應時會丟擲 SlaveException 型別的異常, 這一類異常 包含 SlaveExceptionCode 屬性,即異常碼,通過判斷異常碼能得知出錯的原因。

 

 

 

// create and start the TCP slave

TcpListener slaveTcpListener = new TcpListener(address, port);

slaveTcpListener.Start();

ModbusSlave slave = ModbusTcpSlave.CreateTcp(slaveID, slaveTcpListener);

Thread slaveThread = new Thread(slave.Listen);

slaveThread.Start();

// create the master

TcpClient masterTcpClient = new TcpClient(address.ToString(), port);

ModbusIpMaster master = ModbusIpMaster.CreateTcp(masterTcpClient);

ushort numInputs = 5;

ushort startAddress = 100;

// read five register values

ushort[] inputs = master.ReadInputRegisters(startAddress, numInputs);

for (int i = 0; i < numInputs; i++)

Console.WriteLine("Register {0}={1}", startAddress + i, inputs[i]);

// clean up

masterTcpClient.Close();

slaveTcpListener.Stop();

// output

// Register 100=0

// Register 101=0

// Register 102=0

// Register 103=0

// Register 104=0

Modbus serial ASCII master and slave example.


using (SerialPort masterPort = new SerialPort("COM1"))

using (SerialPort slavePort = new SerialPort("COM2"))


{

// configure serial ports

masterPort.BaudRate = slavePort.BaudRate = 9600;

masterPort.DataBits = slavePort.DataBits = 8;

masterPort.Parity = slavePort.Parity = Parity.None;

masterPort.StopBits = slavePort.StopBits = StopBits.One;

masterPort.Open();

slavePort.Open();

// create modbus slave on seperate thread

byte slaveID = 1;

ModbusSlave slave = ModbusSerialSlave.CreateAscii(slaveID, slavePort);

Thread slaveThread = new Thread(new ThreadStart(slave.Listen));

slaveThread.Start();

// create modbus master

ModbusSerialMaster master = ModbusSerialMaster.CreateAscii(masterPort);

master.Transport.Retries = 5;

ushort startAddress = 100;

ushort numRegisters = 5;

// read five register values

ushort[] registers = master.ReadHoldingRegisters(slaveID, startAddress, numRegisters);

for (int i = 0; i < numRegisters; i++)

Console.WriteLine("Register {0}={1}", startAddress + i, registers[i]);

}

// output

// Register 100=0

// Register 101=0

// Register 102=0

// Register 103=0

// Register 104=0

Write and Read 32 bit value example.

uint largeValue = UInt16.MaxValue + 5;

ushort lowOrderValue = BitConverter.ToUInt16(BitConverter.GetBytes(largeValue), 0);

ushort highOrderValue = BitConverter.ToUInt16(BitConverter.GetBytes(largeValue), 2);

// write large value in two 16 bit chunks

master.WriteMultipleRegisters(slaveID, startAddress, new ushort[] { lowOrderValue, highOrderValue });

// read large value in two 16 bit chunks and perform conversion

ushort[] registers = master.ReadHoldingRegisters(slaveID, startAddress, 2);

uint value = ModbusUtility.GetUInt32(registers[1], registers[0]);

NModbus

http://web.archive.org/web/20090601225835/http://www...

第4頁??共6頁

2011/07/06??9:49

Logging example.


NModbus uses log4net. Your application can easily be configured to capture the NModbus log

statements, as well as your own. Try adding the following xml to your application's configuration


settings. NModbusConsoleAppender consumes only log statements of level INFO and higher

while NModbusFileAppender consumes all log statements (output to NModbusLog.txt).

<configSections>

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

</configSections>

<log4net>

<root>

<level value="DEBUG" />

<appender-ref ref="NModbusFileAppender" />

<appender-ref ref="NModbusConsoleAppender" />

</root>

<appender name="NModbusFileAppender" type="log4net.Appender.FileAppender">

<file value="NModbusLog.txt" />

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%-5level %logger %method - %message%newline" />

</layout>

</appender>

<appender name="NModbusConsoleAppender" type="log4net.Appender.ConsoleAppender">

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%-5level %logger %method - %message%newline" />

</layout>

<filter type="log4net.Filter.LevelRangeFilter">

<levelMin value="INFO" />

</filter>

</appender>

</log4net>

To configure log4net based on your application's configuration settings add the following line.

log4net.Config.XmlConfigurator.Configure();

Example log4net appender output for a the modbus serial RTU master write registers example.

// ConsoleAppender

INFO Modbus.IO.ModbusTransport UnicastMessage - TX: 1, 16, 0, 100, 0, 3, 6, 0, 1, 0, 2, 0, 3

INFO Modbus.IO.ModbusTransport UnicastMessage - RX: 1, 16, 0, 100, 0, 3

// FileAppender (NModbusLog.txt)

INFO Modbus.IO.ModbusTransport UnicastMessage - TX: 1, 16, 0, 100, 0, 3, 6, 0, 1, 0, 2, 0, 3

DEBUG Modbus.IO.ModbusRtuTransport Read - Read 4 bytes.

DEBUG Modbus.IO.ModbusRtuTransport ReadResponse - Frame start 1, 16, 0, 100.

DEBUG Modbus.IO.ModbusRtuTransport Read - Read 4 bytes.

DEBUG Modbus.IO.ModbusRtuTransport ReadResponse - Frame end 0, 3, 193, 215.

INFO Modbus.IO.ModbusTransport UnicastMessage - RX: 1, 16, 0, 100, 0, 3

For more information visit the

log4net

project page.

Add your own custom messages.

So your device has custom messages? Not a problem, NModbus exposes interfaces IModbusMessage and

IModbusMessageWithData just for that reason. Simply implement custom request and response messages

and call the appropriate ModbusMaster.ExecuteCustomMessage overload.

Example from a test demonstrationg both ExecuteCustomMessage overloads:

 

ushort testAddress = 120;

ushort[] testValues = new ushort[] { 10, 20, 30, 40, 50 };

CustomReadHoldingRegistersRequest readRequest = new CustomReadHoldingRegistersRequest(3, SlaveAddress, testAddress, (ushort) testValue

CustomWriteMultipleRegistersRequest writeRequest = new CustomWriteMultipleRegistersRequest(16, SlaveAddress, testAddress, new RegisterCo

ushort[] originalValues = Master.ExecuteCustomMessage<CustomReadHoldingRegistersResponse, ushort>(readRequest);

Master.ExecuteCustomMessage<CustomWriteMultipleRegistersResponse>(writeRequest);

ushort[] newValues = Master.ExecuteCustomMessage<CustomReadHoldingRegistersResponse, ushort>(readRequest);

Assert.AreEqual(testValues, newValues);

writeRequest = new CustomWriteMultipleRegistersRequest(16, SlaveAddress, testAddress, new RegisterCollection(originalValues));

Master.ExecuteCustomMessage<CustomWriteMultipleRegistersResponse>(writeRequest);

 

Check out these example custom message implementations:

 

CustomReadHoldingRegistersRequest

 

CustomReadHoldingRegistersResponse

NModbus

CustomWriteMultipleRegistersRequest

 

CustomWriteMultipleRegistersResponse

NModbus


 

相關文章