Modbus.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using IPLCConnect;
  2. using NModbus;
  3. using System.Runtime.CompilerServices;
  4. namespace ModbusConnect
  5. {
  6. [PLCProtocol(PLCProtocol.Modbus)]
  7. public sealed class Modbus : IPLCConnect.IPLCConnect
  8. {
  9. public PLCProtocol Protocol => PLCProtocol.Modbus;
  10. private System.Net.Sockets.TcpClient? tcpClient;
  11. private IModbusMaster? modbus;
  12. private bool isConnected;
  13. private bool isfirst = true;
  14. public bool IsConnected
  15. {
  16. get => isConnected;
  17. set
  18. {
  19. if (!isfirst && isConnected == value) return;
  20. isConnected = value;
  21. StatusChanged?.Invoke(this, value);
  22. isfirst = false;
  23. }
  24. }
  25. public string IP { get; set; } = "127.0.0.1";
  26. public int Port { get; set; } = 502;
  27. public byte SlaveID { get; set; } = 1;
  28. public event EventHandler<bool> StatusChanged;
  29. public void Connect()
  30. {
  31. try
  32. {
  33. var modbusFactory = new NModbus.ModbusFactory();
  34. tcpClient = new System.Net.Sockets.TcpClient();
  35. var result = tcpClient.ConnectAsync(IP, Port).Wait(500);
  36. IsConnected = result;
  37. if (!IsConnected) return;
  38. modbus = modbusFactory.CreateMaster(tcpClient);
  39. IsConnected = true;
  40. }
  41. catch
  42. {
  43. IsConnected = false;
  44. }
  45. }
  46. public void DisConnect()
  47. {
  48. try
  49. {
  50. tcpClient?.Close();
  51. }
  52. catch
  53. {
  54. }
  55. IsConnected = false;
  56. }
  57. public void Dispose()
  58. {
  59. DisConnect();
  60. }
  61. public void Init(string ip, int port)
  62. {
  63. IP = ip;
  64. Port = port;
  65. }
  66. public T Read<T>(string addr) where T : unmanaged
  67. {
  68. if(modbus == null ||tcpClient == null || !tcpClient.Connected)
  69. {
  70. IsConnected = false;
  71. return default;
  72. }
  73. if (string.IsNullOrEmpty(addr)) return default;
  74. ushort startaddr = ushort.Parse(addr);
  75. byte addrnum =(byte)Unsafe.SizeOf<T>();
  76. ushort[] data = new ushort[addrnum / 2];
  77. try
  78. {
  79. if (modbus != null)
  80. {
  81. data = modbus.ReadHoldingRegisters(SlaveID, (ushort)(startaddr + (addrnum >> 2) - 1), (ushort)(addrnum >> 1));
  82. }
  83. }
  84. catch
  85. {
  86. DisConnect();
  87. }
  88. return Unsafe.As<ushort,T>(ref data[0]);
  89. }
  90. public void Write<T>(string addr, T value) where T : unmanaged
  91. {
  92. if (modbus == null) return;
  93. if (string.IsNullOrEmpty(addr)) return;
  94. ushort address = ushort.Parse(addr);
  95. byte bytecount = (byte)Unsafe.SizeOf<T>();
  96. try
  97. {
  98. ushort[] datas = new ushort[bytecount / 2];
  99. Unsafe.CopyBlock(ref Unsafe.As<ushort, byte>(ref datas[0]), ref Unsafe.As<T, byte>(ref value), (uint)datas.Length * 2);
  100. modbus.WriteMultipleRegisters(SlaveID, (ushort)(address + (bytecount >> 1) - 1 - 1), datas);
  101. }
  102. catch
  103. {
  104. DisConnect();
  105. }
  106. }
  107. public bool ReadBit(string addr, byte bitindex)
  108. {
  109. if (string.IsNullOrEmpty(addr)) return false;
  110. var result = Read<ushort>(addr);
  111. return (result & (1 << bitindex)) != 0;
  112. }
  113. public void Writebit(string addr, byte bitindex, bool value)
  114. {
  115. if (string.IsNullOrEmpty(addr)) return;
  116. var result = Read<ushort>(addr);
  117. result = (ushort)(value ? result | (1 << bitindex) : result & ~(1 << bitindex));
  118. Write(addr, Unsafe.As<ushort, short>(ref result));
  119. }
  120. }
  121. }