using System; using System.Collections.Generic; using System.Text; using System.Data; using CommonClassLib; using ICommLayer; using DBFactory; namespace SimensCP5611 { /// /// 通过西门子的CP5611卡实现Profibus总线方式的通讯接口派生类 /// 获得设备状态类 /// 创建者:Richard.Liu /// public class CGetDeviceState:IGetDeviceState { DBOperator dbo = new DBOperator(); string _commLayerError; public string CommLayerError { get { return _commLayerError; } set { _commLayerError = value; } } public CGetDeviceState() { dbo.Open(); } //~CGetDeviceState() //{ // dbo.Close(); //} /// ///检测开关: 0-无货 /// 1-有货 ///第1字 ///可下达指令的设备:读/写标志位 ///1-写入数据 ///2-读出数据正确 ///确认按钮: ///1-无货确认 ///2-有货确认 /// 第2字 ///可下达指令的设备:命令 ///堆垛机: ///1-任务完成 ///其他植表示错误 /// 穿梭车: ///1-接货完成 ///2-送货完成 ///3-停止完成 ///4-到1#位置 ///5-到2#位置 /// … ///其他植表示错误 /// 输送机、台车: ///1-入库完成 ///2-出库完成 ///3-送货完成 ///4-停止完成 ///其他植表示错误 ///确认按钮: ///一个变化的值,每确认一次,该值变化一次,以标志一个 ///新的确认消息。例如可以是0、1交替变化,也可以是递 ///增变化。 ///第3字 任务号,即上位机下达任务时的任务号 ///第4字 堆垛机: ///终点X坐标(沿轨道方向) /// 穿梭车、台车、输送机: ///前三个字的异或值 /// (第5字以后部分只对堆垛机有意义) ///第5字 终点Y坐标(沿高度方向) ///第6字 前5个字的异或值 /// /// 设备编号 /// 获得上行消息成功后,发送应答消息后返回6或4个字节型状态 public int [] GetDeviceState(int DeviceIndex, int TaskIndex) { try { int[] _Rword = new int[6]; byte[] _RRword = new byte[200]; DataSet ds = dbo.ExceSQL("SELECT F_DeviceIndex,F_DeviceKindIndex, F_DBWAddress, F_DBWSendLength, F_DBWGetLength FROM T_Base_Device where F_DeviceIndex=" + DeviceIndex); DataView dv = ds.Tables[0].DefaultView; if (ds.Tables[0].DefaultView.Count > 0) { if (Convert.ToDecimal(dv[0]["F_DBWGetLength"]) > 1) { _RRword = CSimensCP5611.DB_Read_CP5611(1, 2, Convert.ToInt16(dv[0]["F_DBWAddress"]), Convert.ToInt16(dv[0]["F_DBWGetLength"])*2); } else//光电开关一类的位状态bit1--bit16 { int add = 0; int Bit = Convert.ToInt16(Convert.ToDecimal(dv[0]["F_DBWGetLength"]) * 16) - 1;//转换成bit0--bit15 if (Bit > 7) { add = 1; Bit = Bit - 8; } else { add = 0; } _RRword = CSimensCP5611.DB_Read_CP5611(1, 2, Convert.ToInt16(dv[0]["F_DBWAddress"])+add, 1, Bit); _Rword[0] = _RRword[0]; _Rword[1] = 3;//3-检测开关状态 _Rword[2] = TaskIndex;//任务号 _Rword[3] = 0; _Rword[4] = 0; _Rword[5] = DeviceIndex;//设备号索引 return _Rword; } if (_RRword == null) { _commLayerError = "SimensCP5611.CGetDeviceState" + ":GetDeviceState---" + CSimensCP5611.ErrorsText; return null; } } else { return null; } for (int g = 0; g <= 5; g++) { _Rword[g] = _RRword[(2 * g)] * 256 + _RRword[(2 * g + 1)]; } //ds.Dispose(); int _RXor = 0; if (_Rword != null) { if (Convert.ToInt16(dv[0]["F_DeviceKindIndex"]) == 1)//堆垛机类型设备 { _RXor = _Rword[0]; for (int i = 1; i <= 4; i++) { _RXor = _RXor ^ _Rword[i]; } //_Rword[0] == 1 && PLC读出数据正确 if (_Rword[2] == TaskIndex && _RXor == _Rword[5])//(正确反馈TaskIndex的消息应答) { _Rword[5] = DeviceIndex;//设备号索引 if (_Rword[1] == 0) { _Rword[1] = 2;//模拟自由口报告坐标 } return _Rword; } else return null; } else if (Convert.ToInt16(dv[0]["F_DeviceKindIndex"]) == 28)//光电开关采集器 { int[] rr = new int[_RRword.GetUpperBound(0) + 1]; for (int i = _RRword.GetLowerBound(0); i <= _RRword.GetUpperBound(0); i++) { rr[i] = Convert.ToInt32(_RRword[i]); } return rr; } else//其它设备类型 { _RXor = _Rword[0]; for (int i = 1; i <= 2; i++) { _RXor = _RXor ^ _Rword[i]; } //_Rword[0] == 1 && PLC读出数据正确 if (_Rword[2] == TaskIndex && _RXor == _Rword[3])//(正确反馈TaskIndex的消息应答) { _Rword[3] = 0; _Rword[4] = 0; _Rword[5] = DeviceIndex;//设备号索引 return _Rword; } else return null; } } else { return null; } } catch (Exception ex) { _commLayerError = "SimensCP5611.CGetDeviceState" + ":GetDeviceState---" +ex.Message ; return null; } } } }