using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Modbus.Device;
using System.Net.Sockets;
using System.IO.Ports;
using System.IO;
namespace ModBusTest
{
public class MyModBus
{
SerialPort serialPort;
TcpClient client;
IModbusMaster master;
public string Err;
///
/// TCP IP 方式连接
///
///
/// 连接是否成功
public bool ConnectIP(string IP)
{
try
{
client = new TcpClient(IP, 502);
if (client.Connected)
{
master = ModbusIpMaster.CreateIp(client);
master.Transport.ReadTimeout = 200;
master.Transport.WriteTimeout = 200;
master.Transport.Retries = 2;
master.Transport.WaitToRetryMilliseconds = 200;
return true;
}
else
{
WriteLog(“打开失败,请检查IP”);
return false;
}
}
catch (Exception ex)
{
WriteLog(ex.ToString());
return false;
}
}
///
/// 串口 RTU方式连接
///
/// 串口名
/// 波特率
/// 连接是否成功
public bool ConnectSerial(string COM,int Baud)
{
try
{
serialPort = new SerialPort();
serialPort.PortName = COM;
serialPort.BaudRate = Baud;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.Two;
serialPort.Parity = Parity.None;
serialPort.Open();
master = ModbusSerialMaster.CreateRtu(serialPort);
master.Transport.ReadTimeout = 200;
master.Transport.WriteTimeout = 200;
master.Transport.Retries = 2;
master.Transport.WaitToRetryMilliseconds = 200;
return true;
catch (Exception ex)
WriteLog(ex.ToString());
return false;
/// <summary>
/// 读取保持寄存器值 03H
/// </summary>
/// <param name="SlaveID">从站号</param>
/// <param name="StartAddress">开始读取的寄存器地址</param>
/// <param name="NumOfPoint">读取数据个数</param>
/// <returns></returns>
public short[] ReadHoldingRegisters(byte SlaveID,ushort StartAddress,ushort NumOfPoint)
ushort[] Uvalue = master.ReadHoldingRegisters(SlaveID, StartAddress, NumOfPoint);
short[] value = new short[Uvalue.Length];
for (int i = 0; i < Uvalue.Length; i++)
if (Uvalue[i] > short.MaxValue)
value[i] = (short)(Uvalue[i] - 65536);
value[i] = (short)Uvalue[i];
return value;
catch (Exception ex)
WriteLog(ex.ToString());
return null;
/// <summary>
/// 单个写保持寄存器值 06H
/// </summary>
/// <param name="slaveAddress"></param>
/// <param name="registerAddress"></param>
/// <param name="value"></param>
public void WriteSingleRegister(byte slaveAddress, ushort registerAddress, short value)
ushort Uvalue;
if (value < 0)
Uvalue = (ushort)(ushort.MaxValue + value + 1);
Uvalue = (ushort)value;
master.WriteSingleRegister(slaveAddress, registerAddress, Uvalue);
catch (Exception ex)
WriteLog(ex.ToString());
return;
/// <summary>
/// 读取线圈 01H
/// </summary>
/// <param name="slaveAddress"></param>
/// <param name="startAddress"></param>
/// <param name="numberOfPoints"></param>
/// <returns></returns>
public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
return master.ReadCoils(slaveAddress, startAddress, numberOfPoints);
/// <summary>
/// 单个写线圈 05H
/// </summary>
/// <param name="slaveAddress"></param>
/// <param name="coilAddress"></param>
/// <param name="value"></param>
public void WriteSingleCoil(byte slaveAddress, ushort coilAddress, bool value)
master.WriteSingleCoil(slaveAddress, coilAddress, value);
/// <summary>
/// 读取输入寄存器 04H
/// </summary>
/// <param name="slaveAddress"></param>
/// <param name="startAddress"></param>
/// <param name="numberOfPoints"></param>
/// <returns></returns>
public short[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
ushort[] Uvalue = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
short[] value = new short[Uvalue.Length];
for (int i = 0; i < Uvalue.Length; i++)
if (Uvalue[i] > short.MaxValue)
value[i] = (short)(Uvalue[i] - 65536);
value[i] = (short)Uvalue[i];
return value;
catch(Exception ex)
WriteLog(ex.ToString());
return null;
/// <summary>
/// 读取输入 02H
/// </summary>
/// <param name="slaveAddress"></param>
/// <param name="startAddress"></param>
/// <param name="numberOfPoints"></param>
/// <returns></returns>
public bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
return master.ReadInputs(slaveAddress, startAddress, numberOfPoints);
/// <summary>
/// 记录异常log,使用时解除释放
/// </summary>
/// <param name="message"></param>
protected virtual void WriteLog(string message)
string LogPath = "D:\\Log\\ModBusLog\\";
if (!Directory.Exists(LogPath))
Directory.CreateDirectory(LogPath);
string path = LogPath + DateTime.Today.ToString("yyyyMMdd") + ".txt";
string str = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff") + " => " + message;
// CsvServer.Instance.WriteLine(path, str);
Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。所以这也是我们工控领域软件开发的所必懂的通讯协议,我也是初次学习,先贴上我的学习笔记.
一 、协议概述
1、Modbus协议是应用于控制器上的一种通用语言,实现控制器之间,控制器通过网络和其他设备之间的通信,支持传统RS232/RS422/RS485和以太网设备,它已经成为一种通用的工业标准,有了它不同厂商生产的控制设备可以连成工业网络,进行集中控制,此协议定义了一个控制器能认识...
背景:最近想提升下测试设备的方面的能力,yan测试设备的软件平台,前期朋友C#开发的,所有功能软件内部写好,由于不是专门的公司,后期发现维护工作大多,新需求变更要新编写功能,逐步平台放弃了,最近
1. WriteSingleCoil(byte slaveadress, ushort coilAddress, bool value) ;控制modbus0x地址
*slaveadress是对应的ID
*coilAddress 是控制线圈地址 注:地址比modbus地址小1
*value