| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- using Modbus.Data;
- using Modbus.Device;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using TeamAAS_VP.Models;
- using TeamAAS_VP;
- namespace TeamAAS_VP.Core
- {
- /// <summary>
- /// 后台Modbus TCP 通讯
- /// </summary>
- public class BgModbusTcpCommunicate
- {
- public TcpListener TcpListener { get;private set; }
- public ModbusSlave Slave { get; private set; }
- BgModbusTcp Config;
- public string IP { get => Config.IP; }
- public int Port { get => Config.Port; }
- public byte SlaveID { get => Config.SlaveID; }
- public bool IsEnabled { get => Config.IsEnabled; }
- public BgModbusTcpCommunicate(BgModbusTcp _Config)
- {
- Config = _Config;
- if (!Config.IsEnabled)
- {
- return;
- }
- if (TcpListener == null)
- {
- TcpListener = new TcpListener(IPAddress.Parse(Config.IP), Config.Port);
- TcpListener.Start();
- }
- Slave = ModbusTcpSlave.CreateTcp(Config.SlaveID, TcpListener);
- Slave.DataStore = Modbus.Data.DataStoreFactory.CreateDefaultDataStore();
- Slave.ModbusSlaveRequestReceived += Slave_ModbusSlaveRequestReceived;
- Slave.DataStore.DataStoreWrittenTo += DataStore_DataStoreWrittenTo;
- Slave.DataStore.DataStoreReadFrom += DataStore_DataStoreReadFrom;
-
- }
- public void Listen()
- {
- Slave.Listen();
- }
- private void Slave_ModbusSlaveRequestReceived(object sender, ModbusSlaveRequestEventArgs e)
- {
- try
- {
- switch (e.Message.FunctionCode)
- {
- case 2:
- break;
- case 4:
- break;
- default:
- break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"后台Modbus tcp读取{e.Message.FunctionCode}", ex);
- }
- }
- /// <summary>
- /// 当通过Modbus命令读取数据存储时发生
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void DataStore_DataStoreReadFrom(object sender, Modbus.Data.DataStoreEventArgs e)
- {
- try
- {
- switch (e.ModbusDataType)
- {
- case ModbusDataType.HoldingRegister:
- break;
- case ModbusDataType.InputRegister:
- break;
- case ModbusDataType.Coil:
- break;
- case ModbusDataType.Input:
- break;
- default:
- break;
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"后台Modbus tcp读取{e.ModbusDataType.ToString()}", ex);
- }
- }
- /// <summary>
- /// 当slave 收到 master 的命令 写入 DO 值或 AO 值到 DataStore 时触发事件。
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void DataStore_DataStoreWrittenTo(object sender, Modbus.Data.DataStoreEventArgs e)
- {
- switch (e.ModbusDataType)
- {
- case ModbusDataType.Coil: //code 5 //写入单个线圈
- //ModbusDataCollection<bool> discretes = slave.DataStore.CoilDiscretes; //获取线圈离散
- break;
- case ModbusDataType.HoldingRegister: //code 15
- //ModbusDataCollection<ushort> holdingRegisters = slave.DataStore.HoldingRegisters; //获取保存寄存器。
- break;
- }
- }
- /// <summary>
- /// 将接收到的ushort[]转换为float类型
- /// </summary>
- /// <param name="val"></param>
- /// <returns></returns>
- public float GetFloatFormUshortArray(ushort[] val)
- {
- if (val != null && val.Length == 2)
- {
- List<byte> result = new List<byte>();
- result.AddRange(BitConverter.GetBytes(val[0]));
- result.AddRange(BitConverter.GetBytes(val[1]));
- return BitConverter.ToSingle(result.ToArray(), 0);
- }
- else
- {
- return 0.0f;
- }
- }
- /// <summary>
- /// 将float类型分解成两个ushort类型
- /// </summary>
- /// <param name="value"></param>
- /// <returns></returns>
- public ushort[] GetUshortArrayFormFloat(float value)
- {
- ushort lowOrderValue = BitConverter.ToUInt16(BitConverter.GetBytes(value), 2);
- ushort highOrderValue = BitConverter.ToUInt16(BitConverter.GetBytes(value), 0);
- return new ushort[2] { lowOrderValue, highOrderValue };
- }
- /// <summary>
- /// 获取输入位状态
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public bool SW(int index)
- {
- try
- {
- return Slave.DataStore.CoilDiscretes[index];
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"获取输入位状态时出错", ex);
- return false;
- }
- }
- /// <summary>
- /// 获取输出位状态
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public bool Oport(int index)
- {
- try
- {
- return Slave.DataStore.InputDiscretes[index];
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"获取输出位状态时出错", ex);
- return false;
- }
- }
- /// <summary>
- /// 输出位操作
- /// </summary>
- /// <param name="index">地址</param>
- /// <param name="state">状态</param>
- /// <param name="time">脉冲时间</param>
- /// <param name="_async">是否异步执行</param>
- public void BitOperate(int index, bool state)
- {
- try
- {
- Slave.DataStore.InputDiscretes[index] = state;
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"输出位操作时出错", ex);
- }
- }
- /// <summary>
- /// 输出字操作
- /// </summary>
- /// <param name="index">字编号</param>
- /// <param name="value">输出值</param>
- /// <param name="time">脉冲时长</param>
- /// <param name="_async">是否异步</param>
- public void OutW(int index, ushort value)
- {
- try
- {
- Slave.DataStore.InputRegisters[index] = value;
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"输出字操作时出错", ex);
- }
- }
- /// <summary>
- /// 获取输出字值
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public ushort ReadOutW(int index)
- {
- try
- {
- return Slave.DataStore.InputRegisters[index];
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"获取输出字值时出错", ex);
- return 0;
- }
- }
- /// <summary>
- /// 获取输入字值
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public ushort InW(int index)
- {
- try
- {
- return Slave.DataStore.HoldingRegisters[index];
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"获取输入字值时出错", ex);
- return 0;
- }
- }
- /// <summary>
- /// 输出浮点数
- /// </summary>
- /// <param name="index">字编号</param>
- /// <param name="value">值</param>
- /// <param name="time">脉冲时长</param>
- /// <param name="_async">是否异步</param>
- public void OutReal(int index, float value)
- {
- try
- {
- ushort[] data = GetUshortArrayFormFloat(value);
- Slave.DataStore.InputRegisters[index] = data[0];
- Slave.DataStore.InputRegisters[index + 1] = data[1];
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"输出浮点数时出错", ex);
- }
- }
- /// <summary>
- /// 获取输出浮点数
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public float ReadOutReal(int index)
- {
- try
- {
- return GetFloatFormUshortArray(new ushort[] { Slave.DataStore.InputRegisters[index], Slave.DataStore.InputRegisters[index + 1] });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"获取输出浮点数时出错", ex);
- return 0.0f;
- }
- }
- /// <summary>
- /// 获取输入浮点数
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public float InReal(int index)
- {
- try
- {
- return GetFloatFormUshortArray(new ushort[] { Slave.DataStore.HoldingRegisters[index + 1], Slave.DataStore.HoldingRegisters[index + 0] });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError($"获取输入浮点数时出错", ex);
- return 0.0f;
- }
- }
- }
- }
|