Modbus.cs 3.9 KB

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