Control.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. 
  2. using NModbus;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Runtime.CompilerServices;
  5. namespace PLCControl.ModBus
  6. {
  7. public class Control : IPLCControl
  8. {
  9. private object locker = new object();
  10. private System.Net.Sockets.TcpClient? tcpClient;
  11. private IModbusMaster? modbus;
  12. [AllowNull]
  13. public Action<bool> ConnectionChanged { get; set; }
  14. public bool IsConnected =>tcpClient==null ? false : tcpClient.Connected;
  15. [AllowNull]
  16. public string IPAddress { get; set; } = "127.0.0.1";
  17. public int Port { get; set; } = 502;
  18. public byte SlaveID { get; set; } = 1;
  19. private bool _isConnected;
  20. private void InvokeConnectionChanged(bool isConnected)
  21. {
  22. lock (locker)
  23. {
  24. if (_isConnected == isConnected) return;
  25. ConnectionChanged?.Invoke(isConnected);
  26. _isConnected = isConnected;
  27. }
  28. }
  29. public bool Connect()
  30. {
  31. try
  32. {
  33. var modbusFactory = new NModbus.ModbusFactory();
  34. tcpClient = new System.Net.Sockets.TcpClient();
  35. var result = tcpClient.ConnectAsync(IPAddress, Port).Wait(500);
  36. if (!result) return false;
  37. modbus = modbusFactory.CreateMaster(tcpClient);
  38. InvokeConnectionChanged(true);
  39. return true;
  40. }
  41. catch (Exception ex)
  42. {
  43. return false;
  44. }
  45. }
  46. public void Disconnect()
  47. {
  48. try
  49. {
  50. tcpClient?.Close();
  51. InvokeConnectionChanged(false);
  52. }
  53. catch (Exception ex)
  54. {
  55. }
  56. }
  57. public bool ReadBit(ushort address, byte bitindex)
  58. {
  59. var result = Read(address, 2)[0];
  60. return (result & (1 << bitindex)) != 0;
  61. }
  62. private ushort[] Read(ushort startaddr, byte addrnum)
  63. {
  64. try
  65. {
  66. if (modbus == null) return new ushort[addrnum / 2];
  67. return modbus.ReadHoldingRegisters(SlaveID, (ushort)(startaddr-1), (ushort)(addrnum>>1));
  68. }
  69. catch
  70. {
  71. Disconnect();
  72. }
  73. return new ushort[addrnum / 2];
  74. }
  75. public void ReadDatas<T>(ushort startAddress, ref T value, byte bytecount) where T : unmanaged
  76. {
  77. if (modbus == null) return;
  78. try
  79. {
  80. var result = modbus.ReadHoldingRegisters(SlaveID, (ushort)(startAddress-1), (ushort)(bytecount >> 1));
  81. Unsafe.CopyBlock(ref Unsafe.As<T, byte>(ref value), ref Unsafe.As<ushort, byte>(ref result[0]), (uint)bytecount);
  82. }
  83. catch
  84. {
  85. Disconnect();
  86. }
  87. }
  88. public short ReadInt16(ushort address)
  89. {
  90. return Unsafe.As<ushort, short>(ref Read(address, 2)[0]);
  91. }
  92. public void WriteBit(ushort address, byte bitindex, bool value)
  93. {
  94. var result = Read(address, 2)[0];
  95. result = (ushort)(value ? result | (1 << bitindex) : result & ~(1 << bitindex));
  96. WriteInt16(address, Unsafe.As<ushort, short>(ref result));
  97. }
  98. public void WriteInt16(ushort address, short value)
  99. {
  100. if (modbus == null) return;
  101. try
  102. {
  103. modbus.WriteSingleRegister(SlaveID, (ushort)(address-1), Unsafe.As<short, ushort>(ref value));
  104. }
  105. catch
  106. {
  107. Disconnect();
  108. }
  109. }
  110. }
  111. }