/// <summary> /// 启动串口通讯 /// /// PLC 的 D8120 设置为 0x0897,则表示 19200,7,1,E /// PLC 的 D8120 设置为 0x0C8E,则表示 9600,7,1,E /// </summary> /// <returns>如果成功返回 true,否则返回 false</returns> public bool Start(int portNo) { string cmd; FxCommandResponse res; bool bOpen = false; if (false == bDefaultBaudRate) { bOpen = Start(portNo, "115200,E,7,1"); nBaudrate = 115200; if (bOpen) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("X0", ControllerTypeConst.ctPLC_Fx), 2); res = Send(0, cmd); if (res.ResultCode != ResultCodeConst.rcSuccess) { bOpen = false; _SerialPort.ClosePort(); } } } if (false == bOpen) { bOpen = Start(portNo, "9600,E,7,1"); nBaudrate = 9600; if (bOpen) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("X0", ControllerTypeConst.ctPLC_Fx), 2); res = Send(0, cmd); if (res.ResultCode != ResultCodeConst.rcSuccess) { bOpen = false; _SerialPort.ClosePort(); nBaudrate = 0; } } } return(bOpen); //return Start(portNo, "9600,E,7,1"); }
/// <summary> /// 将给定节点的“输出值”写入外部设备或PLC /// </summary> /// <param name="sourceList">节点列表</param> /// <param name="timeout">最大超时值</param> /// <returns>返回成功写的点数</returns> public override int WritePoints(List <AcquirePoint> outputList, TimeSpan timeout) { int ct = 0; string cmd; FxCommandResponse res; foreach (AcquirePoint ap in outputList) { if (ap.ControllerObject.ControllerId != base.ControllerId) { continue; } if (ap.AV.Output.IsNull) { continue; } if (ap.AV.Output.B) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOn, new FxAddress(ap.ChannelNoAlias, FxAddressLayoutType.AddressLayoutByte)); } else { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOff, new FxAddress(ap.ChannelNoAlias, FxAddressLayoutType.AddressLayoutByte)); } res = Send(0, cmd); #if DEBUG //Logger.Instance.WriteLine("FxPLC输出: {0} ", res.ToString()); #endif ct++; } return(ct); }
/// <summary> /// 读取设备所有IO点数据,并返回这些点的数据值 /// </summary> public override List <AcquireRawValue> ReadAllPoints(List <AcquirePoint> sourceAPList, TimeSpan timeout) { if (_SerialPort == null || !_SerialPort.IsOpen) { return(null); } List <AcquireRawValue> vlist = new List <AcquireRawValue>(); if (sourceAPList != null) { sourceAPList.ForEach(o => { if (o.ControllerObject.ControllerId == this.ControllerId) { vlist.Add(new AcquireRawValue(o.Id, o.ControllerObject, o.ChannelNoAlias)); } }); } else { //for(int result = 0; result < 127; result++) { // vlist.Add(new AcquireRawValue(0, 0, string.Format("X{0}", result))); // vlist.Add(new AcquireRawValue(0, 0, string.Format("Y{0}", result))); //} } string cmd; FxCommandResponse res; // 读取 X0..X177,一次性读取所有X cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("X0", ControllerTypeConst.ctPLC_Fx), 16); res = Send(0, cmd); //Debug.Print("X0--X177 = {0}", res.ToString()); // 根据通道号别名,例如"X001","Y177","Mxxx"等内容更新 if (res.ResultCode == ResultCodeConst.rcSuccess) { foreach (AcquireRawValue o in vlist) { if (o.PLCAddr != null && o.PLCAddr.AddressType == FxAddressType.X) { int byteIndex = (int)(o.PLCAddr.TagOffset / 8); int byteOff = (int)(o.PLCAddr.TagOffset % 8); if (byteIndex >= 0 && byteIndex < res.ResponseValue.Count) { o.Value = new ValueStruct(((res.ResponseValue[byteIndex] >> byteOff) & 0x01) == 0x01); //Debug.Print("X{0} <== {1}", Convert.ToString(o.PLCAddr.TagOffset, 8), o.Value); } else { //Debug.Print("X{0} <== {1}", Convert.ToString(o.PLCAddr.TagOffset, 8), o.Value); } } } } else { Debug.Print("{0}\t{1} 读取失败(X001-X177)", DateTime.Now, this.ToString()); } // 读取 Y0..Y177,一次性读取所有Y cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("Y0", ControllerTypeConst.ctPLC_Fx), 16); res = Send(0, cmd); //Debug.Print("Y0--Y177 = {0}", res.ToString()); // 根据通道号别名,例如"Y177"等内容更新 if (res.ResultCode == ResultCodeConst.rcSuccess) { foreach (AcquireRawValue o in vlist) { if (o.PLCAddr != null && o.PLCAddr.AddressType == FxAddressType.Y) { int byteIndex = (int)(o.PLCAddr.TagOffset / 8); int byteOff = (int)(o.PLCAddr.TagOffset % 8); if (byteIndex >= 0 && byteIndex < res.ResponseValue.Count) { o.Value = new ValueStruct(((res.ResponseValue[byteIndex] >> byteOff) & 0x01) == 0x01); } else { //Debug.Print("Y{0} <== {1}", Convert.ToString(o.PLCAddr.TagOffset, 8), o.Value); } } } } else { Debug.Print("{0}\t{1} 读取失败(Y001-Y177)", DateTime.Now, this.ToString()); } // 一次性读取 M0..M499 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("M0", ControllerTypeConst.ctPLC_Fx), 64); res = Send(0, cmd); //Debug.Print("M0--M499 = {0}", res.ToString()); // 根据通道号别名,例如"M19"等内容更新 if (res.ResultCode == ResultCodeConst.rcSuccess) { foreach (AcquireRawValue o in vlist) { if (o.PLCAddr != null && o.PLCAddr.AddressType == FxAddressType.M && o.PLCAddr.TagOffset < 1000) { int byteIndex = (int)(o.PLCAddr.TagOffset / 8); int byteOff = (int)(o.PLCAddr.TagOffset % 8); if (byteIndex >= 0 && byteIndex < res.ResponseValue.Count) { o.Value = new ValueStruct(((res.ResponseValue[byteIndex] >> byteOff) & 0x01) == 0x01); } else { //Debug.Print("M{0} <== {1}", Convert.ToString(o.PLCAddr.TagOffset, 8), o.Value); } } } } else { Debug.Print("{0}\t{1} 读取失败(M001-M499)", DateTime.Now, this.ToString()); } #region 一次性读取 M1000-1999 ---- 目前不读取这个范围的 M 点 if (false) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("M1000", ControllerTypeConst.ctPLC_Fx), 32); res = Send(0, cmd); //Debug.Print("M1000--M1127 = {0}", res.ToString()); // 根据通道号别名,例如"M1099"等内容更新 if (res.ResultCode == ResultCodeConst.rcSuccess) { foreach (AcquireRawValue o in vlist) { if (o.PLCAddr != null && o.PLCAddr.AddressType == FxAddressType.M && o.PLCAddr.TagOffset >= 1000) { int byteIndex = (int)((o.PLCAddr.TagOffset - 1000) / 8); int byteOff = (int)((o.PLCAddr.TagOffset - 1000) % 8); if (byteIndex >= 0 && byteIndex < res.ResponseValue.Count) { o.Value = new ValueStruct(((res.ResponseValue[byteIndex] >> byteOff) & 0x01) == 0x01); } else { //Debug.Print("M{0} <== {1}", o.PLCAddr.TagOffset, o.Value); } } } } } #endregion // 读取其他内容:C/D/T foreach (AcquireRawValue o in vlist) { if (o.PLCAddr != null) { switch (o.PLCAddr.AddressType) { case FxAddressType.C: cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, o.PLCAddr, 2); break; case FxAddressType.D: cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, o.PLCAddr, 2); break; case FxAddressType.T: cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, o.PLCAddr, 2); break; case FxAddressType.S: cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, o.PLCAddr, 2); break; default: continue; } res = Send(0, cmd); if (res.ResultCode == ResultCodeConst.rcSuccess) { o.Value = new ValueStruct((int)res.ResponseValue[0]); //Debug.Print("{0} <== {1}", o.PLCAddr.ToString(), o.Value); } else { //Debug.Print("{0} <== {1}. Error", o.PLCAddr.ToString(), o.Value); } } } return(vlist); }
public FxCommandResponse Send(short channelNo, byte[] dataBuff, int dataSize, ICellDataType responseDataType) { byte[] resultBuff = null; FxCommandResponse result = new FxCommandResponse(ResultCodeConst.rcNotSettting, null, responseDataType); if (!_SerialPort.IsOpen) { return(result); } if (_SerialPort.BytesToWrite > 0) { //MyApp._LogWriter.WriteLine("准备写串口前,发现写缓冲中尚存{0}字节没有发出!", _SerialPort.BytesToWrite); } int reReadTimes = 0; // 重读次数 _SerialPort.Write(dataBuff); System.Threading.Thread.Sleep(1); _RingBuffer.Clear(); // 读取数据,直到得到完整报文或超时 reReadTimes = 0; while (reReadTimes < MAX_RETRY_READ_COUNT) // 连续超时指定次数,则不再等待 { byte[] data = new byte[256]; int len = _SerialPort.Read(data, 0, data.Length); if (len > 0) { reReadTimes = 0; _RingBuffer.Append(data, 0, len); resultBuff = _RingBuffer.PickPackage(); if (resultBuff != null) { break; } } else { reReadTimes++; System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(1)); } } // 处理收到的数据 if (resultBuff == null) { result.ResultCode = ResultCodeConst.rcFailt; Debug.Print("发送命令超时候仍没有收到FX PLC的合法响应."); } else if (resultBuff.Length == 1) { result.ResultCode = (ResultCodeConst)resultBuff[0]; } else { result.ResultCode = ResultCodeConst.rcSuccess; List <int> valuelist; FxCommandHelper.ParseSmart(resultBuff, 0, responseDataType, out valuelist); result.SetResponseValue(valuelist); result.SetRawData(resultBuff); } return(result); }
public void Test_All() { string cmd; FxCommandResponse res; Random _Random = new Random(); //// 置位 //response = FxCommandHelper.Make(FxCommandConst.FxCmdForceOn, new FxAddress("S1")); //res = _FxSerial.SendCmdToQnCPU(0, response); //// 复位 //response = FxCommandHelper.Make(FxCommandConst.FxCmdForceOff, new FxAddress("S1")); //res = _FxSerial.SendCmdToQnCPU(0, response); #region 读取所有 X/Y/M/ ,并计算其耗时 Stopwatch sw = new Stopwatch(); sw.Start(); for (int ct = 0; ct < 10; ct++) { // 一次性读取多个字节的 X,例如 16 字节::必须采用 AddressLayoutBin 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("X0", ControllerTypeConst.ctPLC_Fx), 16); res = _FxSerial.Send(0, cmd); //Debug.WriteLine(string.Format("成批读X0..X177 \t{0}", res.ToString())); //System.Threading.Thread.Sleep(1000); // 一次性读取多个字节的 Y,例如 16 字节::必须采用 AddressLayoutBin 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("Y0", ControllerTypeConst.ctPLC_Fx), 16); res = _FxSerial.Send(0, cmd); //Debug.WriteLine(string.Format("成批读Y0..Y177 \t{0}", res.ToString())); //System.Threading.Thread.Sleep(1000); // 一次性读取多个字节的 M,每次读取128个单元::必须采用 AddressLayoutBin 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("M0", ControllerTypeConst.ctPLC_Fx), 128); res = _FxSerial.Send(0, cmd); //Debug.WriteLine(string.Format("成批读M{0}..M{1} \t{2}", result, result + 128, res.ToString())); Debug.Print("=====================> {0}", sw.ElapsedMilliseconds); } System.Threading.Thread.Sleep(1000); #endregion #region 针对 X/Y 的设置、读取 // 置位与复位:必须采用 AddressLayoutByte 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOn, new FxAddress("Y20", FxAddressLayoutType.AddressLayoutByte)); res = _FxSerial.Send(0, cmd); Debug.WriteLine(res.ToString()); System.Threading.Thread.Sleep(1000); cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOff, new FxAddress("Y20", FxAddressLayoutType.AddressLayoutByte)); res = _FxSerial.Send(0, cmd); Debug.WriteLine(res.ToString()); System.Threading.Thread.Sleep(1000); // 针对 Y001..Y177 设置与读取 for (int i = 0; i < 128; i++) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOff, new FxAddress(string.Format("Y{0}", Convert.ToString(i, 8)), FxAddressLayoutType.AddressLayoutByte)); res = _FxSerial.Send(0, cmd); } // 针对 Y001..Y077 设置与读取 for (int i = 0; i < 128; i++) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOn, new FxAddress(string.Format("Y{0}", Convert.ToString(i, 8)), FxAddressLayoutType.AddressLayoutByte)); res = _FxSerial.Send(0, cmd); //Debug.WriteLine(res.ToString()); System.Threading.Thread.Sleep(100); if ((i - 8) >= 0) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOff, new FxAddress(string.Format("Y{0}", Convert.ToString(i - 8, 8)), FxAddressLayoutType.AddressLayoutByte)); res = _FxSerial.Send(0, cmd); Debug.WriteLine(string.Format("Y{0}\t{1}", Convert.ToString(i, 8), res.ToString())); } //System.Threading.Thread.Sleep(1000); } // 一次性读取多个字节的 X,例如 16 字节::必须采用 AddressLayoutBin 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("X0", ControllerTypeConst.ctPLC_Fx), 16); res = _FxSerial.Send(0, cmd); Debug.WriteLine(string.Format("成批读X0..X177 \t{0}", res.ToString())); System.Threading.Thread.Sleep(1000); // 一次性读取多个字节的 Y,例如 16 字节::必须采用 AddressLayoutBin 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("Y0", ControllerTypeConst.ctPLC_Fx), 16); res = _FxSerial.Send(0, cmd); Debug.WriteLine(string.Format("成批读Y0..Y177 \t{0}", res.ToString())); System.Threading.Thread.Sleep(1000); #endregion #region 针对 M 类型的读写 // 针对 M001..M077 设置与读取 for (int i = 0; i < 64; i++) { cmd = FxCommandHelper.Make(FxCommandConst.FxCmdForceOn, new FxAddress(string.Format("M{0}", i), FxAddressLayoutType.AddressLayoutByte)); res = _FxSerial.Send(0, cmd); Debug.WriteLine(res.ToString()); //response = FxCommandHelper.Make(FxCommandConst.FxCmdForceOff, // new FxAddress(string.Format("M{0}", Convert.ToString(result, 8)), FxAddressLayoutType.AddressLayoutByte)); //res = _FxSerial.SendCmdToQnCPU(0, response); //Debug.WriteLine(res.ToString()); //System.Threading.Thread.Sleep(100); } // 一次性读取多个字节的 M,例如 16 字节::必须采用 AddressLayoutBin 方式 cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("M0", ControllerTypeConst.ctPLC_Fx), 64); res = _FxSerial.Send(0, cmd); Debug.WriteLine(string.Format("成批读M0..M77 \t{0}", res.ToString())); System.Threading.Thread.Sleep(1000); #endregion #region 循环设置与读取 Dxxx 的数据 for (int i = 0; i < 1; i++) { List <uint> lst = new List <uint>() { (uint)i }; for (int k = 0; k < 10; k++) { lst.Add((uint)_Random.Next()); } cmd = FxCommandHelper.Make <UInt32DataType>(FxCommandConst.FxCmdWrite, new FxAddress("D1", ControllerTypeConst.ctPLC_Fx), lst); res = _FxSerial.Send(0, cmd); Debug.WriteLine(res.ToString()); cmd = FxCommandHelper.Make(FxCommandConst.FxCmdRead, new FxAddress("D1", ControllerTypeConst.ctPLC_Fx), lst.Count * 4); res = _FxSerial.Send(0, cmd, UInt32DataType.Default); Debug.WriteLine(res.ToString()); if (res.ResponseValue != null && res.ResponseValue.Count > 0) { Debug.WriteLine(""); Debug.Write(DateTime.Now.ToString()); Debug.Write("\t"); for (int j = 0; j < res.ResponseValue.Count; j++) { Debug.Write(res.ResponseValue[j]); Debug.Write(','); } } else { Debug.WriteLine("没有收到FX PLC响应。"); } } #endregion Debug.Assert(false, "运行暂停!!!"); }
public FxCommandResponse Send(short channelNo, byte[] dataBuff, int dataSize, ICellDataType responseDataType) { byte[] resultBuff = null; FxCommandResponse result = new FxCommandResponse(ResultCodeConst.rcNotSettting, null, responseDataType); if (!_SerialPort.IsOpen) { return(result); } if (_SerialPort.BytesToWrite > 0) { //MyApp._LogWriter.WriteLine("��д����ǰ������д�������д�{0}�ֽ�û�з�����", _SerialPort.BytesToWrite); } int reReadTimes = 0; // �ض����� _SerialPort.Write(dataBuff); System.Threading.Thread.Sleep(1); _RingBuffer.Clear(); // ��ȡ���ݣ�ֱ���õ�́E����Ļ�ʱ reReadTimes = 0; while (reReadTimes < MAX_RETRY_READ_COUNT) { // ������ʱָ�����������ٵȴ� byte[] data = new byte[256]; int len = _SerialPort.Read(data, 0, data.Length); if (len > 0) { reReadTimes = 0; _RingBuffer.Append(data, 0, len); resultBuff = _RingBuffer.PickPackage(); if (resultBuff != null) { break; } } else { reReadTimes++; System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(1)); } } // �����յ������� if (resultBuff == null) { result.ResultCode = ResultCodeConst.rcFailt; Debug.Print("����ÁE�Ϭʱ����û���յ�FX PLC�ĺϷ�ρE�."); } else if (resultBuff.Length == 1) { result.ResultCode = (ResultCodeConst)resultBuff[0]; } else { result.ResultCode = ResultCodeConst.rcSuccess; List <int> valuelist; FxCommandHelper.ParseSmart(resultBuff, 0, responseDataType, out valuelist); result.SetResponseValue(valuelist); result.SetRawData(resultBuff); } return(result); }