运用c#开发了一个小程序,不会,一边搜索,一边Ctrl+C
可以控制车间所有的PLC,通过左侧树结构选择不同的区域进行一起HIP断气开气,断控制电压K0
通过xml配置需要控制的PLC与变量
程序对现场状态实时监控,如果PLC断开会自动重连
对XML文件进行解析,每一个PLC都会开启一个线程。
#region 通用数据解析及连接
//通用数据解析及连接
privatevoidConnectAndComm() {if (CommonMethods.SiemensList.Count > 0) {foreach (var item in CommonMethods.SiemensList) {if (item.IsActive) { Task.Run(() => GetSiemensValue(item)); } } }
}
///<summary>/// 西门子通用数据读取及解析///</summary>///<param name="item"></param>privatevoidGetSiemensValue(NodeSiemens nodesiemens) {while (IsRunMode) {if (nodesiemens.IsConnected) {//读取
//开始计时 nodesiemens.sw.Restart();
if (!nodesiemens.IsUseMultiRead) {foreach (var gp in nodesiemens.DeviceGroupList) {if (gp.IsActive) {//批量读取字节数组byte[] res = nodesiemens.siemens.ReadBytes(GetStoreTypeFromStoreArea(gp.StoreArea), gp.DBNo, gp.Start, gp.Length);
if(res != null) { num += 1; }
//读取成功if (res != null && res.Length == gp.Length) { num = 0;//数据解析
//西门子PLC //布尔类型 DB1.DBX0.0//字节类型 DB1.DBB0//int uint类型 DB1.DBW0//dint dword DB1.DBD0//float DB1.DBD0//long ulong double DB1.DBR0//string char[] string DB1.DBS0.10 DB1.DBS0|10
foreach (varvarin gp.varList) {if (VerifySiemensAddress(var.Start, outint start, outint offset)) {//假设组从10 开始读10个 12 start -= gp.Start;
switch (var.VarType) {case DataType.Bool:var.Value = BitLib.GetBitFromByteArray(res, start, offset);break;case DataType.Byte:var.Value = ByteLib.GetByteArray(res, start);break;case DataType.Short:var.Value = ShortLib.GetShortFromByteArray(res, start);break;case DataType.UShort:var.Value = UShortLib.GetUShortFromByteArray(res, start);break;case DataType.Int:var.Value = IntLib.GetIntFromByteArray(res, start);break;case DataType.UInt:var.Value = UIntLib.GetUIntFromByteArray(res, start);break;case DataType.Float:var.Value = FloatLib.GetFloatFromByteArray(res, start);break;case DataType.Double:var.Value = DoubleLib.GetDoubleFromByteArray(res, start);break;case DataType.Long:var.Value = LongLib.GetLongFromByteArray(res, start);break;case DataType.ULong:var.Value = ULongLib.GetULongFromByteArray(res, start);break;case DataType.String://是String还是Charif (var.Start.Contains('.')) {var.Value = StringLib.GetSiemensStringFromByteArray(res, start, offset); }else {var.Value = StringLib.GetStringFromByteArray(res, start, offset, Encoding.GetEncoding("GBK")); }break;default:break; }
//数据转换var.Value = MigrationLib.GetMigrationValue(var.Value, var.Scale, var.Offset);
if (CommonMethods.CurrentSiemensValue.ContainsKey(var.Name)) { CommonMethods.CurrentSiemensValue[var.Name] = var.Value; }else { CommonMethods.CurrentSiemensValue.Add(var.Name, var.Value); } } } }//读取失败else {if(num == 10) { nodesiemens.IsConnected = false; } } } } }//读取失败else { nodesiemens.IsConnected = false;//Isconnected.Remove(nodesiemens.IpAddress); } } } } } }else {//连接
if (!nodesiemens.FirstConnect) { Thread.Sleep(nodesiemens.ConnectTimeOut);
//断开连接 nodesiemens.siemens.DisConnect(); }
//把配置的赋值给通信对象的属性 nodesiemens.siemens.ConnectTimeOut = nodesiemens.ConnectTimeOut;
nodesiemens.IsConnected = nodesiemens.siemens.Connect(nodesiemens.IpAddress, GetCPUTypeFromPLCType(nodesiemens.PlcType), nodesiemens.Rack, nodesiemens.Slot);//bool isc = Isconnected.ContainsKey(nodesiemens.IpAddress); nodesiemens.FirstConnect = false;
} } }private CPU_Type GetCPUTypeFromPLCType(SiemensPLCType type) {switch (type) {case SiemensPLCType.S7200:return CPU_Type.S7200;case SiemensPLCType.S7200Smart:return CPU_Type.S7200SMART;case SiemensPLCType.S7300:return CPU_Type.S7300;case SiemensPLCType.S7400:return CPU_Type.S7400;case SiemensPLCType.S71200:return CPU_Type.S71200;case SiemensPLCType.S71500:return CPU_Type.S71500;default:return CPU_Type.S71200; } }
private StoreType GetStoreTypeFromStoreArea(SiemensStoreArea area) {switch (area) {case SiemensStoreArea.M存储区:return StoreType.Marker;case SiemensStoreArea.I存储区:return StoreType.Input;case SiemensStoreArea.Q存储区:return StoreType.Output;case SiemensStoreArea.DB存储区:return StoreType.DataBlock;case SiemensStoreArea.T存储区:return StoreType.Timer;case SiemensStoreArea.C存储区:return StoreType.Counter;default:return StoreType.DataBlock; } }
///<summary>/// 验证西门子PLC的地址///</summary>///<param name="address"></param>///<param name="start"></param>///<param name="offset"></param>///<returns></returns>privateboolVerifySiemensAddress(string address, outint start, outint offset) {if (address.Contains('.')) {string[] result = address.Split('.');
//E.10 1.E 0.10if (result.Length == 2) {bool val = true; val &= int.TryParse(result[0], out start); val &= int.TryParse(result[1], out offset);return val; }//0.10.10else { start = 0; offset = 0;returnfalse; } }elseif (address.Contains('|')) {string[] result = address.Split('|');
//E.10 1.E 0.10if (result.Length == 2) {bool val = true; val &= int.TryParse(result[0], out start); val &= int.TryParse(result[1], out offset);return val; }//0.10.10else { start = 0; offset = 0;returnfalse; } }else { offset = 0;returnint.TryParse(address, out start); } }
|