using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace AuroraIO.AJINEXTEK { public class AjinIO : IOUnit { public class IOModuleInfo { public enum eModuleType { Digital, Analog }; #region IO Enumerator Definitions(IPG YLS, LBAD) public enum eADIAddress { LaserReady, EmissionStatus, LaserError, LaserIsOn, ProgramActive, Warning, LaserModuleAlarm, LaserAssigned, LBADReadyStatus, LBADJudgementComplete, LBADJudgeOK, LBADJudgeWARNING, LBADJudgeNG, LBADJudgeNA, LDDError = 27, LaserEMO_1, LaserEMO_2, LeakSensorHead, LeakSensorChiller, DICount } public enum eADOAddress { ProgramStart, PCcontrolEnable, ResetAlarm, GuideLaserEnable, AnalogControl, ProgramStop, LaserOn, PulseMode, PCLBADReadyStatus, PCLBADWeldingTrigger, PCLBADWeldingStop, PCLBADJudgementCompleteAck, DOCount } #endregion public IOModuleInfo(int no, int iCount, int oCount, eModuleType type, int inputStart, int outputStart) { ioModuleNo = no; inputCount = iCount; outputCount = oCount; ioModuleType = type; inputStartIndex = inputStart; outputStartIndex = outputStart; } eModuleType ioModuleType; public eModuleType IoModuleType { get { lock (this) { return ioModuleType; } } set { lock (this) { ioModuleType = value; } } } int ioModuleNo; public int IOModuleNo { get { lock (this) { return ioModuleNo; } } set { lock (this) { ioModuleNo = value; } } } int inputCount; public int InputCount { get { lock (this) { return inputCount; } } set { lock (this) { inputCount = value; } } } int outputCount; public int OutputCount { get { lock (this) { return outputCount; } } set { lock (this) { outputCount = value; } } } int inputStartIndex; public int InputStartIndex { get { lock (this) { return inputStartIndex; } } set { lock (this) { inputStartIndex = value; } } } int outputStartIndex; public int OutputStartIndex { get { lock (this) { return outputStartIndex; } } set { lock (this) { outputStartIndex = value; } } } } List ioModulInfoList = new List(); #region 추상 함수 선언 public override int Open(string iP) { int error = 0; string msg = ""; try { if (CAXL.AxlIsOpened() == (int)AXT_BOOLEAN.FALSE) { error = (int)CAXL.AxlOpen(7); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("IO Device Open Fail!!({0})", GetErrorMessage(error)); return error; } } //LoadIOTable(); return 0; } catch (Exception e) { return -1; } } public override void Close() { try { if (CAXL.AxlIsOpened() == (int)AXT_BOOLEAN.TRUE) CAXL.AxlClose(); } catch { } } public AjinIO() { } public override int GetDICount() { int count = 0; foreach(IOModuleInfo module in ioModulInfoList) { if(module.IoModuleType == IOModuleInfo.eModuleType.Digital) { count += module.InputCount; } } return count; } public override int GetDOCount() { int count = 0; foreach (IOModuleInfo module in ioModulInfoList) { if (module.IoModuleType == IOModuleInfo.eModuleType.Digital) { count += module.OutputCount; } } return count; } public override int GetAICount() { int count = 0; foreach (IOModuleInfo module in ioModulInfoList) { if (module.IoModuleType == IOModuleInfo.eModuleType.Analog) { count += module.InputCount; } } return count; } public override int GetAOCount() { int count = 0; foreach (IOModuleInfo module in ioModulInfoList) { if (module.IoModuleType == IOModuleInfo.eModuleType.Analog) { count += module.OutputCount; } } return count; } public override void Instance(string mappingFolder) { IOMappingFolder = mappingFolder; //LoadIOTable(); } public override int Initialize() { int error = 0; string msg = ""; int dioModuleCount = 0; int aioModuleCount = 0; #region DIO error = (int)CAXD.AxdInfoGetModuleCount(ref dioModuleCount); if ((error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) && (error != (int)AXT_FUNC_RESULT.AXT_RT_DIO_NOT_MODULE)) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); //messageDlg.messageDlg.RunDlg(msg, true, MessageDlg.DialogMode.MODAL); return error; } int boardNo = 0; int modulePos = 0; uint moduleId = 0; int moduleNo = 0; int inputCount = 0; int outputCount = 0; int inputIndex = 0; int outputIndex = 0; if (0 < dioModuleCount) { ioModulInfoList.Clear(); for (int i = 0; i < dioModuleCount; i++) { error = (int)CAXD.AxdInfoGetModule(i, ref boardNo, ref modulePos, ref moduleId); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } error = (int)CAXD.AxdInfoGetModuleNo(boardNo, modulePos, ref moduleNo); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } error = (int)CAXD.AxdInfoGetInputCount(moduleNo, ref inputCount); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } error = (int)CAXD.AxdInfoGetOutputCount(moduleNo, ref outputCount); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } #region R&D 장비에서 설정문제인지 IO보드가 중복검색되어서, 예외처리 추가 bool isAlreadyExists = false; foreach (IOModuleInfo module in ioModulInfoList) { if (moduleNo == module.IOModuleNo) { isAlreadyExists = true; break; } } if (isAlreadyExists) continue; #endregion IOModuleInfo tempModule = new IOModuleInfo(moduleNo, inputCount, outputCount, IOModuleInfo.eModuleType.Digital, inputIndex, outputIndex); ioModulInfoList.Add(tempModule); inputIndex += inputCount; outputIndex += outputCount; } } #endregion #region AIO error = (int)CAXA.AxaInfoGetModuleCount(ref aioModuleCount); if ((error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) && (error != (int)AXT_FUNC_RESULT.AXT_RT_AIO_NOT_MODULE)) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); //messageDlg.messageDlg.RunDlg(msg, true, MessageDlg.DialogMode.MODAL); return error; } if (0 < aioModuleCount) { boardNo = 0; modulePos = 0; moduleId = 0; moduleNo = 0; inputCount = 0; outputCount = 0; inputIndex = 0; outputIndex = 0; for (int i = 0; i < aioModuleCount; i++) { error = (int)CAXA.AxaInfoGetModule(i, ref boardNo, ref modulePos, ref moduleId); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } error = (int)CAXA.AxaInfoGetModuleNo(boardNo, modulePos, ref moduleNo); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } error = (int)CAXA.AxaInfoGetInputCount(moduleNo, ref inputCount); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } error = (int)CAXA.AxaInfoGetOutputCount(moduleNo, ref outputCount); if (error != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("Read Module Count Error!!({0})", GetErrorMessage(error)); return error; } #region R&D 장비에서 설정문제인지 IO보드가 중복검색되어서, 예외처리 추가 bool isAlreadyExists = false; foreach (IOModuleInfo module in ioModulInfoList) { if (moduleNo == module.IOModuleNo) { isAlreadyExists = true; break; } } if (isAlreadyExists) continue; #endregion IOModuleInfo tempModule = new IOModuleInfo(moduleNo, inputCount, outputCount, IOModuleInfo.eModuleType.Analog, inputIndex, outputIndex); ioModulInfoList.Add(tempModule); inputIndex += inputCount; outputIndex += outputCount; } } #endregion //IO 레벨 세팅 //error = SetIoLevel(); //Interrupt 세팅 //error = SetIntterrupt(); return 0; } public override bool IsConnected() { int err = (int)CAXL.AxlGetBoardStatus(0); return err == (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS; } #endregion public override int GetDoArray(ref bool[] array) { uint data = 0; int lastIndex = 0; foreach (IOModuleInfo module in ioModulInfoList) { if(module.IoModuleType == IOModuleInfo.eModuleType.Digital && module.OutputCount !=0) { int err = (int)CAXD.AxdoReadOutportDword(module.IOModuleNo, 0, ref data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { return err; } BitArray arr = new BitArray(BitConverter.GetBytes(data)); arr.CopyTo(array, lastIndex); lastIndex += module.OutputCount; } } return 0; } public override int GetDiArray(ref bool[] array) { uint data = 0; foreach (IOModuleInfo module in ioModulInfoList) { if (module.IoModuleType == IOModuleInfo.eModuleType.Digital && module.InputCount != 0) { int err = (int)CAXD.AxdiReadInportDword(module.IOModuleNo, 0, ref data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { return err; } //BitArray arr = new BitArray(BitConverter.GetBytes(data)); // 1안 ) 220118 이준혁Y 테스트 필요. //BitArray arr = new BitArray(module.InputCount, false); //for (int i = 0; i < module.InputCount; i++) //{ // int selectBitToInt = (int)(Math.Pow(2, i)); // int selectedBitToInt = (int)data & selectBitToInt; // if (selectedBitToInt == selectBitToInt) arr[i] = true; // else arr[i] = false; //} // 2안) 220118 카운트 크기에 따라서, BitArray 다른 것으로 쓰게끔. Byte tempByte = 0; UInt16 tempUInt = 0; BitArray arr = new BitArray(module.InputCount, false); if (module.InputCount == 8) { tempByte = Convert.ToByte(data); arr = new BitArray(BitConverter.GetBytes(tempByte).ToArray()); } else if (module.InputCount == 16) { tempUInt = Convert.ToUInt16(data); arr = new BitArray(BitConverter.GetBytes(tempUInt)); } else if (module.InputCount == 32) { arr = new BitArray(BitConverter.GetBytes(data)); } else; arr.CopyTo(array, module.InputStartIndex); } } return 0; } public override int ReadDoBit(int index, ref bool bit) { uint data = 0; int err = (int)CAXD.AxdoReadOutport(index, ref data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { return err; } bit = Convert.ToBoolean(data); return 0; } public override int ReadDiBit(int index, ref bool bit) { uint data = 0; int err = (int)CAXD.AxdiReadInport(index, ref data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { return err; } bit = Convert.ToBoolean(data); return 0; } public override bool ReadDoBit(int index) { //현재 사용하지 않아서 추후 구현 //return true; //[추후 구현] return true 스텁 의존 코드 확인 후 아래로 교체(ReadDiBit(int) 패턴) uint data = 0; int err = (int)CAXD.AxdoReadOutport(index, ref data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { throw new Exception(string.Format("ERR_IO_FAIL_TO_GET_BIT;ERROR CODE:{0}", err)); } return Convert.ToBoolean(data); } public override bool ReadDiBit(int index) { uint data = 0; int err = (int)CAXD.AxdiReadInport(index, ref data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { throw new Exception(string.Format("ERR_IO_FAIL_TO_GET_BIT;ERROR CODE:{0}", err)); } return Convert.ToBoolean(data); } public override int WriteDoBit(int index, bool bit) { uint data = Convert.ToUInt16(bit); int err = (int)CAXD.AxdoWriteOutport(index, data); if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { return err; } return 0; } public override void ClearList() { ListDI.Clear(); ListDO.Clear(); } //int SetIoLevel() //{ // string msg = string.Empty; // int rv = 0; // //AJin IO에서 접점 변경은 Active를 High(1) 또는 Low(0) Level 설정한다. // //기본적으로 NO(Normal Open)접점이 Active상태에서 high(1) Level이므로 설정을 아래와 같이 한다. // //input contact // foreach (IOModuleInfo ioModule in ioModulInfoList) // { // for (int i = 0; i < ioModule.InputCount; i++) // { // uint uLevel = (uint)(ListDI[ioModule.InputStartIndex + i].ActiveLevel == InfoIO.ActiveLevelType.High ? 1 : 0); // rv = (int)CAXD.AxdiLevelSetInportBit(ioModule.IOModuleNo, i, uLevel); // if (rv != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) // { // msg = string.Format("{0} Set DI Active Level Error({1})", ListDI[ioModule.InputStartIndex + i].Index, GetErrorMessage(rv)); // return rv; // } // } // for (int i = 0; i < ioModule.OutputCount; i++) // { // uint uLevel = (uint)(ListDO[ioModule.OutputStartIndex + i].ActiveLevel == InfoIO.ActiveLevelType.High ? 1 : 0); // rv = (int)CAXD.AxdoLevelSetOutportBit(ioModule.IOModuleNo, i, uLevel); // if (rv != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) // { // msg = string.Format("{0} Set Active Level Error({1})", ListDO[ioModule.OutputStartIndex + i].Index, GetErrorMessage(rv)); // return rv; // } // } // } // return rv; //} int SetIntterrupt() { string msg = string.Empty; int rv = 0; foreach (IOModuleInfo ioModule in ioModulInfoList) { //인터럽트 처리 사용 여부 설정 rv = (int)CAXD.AxdiInterruptSetModuleEnable(ioModule.IOModuleNo, 1); if (rv != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("ModuleNo :{0}; Set Interrupted Error({1})",ioModule.IOModuleNo, GetErrorMessage(rv)); return rv; } uint eventNo=0; //인터럽트 처리 방법 설정 rv = (int)CAXD.AxdiInterruptSetModule(ioModule.IOModuleNo,(IntPtr)null, 0, InterruptCallbackFunction, ref eventNo); if (rv != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("ModuleNo :{0}; Set Interrupted Error({1})", ioModule.IOModuleNo, GetErrorMessage(rv)); return rv; } for (int i = 0; i < ioModule.InputCount; i++) { //Rising Edge 설정 rv = (int)CAXD.AxdiInterruptEdgeSetBit(ioModule.IOModuleNo, i,1,1); if (rv != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("IO Index :{0}; Set Interrupted Error({1})", ListDI[ioModule.InputStartIndex + i].Index, GetErrorMessage(rv)); return rv; } //Falling Edge 설정 rv = (int)CAXD.AxdiInterruptEdgeSetBit(ioModule.IOModuleNo, i, 0, 1); if (rv != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) { msg = string.Format("IO Index :{0}; Set Interrupted Error({1})", ListDI[ioModule.InputStartIndex + i].Index, GetErrorMessage(rv)); return rv; } } } return rv; } #region ErrorMessage public string GetErrorMessage(int errCode) { return Enum.ToObject(typeof(AXT_FUNC_RESULT), errCode).ToString(); } #endregion ErrorMessage } }