ModbusTcpSlaverService.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using NModbus;
  2. using System;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Threading;
  6. using Team.Utility;
  7. namespace Team.Communicate.Modbus
  8. {
  9. public class ModbusTcpSlaverService : IModbusTcpSlaverService
  10. {
  11. private IModbusSlave _modbusSlave;
  12. private TcpListener slaveTcpListener;
  13. public event EventHandler<StorageEventArgs<bool>> CoilDiscretesHandler;
  14. public event EventHandler<StorageEventArgs<ushort>> InputRegistersHandler;
  15. public event EventHandler<StorageEventArgs<ushort>> HoldeRegistersHandler;
  16. private CancellationTokenSource _cancellationTokenSource;
  17. public ModbusTcpSlaverService()
  18. {
  19. _cancellationTokenSource = new CancellationTokenSource();
  20. }
  21. /// <summary>
  22. /// create and start the TCP slave
  23. /// 默认创建所有监听所有网卡ip地址和localhost
  24. /// 默认端口号为502
  25. /// 默认slaveId为1
  26. /// </summary>
  27. public void CreateModbusTcpSlave(string ip = default, byte slaveId = 1, int port = 502)
  28. {
  29. IPAddress address;
  30. if (ip == default)
  31. {
  32. address = IPAddress.Any;
  33. }
  34. else
  35. {
  36. var ret = IPAddress.TryParse(ip, out address);
  37. if (!ret)
  38. {
  39. throw new ArgumentException("ip 参数错误");
  40. }
  41. }
  42. slaveTcpListener = new TcpListener(address, port);
  43. slaveTcpListener.Start();
  44. var factory = new ModbusFactory();
  45. var network = factory.CreateSlaveNetwork(slaveTcpListener);
  46. var slaveStorage = new SlaveStorage();
  47. slaveStorage.InputRegisters.StorageOperationOccurred += InputRegisters_StorageOperationOccurred;
  48. slaveStorage.HoldingRegisters.StorageOperationOccurred += HoldingRegisters_StorageOperationOccurred;
  49. slaveStorage.CoilInputs.StorageOperationOccurred += CoilInputs_StorageOperationOccurred;
  50. slaveStorage.CoilDiscretes.StorageOperationOccurred += CoilDiscretes_StorageOperationOccurred; ;
  51. var slave = factory.CreateSlave(slaveId, slaveStorage);
  52. network.AddSlave(slave);
  53. var listenTask = network.ListenAsync(_cancellationTokenSource.Token);
  54. _modbusSlave = slave;
  55. }
  56. private void CoilDiscretes_StorageOperationOccurred(object sender, StorageEventArgs<bool> args)
  57. {
  58. //LogUtil.WriteInfo($"DANFOSS CoilDiscretes: {args.Operation} starting at {args.StartingAddress},count {args.Points.Length}");
  59. CoilDiscretesHandler?.Invoke(this, args );
  60. }
  61. private void CoilInputs_StorageOperationOccurred(object sender, StorageEventArgs<bool> args)
  62. {
  63. //LogUtil.WriteInfo($"DANFOSS CoilInputs: {args.Operation} starting at {args.StartingAddress},count {args.Points.Length}");
  64. }
  65. private void HoldingRegisters_StorageOperationOccurred(object sender, StorageEventArgs<ushort> args)
  66. {
  67. //HoldeRegistersHandler?.Invoke(this, args);
  68. //var x=args.Points[32];
  69. }
  70. private void InputRegisters_StorageOperationOccurred(object sender, StorageEventArgs<ushort> args)
  71. {
  72. //LogUtil.WriteInfo($"DANFOSS Input registers: {args.Operation} starting at {args.StartingAddress},count {args.Points.Length}");
  73. InputRegistersHandler?.Invoke(this, args);
  74. }
  75. public IModbusSlave GetModbusSlaveByIp()
  76. {
  77. return _modbusSlave;
  78. }
  79. /// <summary>
  80. /// 写入32位整数
  81. /// </summary>
  82. /// <param name="startAddress"></param>
  83. /// <param name="value"></param>
  84. public void WriteParameter(ushort startAddress,int value)
  85. {
  86. if (_modbusSlave==null)
  87. {
  88. throw new Exception("没有创建modbus slave");
  89. }
  90. var bytes=BitConverter.GetBytes(value);
  91. var first = BitConverter.ToUInt16(new[] {bytes[0], bytes[1]},0);
  92. var second = BitConverter.ToUInt16(new[] { bytes[2], bytes[3] }, 0);
  93. _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new []{ first, second });
  94. }
  95. public void WriteCoilParameter(ushort startAddress, bool value)
  96. {
  97. if (_modbusSlave == null)
  98. {
  99. throw new Exception("没有创建modbus slave");
  100. }
  101. _modbusSlave.DataStore.CoilInputs.WritePoints(startAddress,new bool[] {value});
  102. }
  103. /// <summary>
  104. /// 写入32位正整数
  105. /// </summary>
  106. /// <param name="startAddress"></param>
  107. /// <param name="value"></param>
  108. public void WriteParameter(ushort startAddress, uint value)
  109. {
  110. if (_modbusSlave == null)
  111. {
  112. throw new Exception("没有创建modbus slave");
  113. }
  114. var bytes = BitConverter.GetBytes(value);
  115. var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0);
  116. var second = BitConverter.ToUInt16(new[] { bytes[2], bytes[3] }, 0);
  117. _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first, second });
  118. }
  119. /// <summary>
  120. /// 写入16位正整数
  121. /// </summary>
  122. /// <param name="startAddress"></param>
  123. /// <param name="value"></param>
  124. public void WriteParameter(ushort startAddress, ushort value)
  125. {
  126. if (_modbusSlave == null)
  127. {
  128. throw new Exception("没有创建modbus slave");
  129. }
  130. var bytes = BitConverter.GetBytes(value);
  131. var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0);
  132. _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first});
  133. }
  134. /// <summary>
  135. /// 写入16位整数
  136. /// </summary>
  137. /// <param name="startAddress"></param>
  138. /// <param name="value"></param>
  139. public void WriteParameter(ushort startAddress, short value)
  140. {
  141. if (_modbusSlave == null)
  142. {
  143. throw new Exception("没有创建modbus slave");
  144. }
  145. var bytes = BitConverter.GetBytes(value);
  146. var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0);
  147. _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first });
  148. }
  149. public void Dispose()
  150. {
  151. slaveTcpListener.Stop();
  152. _cancellationTokenSource.Cancel();
  153. }
  154. }
  155. }