实例介绍
【实例简介】
主要针对Modbus协议进行整理,形成类库方便大家使用
【实例截图】
【核心代码】
/// <summary>
/// Read coil registers
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="start_address">Address of first register to be read</param>
/// <param name="len">Number of registers to be read</param>
/// <returns>Array of readed registers</returns>
public bool[] ReadCoils(byte unit_id, ushort start_address, ushort len)
{
if (len < 1)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return null;
}
if (len > MAX_COILS_IN_READ_MSG)
{
error = Errors.TOO_MANY_REGISTERS_REQUESTED;
return null;
}
ushort msg_len = 6;
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.READ_COILS);
send_buffer.AddRange(GetBytes(start_address));
send_buffer.AddRange(GetBytes(len));
Query(unit_id, msg_len);
if (error != Errors.NO_ERROR)
return null;
BitArray ba = new BitArray(receive_buffer.GetRange(2, receive_buffer.Count - 2).ToArray());
bool[] ret = new bool[ba.Count];
ba.CopyTo(ret, 0);
return ret;
}
/// <summary>
/// Read a set of discrete inputs
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="start_address">Address of first register to be read</param>
/// <param name="len">Number of registers to be read</param>
/// <returns>Array of readed registers</returns>
public bool[] ReadDiscreteInputs(byte unit_id, ushort start_address, ushort len)
{
if (len < 1)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return null;
}
if (len > MAX_DISCRETE_INPUTS_IN_READ_MSG)
{
error = Errors.TOO_MANY_REGISTERS_REQUESTED;
return null;
}
ushort msg_len = 6;
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.READ_DISCRETE_INPUTS);
send_buffer.AddRange(GetBytes(start_address));
send_buffer.AddRange(GetBytes(len));
Query(unit_id, msg_len);
if (error != Errors.NO_ERROR)
return null;
BitArray ba = new BitArray(receive_buffer.GetRange(2, receive_buffer.Count - 2).ToArray());
bool[] ret = new bool[ba.Count];
ba.CopyTo(ret, 0);
return ret;
}
/// <summary>
/// Read a set of holding registers
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="start_address">Address of first register to be read</param>
/// <param name="len">Number of registers to be read</param>
/// <returns>Array of readed registers</returns>
public ushort[] ReadHoldingRegisters(byte unit_id, ushort start_address, ushort len)
{
if (len < 1)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return null;
}
if (len > MAX_HOLDING_REGISTERS_IN_READ_MSG)
{
error = Errors.TOO_MANY_REGISTERS_REQUESTED;
return null;
}
ushort msg_len = 6;
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.READ_HOLDING_REGISTERS);
send_buffer.AddRange(GetBytes(start_address));
send_buffer.AddRange(GetBytes(len));
Query(unit_id, msg_len);
if (error != Errors.NO_ERROR)
return null;
List<ushort> ret = new List<ushort>();
for (int ii = 0; ii < receive_buffer[1]; ii = 2)
ret.Add(ToUInt16(receive_buffer.ToArray(), ii 2));
return ret.ToArray();
}
/// <summary>
/// Read a set of input registers
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="start_address">Address of first register to be read</param>
/// <param name="len">Number of registers to be read</param>
/// <returns>Array of readed registers</returns>
public ushort[] ReadInputRegisters(byte unit_id, ushort start_address, ushort len)
{
if (len < 1)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return null;
}
if (len > MAX_INPUT_REGISTERS_IN_READ_MSG)
{
error = Errors.TOO_MANY_REGISTERS_REQUESTED;
return null;
}
ushort msg_len = 6;
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.READ_INPUT_REGISTERS);
send_buffer.AddRange(GetBytes(start_address));
send_buffer.AddRange(GetBytes(len));
Query(unit_id, msg_len);
if (error != Errors.NO_ERROR)
return null;
List<ushort> ret = new List<ushort>();
for (int ii = 0; ii < receive_buffer[1]; ii = 2)
ret.Add(ToUInt16(receive_buffer.ToArray(), ii 2));
return ret.ToArray();
}
/// <summary>
/// Write a coil register
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="address">Register address</param>
/// <param name="value">Value to write</param>
public void WriteSingleCoil(byte unit_id, ushort address, bool value)
{
ushort msg_len = 6;
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.WRITE_SINGLE_COIL);
send_buffer.AddRange(GetBytes(address));
send_buffer.AddRange(GetBytes((ushort)(value == true ? 0xFF00 : 0x0000)));
Query(unit_id, msg_len);
if (error == Errors.NO_ERROR)
{
ushort addr = ToUInt16(receive_buffer.ToArray(), 1);
ushort regval = ToUInt16(receive_buffer.ToArray(), 3);
if (addr != address)
{
error = Errors.WRONG_RESPONSE_ADDRESS;
return;
}
if ((regval == 0xFF00) && !value)
{
error = Errors.WRONG_RESPONSE_VALUE;
return;
}
}
}
/// <summary>
/// Write an holding register
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="address">Register address</param>
/// <param name="value">Value to write</param>
public void WriteSingleRegister(byte unit_id, ushort address, ushort value)
{
ushort msg_len = 6;
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.WRITE_SINGLE_REGISTER);
send_buffer.AddRange(GetBytes(address));
send_buffer.AddRange(GetBytes(value));
Query(unit_id, msg_len);
if (error == Errors.NO_ERROR)
{
ushort addr = ToUInt16(receive_buffer.ToArray(), 1);
if (addr != address)
{
error = Errors.WRONG_RESPONSE_ADDRESS;
return;
}
}
}
/// <summary>
/// Write a set of coil registers
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="start_address">Address of first register to be write</param>
/// <param name="values">Array of values to write</param>
public void WriteMultipleCoils(byte unit_id, ushort start_address, bool[] values)
{
if (values == null)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return;
}
if (values.Length < 1)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return;
}
if (values.Length > MAX_COILS_IN_WRITE_MSG)
{
error = Errors.TOO_MANY_REGISTERS_REQUESTED;
return;
}
byte byte_cnt = (byte)((values.Length / 8) ((values.Length % 8) == 0 ? 0 : 1));
ushort msg_len = (ushort)(1 6 byte_cnt);
byte[] data = new byte[byte_cnt];
BitArray ba = new BitArray(values);
ba.CopyTo(data, 0);
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.WRITE_MULTIPLE_COILS);
send_buffer.AddRange(GetBytes(start_address));
send_buffer.AddRange(GetBytes((ushort)values.Length));
send_buffer.Add(byte_cnt);
send_buffer.AddRange(data);
Query(unit_id, msg_len);
if (error == Errors.NO_ERROR)
{
ushort sa = ToUInt16(receive_buffer.ToArray(), 1);
ushort nr = ToUInt16(receive_buffer.ToArray(), 3);
if (sa != start_address)
{
error = Errors.WRONG_RESPONSE_ADDRESS;
return;
}
if (nr != values.Length)
{
error = Errors.WRONG_RESPONSE_REGISTERS;
return;
}
}
}
/// <summary>
/// Write a set of holding registers
/// </summary>
/// <param name="unit_id">Slave device address</param>
/// <param name="start_address">Address of first register to be write</param>
/// <param name="values">Array of values to write</param>
public void WriteMultipleRegisters(byte unit_id, ushort start_address, ushort[] values)
{
if (values == null)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return;
}
if (values.Length < 1)
{
error = Errors.ZERO_REGISTERS_REQUESTED;
return;
}
if (values.Length > MAX_HOLDING_REGISTERS_IN_WRITE_MSG)
{
error = Errors.TOO_MANY_REGISTERS_REQUESTED;
return;
}
ushort msg_len = (ushort)(7 (values.Length * 2));
InitTCPUDPMasterMessage();
send_buffer.Add((byte)ModbusCodes.WRITE_MULTIPLE_REGISTERS);
send_buffer.AddRange(GetBytes(start_address));
send_buffer.AddRange(GetBytes((ushort)values.Length));
send_buffer.Add((byte)(values.Length * 2));
for (int ii = 0; ii < values.Length; ii )
send_buffer.AddRange(GetBytes(values[ii]));
Query(unit_id, msg_len);
if (error == Errors.NO_ERROR)
{
ushort sa = ToUInt16(receive_buffer.ToArray(), 1);
ushort nr = ToUInt16(receive_buffer.ToArray(), 3);
if (sa != start_address)
{
error = Errors.WRONG_RESPONSE_ADDRESS;
return;
}
if (nr != values.Length)
{
error = Errors.WRONG_RESPONSE_REGISTERS;
return;
}
}
}
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论