2026-02-13 20:36:46 +09:00

635 lines
21 KiB
C#

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<IOModuleInfo> ioModulInfoList = new List<IOModuleInfo>();
#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(7);
if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS)
{
return true;
}
else
{
return false;
}
}
#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;
}
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)
{
return false;
}
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
}
}