123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- using NModbus;
- using System.Diagnostics.CodeAnalysis;
- using System.Runtime.CompilerServices;
- namespace PLCControl.ModBus
- {
- public class Control : IPLCControl
- {
- private object locker = new object();
- private System.Net.Sockets.TcpClient? tcpClient;
- private IModbusMaster? modbus;
- [AllowNull]
- public Action<bool> ConnectionChanged { get; set; }
- public bool IsConnected => tcpClient == null ? false : tcpClient.Connected;
- [AllowNull]
- public string IPAddress { get; set; } = "127.0.0.1";
- public int Port { get; set; } = 502;
- public byte SlaveID { get; set; } = 1;
- private bool _isConnected;
- private void InvokeConnectionChanged(bool isConnected)
- {
- lock (locker)
- {
- if (_isConnected == isConnected) return;
- ConnectionChanged?.Invoke(isConnected);
- _isConnected = isConnected;
- }
- }
- public bool Connect()
- {
- try
- {
- var modbusFactory = new NModbus.ModbusFactory();
- tcpClient = new System.Net.Sockets.TcpClient();
- var result = tcpClient.ConnectAsync(IPAddress, Port).Wait(500);
- if (!result) return false;
- modbus = modbusFactory.CreateMaster(tcpClient);
- InvokeConnectionChanged(true);
- return true;
- }
- catch (Exception ex)
- {
- return false;
- }
- }
- public void Disconnect()
- {
- try
- {
- tcpClient?.Close();
- InvokeConnectionChanged(false);
- }
- catch (Exception ex)
- {
- }
- }
- public bool ReadBit(ushort address, byte bitindex)
- {
- var result = Read(address, 2)[0];
- return (result & (1 << bitindex)) != 0;
- }
- private ushort[] Read(ushort startaddr, byte addrnum)
- {
- try
- {
- if (modbus == null) return new ushort[addrnum / 2];
- return modbus.ReadHoldingRegisters(SlaveID, (ushort)(startaddr +(addrnum>>2) - 1), (ushort)(addrnum >> 1));
- }
- catch
- {
- Disconnect();
- }
- return new ushort[addrnum / 2];
- }
- public void ReadDatas<T>(ushort startAddress, ref T value, byte bytecount) where T : unmanaged
- {
- if (modbus == null) return;
- try
- {
- var result = modbus.ReadHoldingRegisters(SlaveID, (ushort)(startAddress + (bytecount >>2) -1), (ushort)(bytecount >> 1)).Reverse().ToArray();
- Unsafe.CopyBlock(ref Unsafe.As<T, byte>(ref value), ref Unsafe.As<ushort, byte>(ref result[0]), (uint)bytecount);
- }
- catch
- {
- Disconnect();
- }
- }
- public void WriteDatas<T>(ushort address,ref T data,byte bytecount) where T: unmanaged
- {
- if (modbus == null) return;
- try
- {
- ushort[] datas = new ushort[bytecount / 2];
- Unsafe.CopyBlock(ref Unsafe.As<ushort, byte>(ref datas[0]), ref Unsafe.As<T, byte>(ref data), (uint)datas.Length * 2);
- modbus.WriteMultipleRegisters(SlaveID, (ushort)(address + (bytecount >>1) -1 - 1), datas);
- }
- catch
- {
- Disconnect();
- }
- }
- public short ReadInt16(ushort address)
- {
- return Unsafe.As<ushort, short>(ref Read(address, 2)[0]);
- }
- public void WriteBit(ushort address, byte bitindex, bool value)
- {
- var result = Read(address, 2)[0];
- result = (ushort)(value ? result | (1 << bitindex) : result & ~(1 << bitindex));
- WriteInt16(address, Unsafe.As<ushort, short>(ref result));
- }
- public void WriteInt16(ushort address, short value)
- {
- if (modbus == null) return;
- try
- {
- modbus.WriteSingleRegister(SlaveID, (ushort)(address - 1), Unsafe.As<short, ushort>(ref value));
- }
- catch
- {
- Disconnect();
- }
- }
- }
- }
|