using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FLY.Modbus { /// <summary> /// PLC寄存器 与 C# 类型数据 转换, 不含bool /// </summary> public class RegTypeConverter { /// <summary> /// PLC寄存器 或线圈 转 C# 类型数据 /// </summary> /// <param name="plc_value">PLC 寄存器数据 ushort[] 或 bool </param> /// <param name="type">PLC 数据类型</param> /// <param name="scale">PLC数据放大倍数</param> /// <returns></returns> public static object ToObject(object plc_value, REG_TYPE type, double scale) { if(type == REG_TYPE.BOOL) { var v = (bool)plc_value; if (scale < 0) return !v; else return v; } ushort[] data = (ushort[])plc_value; switch (type) { //case REG_TYPE.BOOL: // { // return data[0] != 0 ? true : false; // } case REG_TYPE.INT16: { float v = (Int16)data[0]; v = (float)(v * scale); return v; } case REG_TYPE.UINT16: { float v = (UInt16)data[0]; v = (float)(v * scale); return v; } case REG_TYPE.UINT32: { float v = (UInt32)(data[0] | (data[1] << 16)); v = (float)(v * scale); return v; } case REG_TYPE.INT32: { float v = (Int32)(data[0] | (data[1] << 16)); v = (float)(v * scale); return v; } case REG_TYPE.FLOAT: { byte[] dat = new byte[] { (byte)data[0], (byte)(data[0] >> 8), (byte)data[1], (byte)(data[1] >> 8) }; float v = BitConverter.ToSingle(dat, 0); if ((v > 1000000) || (v < -1000000)) v = 0; v = (float)(v * scale); return v; } default: { throw new Exception("ToObject type=" + type + "不支持的类型"); } } } /// <summary> /// C# 类型数据 转 PLC寄存器 或线圈 /// </summary> /// <param name="value">C#中数值 只能是 float or bool</param> /// <param name="type">PLC 数据类型</param> /// <param name="scale">PLC数据放大倍数</param> /// <returns>ushort[] or bool </returns> public static object ToRegs(object value, REG_TYPE type, double scale) { if (type == REG_TYPE.BOOL) { bool v = (bool)value; if (scale < 0) return !v; else return v; } byte[] bs; float f = (float)value; f = (float)(f / scale); switch (type) { case REG_TYPE.INT16: { short v = (short)f; return new ushort[] { (ushort)v }; } case REG_TYPE.UINT16: { ushort v = (ushort)f; return new ushort[] { v }; } case REG_TYPE.FLOAT: { float v = (float)f; bs = BitConverter.GetBytes(v); return new ushort[] { (ushort)((bs[1] << 8) | bs[0]), (ushort)((bs[3] << 8) | bs[2]) }; } case REG_TYPE.INT32: { Int32 v = (Int32)f; bs = BitConverter.GetBytes(v); return new ushort[] { (ushort)((bs[1] << 8) | bs[0]), (ushort)((bs[3] << 8) | bs[2]) }; } case REG_TYPE.UINT32: { UInt32 v = (UInt32)f; bs = BitConverter.GetBytes(v); return new ushort[] { (ushort)((bs[1] << 8) | bs[0]), (ushort)((bs[3] << 8) | bs[2]) }; } default: { throw new Exception("ToObject type=" + type + "不支持的类型"); } } return null; } } /// <summary> /// C# 类型枚举 /// </summary> public enum REG_TYPE { /// <summary> /// 出错 /// </summary> Unknown = 0, /// <summary> /// float /// </summary> FLOAT = 1, /// <summary> /// uint16 /// </summary> UINT16 = 2, /// <summary> /// int16 /// </summary> INT16 = 3, /// <summary> /// uint32 /// </summary> UINT32 = 4, /// <summary> /// int32 /// </summary> INT32 = 5, /// <summary> /// bool /// </summary> BOOL = 6, } }