diff --git a/DH.Commons/DH.Commons.csproj b/DH.Commons/DH.Commons.csproj index 9d1c41f..1c2b199 100644 --- a/DH.Commons/DH.Commons.csproj +++ b/DH.Commons/DH.Commons.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - AnyCPU;x64 + AnyCPU;X64 diff --git a/DH.Commons/Enums/Enum.cs b/DH.Commons/Enums/Enum.cs index 16a968b..d7e6d1c 100644 --- a/DH.Commons/Enums/Enum.cs +++ b/DH.Commons/Enums/Enum.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -54,4 +55,492 @@ namespace DH.Commons.Enums 心跳=25 } + + + public enum StreamFormat + { + [Description("8位图像")] + S_RAW8 = 0, + [Description("10位图像")] + S_RAW10 = 1, + [Description("12位图像")] + S_RAW12 = 2, + [Description("14位图像")] + S_RAW14 = 3, + [Description("16位图像")] + S_RAW16 = 4, + [Description("BGR三通道24比特图像")] + S_BGR24 = 10, + [Description("BGRA四通道32比特图像")] + S_BGR32 = 11, + [Description("BGRA四通道48比特图像")] + S_BGR48 = 12, + [Description("BGRA四通道64比特图像")] + S_BGR64 = 13, + [Description("RGB三通道24比特图像")] + S_RGB24 = 14, + [Description("RGBA四通道32比特图像")] + S_RGB32 = 15, + [Description("RGBA四通道48比特图像")] + S_RGB48 = 16, + [Description("RGBA四通道64比特图像")] + S_RGB64 = 17, + [Description("YUV411")] + S_YCBCR_411 = 20, + [Description("YUV422")] + S_YCBCR_422 = 21, + [Description("YUV444")] + S_YCBCR_444 = 22, + [Description("8位灰度图像")] + S_MONO8 = 30, + [Description("10位灰度图像")] + S_MONO10 = 31, + [Description("12位灰度图像")] + S_MONO12 = 32, + [Description("14位灰度图像")] + S_MONO14 = 33, + [Description("16位灰度图像")] + S_MONO16 = 34, + S_B8_G8_R8 = 40, + S_B16_G16_R16 = 44 + } + + + + /// + /// 主板型号 + /// + public enum BoardModelEnum + { + EC3216 = 0, + EC3224, + EC3416, + } + /// + /// 扩展板类型 + /// + public enum ExtensionBoardEnum + { + [Description("未外接扩展板")] + None, + [Description("一个IO扩展板")] + ExtIO_1, + [Description("一个EC3216扩展板")] + ExtEC3216_1, + [Description("一个EC3224扩展板")] + ExtEC3224_1, + [Description("一个EC3416扩展板")] + ExtEC3416_1, + } + + /// + /// 转盘类型 + /// + public enum MachineDiskType + { + + [Description("单转盘")] + SingleDisk = 1, + + [Description("双转盘")] + DoubleDisk = 2, + + } + + /// + /// 运动板卡 IO 类型(IN OUT) + /// + public enum IOType + { + [Description("INPUT")] + INPUT = 0, + [Description("OUTPUT")] + OUTPUT = 1 + } + + public enum IOValue + { + [Description("关闭")] + FALSE = 0, + [Description("开启")] + TRUE = 1, + [Description("反转")] + REVERSE = 2, + } + public enum RotationDirectionEnum + { + + [Description("顺时针(正方向)")] + Clockwise = 0, + + [Description("逆时针(负方向)")] + AntiClockwise = 1, + + } + + /// + /// IO预定义类型 主要针对输出 + /// + public enum IOPrestatement + { + [Description("自定义")] + Customized = 0, + + [Description("指示灯-黄")] + Light_Yellow = 1, + [Description("指示灯-绿")] + Light_Green = 2, + [Description("指示灯-红")] + Light_Red = 3, + [Description("蜂鸣器")] + Beep = 4, + [Description("照明灯")] + Light = 5, + + [Description("急停")] + EmergencyStop = 99, + } + + + /// + /// 相机信号IO输出模式 + /// + public enum ActionMode + { + [Description("IO断路输出")] + OpenCircuit = 1, + + [Description("IO开漏输出低电平")] + LowLevel = 2, + + [Description("取反IO")] + Reverse = 3, + + [Description("输出500us低脉冲")] + OutputPulse500us = 5, + + [Description("输出1ms低脉冲")] + OutputPulse1ms = 6, + + [Description("输出2ms低脉冲")] + OutputPulse2ms = 9, + + [Description("输出3ms低脉冲")] + OutputPulse3ms = 10, + + [Description("输出4ms低脉冲")] + OutputPulse4ms = 11, + + [Description("输出5ms低脉冲")] + OutputPulse5ms = 12, + + [Description("输出6ms低脉冲")] + OutputPulse6ms = 13, + + [Description("输出7ms低脉冲")] + OutputPulse7ms = 14, + + [Description("输出8ms低脉冲")] + OutputPulse8ms = 15, + + [Description("输出9ms低脉冲")] + OutputPulse9ms = 16, + + [Description("输出10ms低脉冲")] + OutputPulse10ms = 17, + + [Description("输出20ms低脉冲")] + OutputPulse20ms = 18, + + [Description("输出30ms低脉冲")] + OutputPulse30ms = 19, + + [Description("输出40ms低脉冲")] + OutputPulse40ms = 20, + + [Description("输出50ms低脉冲")] + OutputPulse50ms = 21, + + [Description("输出60ms低脉冲")] + OutputPulse60ms = 22, + + [Description("输出70ms低脉冲")] + OutputPulse70ms = 23, + + [Description("输出80ms低脉冲")] + OutputPulse80ms = 24, + + [Description("输出90ms低脉冲")] + OutputPulse90ms = 25, + + [Description("输出100ms低脉冲")] + OutputPulse100ms = 26, + + [Description("输出200ms低脉冲")] + OutputPulse200ms = 27, + + [Description("输出300ms低脉冲")] + OutputPulse300ms = 28, + } + + + /// + /// 吹气信号IO输出模式 + /// + public enum BlowType + { + + [Description("OK吹气口")] + OK, + + [Description("NG吹气口")] + NG, + + [Description("吹气口1")] + Blow1, + + [Description("吹气口2")] + Blow2, + + [Description("吹气口3")] + Blow3, + + [Description("吹气口4")] + Blow4, + + [Description("吹气口5")] + Blow5, + + [Description("吹气口6")] + Blow6, + + + + } + + /// + /// 来料检测位号,目前支持两路 + /// + public enum BitInputNumberEnum + { + [Description("第0路")] + BitInput0 = 0, + + [Description("第1路")] + BitInput1, + + } + + /// + /// 电平 + /// + public enum LogicLevelEnum + { + [Description("低电平")] + LowLevel = 0, + [Description("高电平")] + HighLevel, + } + + /// + /// 捕捉位置模式 + /// + public enum PositionSourceEnum + { + [Description("指令位置")] + CommandPosition = 0, + [Description("编码器位置")] + EncoderPosition = 1, + } + + + /// + /// 来料检测捕获位置 + /// + public enum SortingInputPositionModeEnum + { + [Description("前部")] + Front = 0, + [Description("中间")] + Middle, + } + + /// + /// 回原点模式1 + /// + public enum GoHomeMode + { + // Negative: 负极限、负方向 + // Positive: 正极限、正方向 + // NeL:负限开关 + // N:无 + + + //[ColorSelect("Gray")] + //[FontColorSelect("Black")] + [Description("1 负极限:负限开关_中间:无_正极限:无_Index位置:负限位正边_偏移:正方向")] + Negative_Ne_Center_N_Positive_N_Index_NePo_Offset_Po = 1, + + [Description("2 负极限:无_中间:无_正极限:正限开关_Index位置:正限位负边_偏移:负方向")] + Negative_N_Center_N_Positive_Po_Index_PoNe_Offset_Ne = 2, + + [Description("3 负极限:无_中间:无_正极限:原点开关_Index位置:原点负边外侧_偏移:负方向")] + Negative_N_Center_N_Positive_H_Index_HNeO_Offset_Ne = 3, + + [Description("4 负极限:无_中间:无_正极限:原点开关_Index位置:原点负边内侧_偏移:正方向")] + Negative_N_Center_N_Positive_H_Index_HNeI_Offset_Po = 4, + + + + + [Description("5 负极限:原点开关_中间:无_正极限:无_Index位置:原点正边外侧_偏移:正方向")] + Negative_H_Center_N_Positive_N_Index_HPoO_Offset_Po = 5, + + [Description("6 负极限:原点开关_中间:无_正极限:无_Index位置:原点正边内侧_偏移:负方向")] + Negative_H_Center_N_Positive_N_Index_HPoI_Offset_Ne = 6, + + + + + [Description("7 负极限:无_中间:原点开关_正极限:正限开关_Index位置:原点负边外侧_偏移:负方向")] + Negative_N_Center_H_Positive_Po_Index_HNeO_Offset_Ne = 7, + [Description("8 负极限:无_中间:原点开关_正极限:正限开关_Index位置:原点负边内侧_偏移:正方向")] + Negative_N_Center_H_Positive_Po_Index_HNeI_Offset_Po = 8, + [Description("9 负极限:无_中间:原点开关_正极限:正限开关_Index位置:原点正边内侧_偏移:负方向")] + Negative_N_Center_H_Positive_Po_Index_HPoI_Offset_Ne = 9, + [Description("10 负极限:无_中间:原点开关_正极限:正限开关_Index位置:原点正边外侧_偏移:正方向")] + Negative_N_Center_H_Positive_Po_Index_HPoO_Offset_Po = 10, + + + + + + [Description("11 负极限:负限开关_中间:原点开关_正极限:无_Index位置:原点正边外侧_偏移:正方向")] + Negative_Ne_Center_H_Positive_N_Index_HPoO_Offset_Po = 11, + [Description("12 负极限:负限开关_中间:原点开关_正极限:无_Index位置:原点正边内侧_偏移:负方向")] + Negative_Ne_Center_H_Positive_N_Index_HPoI_Offset_Ne = 12, + [Description("13 负极限:负限开关_中间:原点开关_正极限:无_Index位置:原点负边内侧_偏移:正方向")] + Negative_Ne_Center_H_Positive_N_Index_HNeI_Offset_Po = 13, + [Description("14 负极限:负限开关_中间:原点开关_正极限:无_Index位置:原点负边外侧_偏移:负方向")] + Negative_Ne_Center_H_Positive_N_Index_HNeO_Offset_Ne = 14, + + + + + + [Description("17 负极限:负限开关_中间:无_正极限:无_停止位置:负限位正边_偏移:正方向")] + Negative_Ne_Center_N_Positive_N_Stop_NePo_Offset_Po = 17, + + + + [Description("18 负极限:无_中间:无_正极限:正限开关_停止位置:正极限负边_偏移:负方向")] + Negative_N_Center_N_Positive_Po_Stop_PoNe_Offset_Ne = 18, + + + [Description("19 负极限:无_中间:无_正极限:原点开关_停止位置:原点负边外侧_偏移:负方向")] + Negative_N_Center_N_Positive_H_Stop_HNeO_Offset_Ne = 19, + [Description("20 负极限:无_中间:无_正极限:原点开关_停止位置:原点负边内侧_偏移:正方向")] + Negative_N_Center_N_Positive_H_Stop_HNeI_Offset_Po = 20, + + + + [Description("21 负极限:原点开关_中间:无_正极限:无_停止位置:原点正边外侧_偏移:正方向")] + Negative_H_Center_N_Positive_N_Stop_HPoO_Offset_Po = 21, + [Description("22 负极限:原点开关_中间:无_正极限:无_停止位置:原点正边内侧_偏移:负方向")] + Negative_H_Center_N_Positive_N_Stop_HPoI_Offset_Ne = 22, + + + + + [Description("23 负极限:无_中间:原点开关_正极限:正限开关_停止位置:原点负边外侧_偏移:负方向")] + Negative_N_Center_H_Positive_Po_Stop_HNeO_Offset_Ne = 23, + [Description("24 负极限:无_中间:原点开关_正极限:正限开关_停止位置:原点负边内侧_偏移:正方向")] + Negative_N_Center_H_Positive_Po_Stop_HNeI_Offset_Po = 24, + [Description("25 负极限:无_中间:原点开关_正极限:正限开关_停止位置:原点正边内侧_偏移:负方向")] + Negative_N_Center_H_Positive_Po_Stop_HPoI_Offset_Ne = 25, + [Description("26 负极限:无_中间:原点开关_正极限:正限开关_停止位置:原点正边外侧_偏移:正方向")] + Negative_N_Center_H_Positive_Po_Stop_HPoO_Offset_Po = 26, + + + + + [Description("27 负极限:负限开关_中间:原点开关_正极限:无_停止位置:原点正边外侧_偏移:正方向")] + Negative_Ne_Center_H_Positive_N_Stop_HPoO_Offset_Ne = 27, + [Description("28 负极限:负限开关_中间:原点开关_正极限:无_停止位置:原点正边内侧_偏移:负方向")] + Negative_Ne_Center_H_Positive_N_Stop_HPoI_Offset_Po = 28, + [Description("29 负极限:负限开关_中间:原点开关_正极限:无_停止位置:原点负边内侧_偏移:正方向")] + Negative_Ne_Center_H_Positive_N_Stop_HNeI_Offset_Ne = 29, + [Description("30 负极限:负限开关_中间:原点开关_正极限:无_停止位置:原点负边外侧_偏移:负方向")] + Negative_Ne_Center_H_Positive_N_Stop_HNeO_Offset_Po = 30, + + + + + [Description("33 负极限:无_中间:无_正极限:无_Index位置:负方向Index_偏移:负方向")] + Negative_N_Center_N_Positive_N_Index_NeIndex_Offset_Ne = 33, + [Description("34 负极限:无_中间:无_正极限:无_Index位置:正方向Index_偏移:正方向")] + Negative_N_Center_N_Positive_N_Index_PoIndex_Offset_Po = 34, + + } + + /// + /// 马达/运动板卡运行模式 + /// + public enum MotionMode + { + /// + /// 普通点位运动 + /// + [Description("普通点位运动")] + P2P = 1, + + /// + /// 找正限位运动 + /// + [Description("找正限位运动")] + FindPositive = 4, + + /// + /// 离开正限位 + /// + [Description("离开正限位")] + LeavePositive = 5, + + /// + /// 找负限位运动 + /// + [Description("找负限位运动")] + FindNegative = 6, + + /// + /// 离开负限位 + /// + [Description("离开负限位")] + LeaveNegative = 7, + + /// + /// 找原点运动 + /// + [Description("回原点运动")] + GoHome = 8, + + /// + /// Jog模式 + /// + [Description("Jog模式")] + Jog = 9, + + ///// + ///// 读数头找原点方式 + ///// + //[Description("找原点inde")] + //FindOriIndex = 10, + + ///// + ///// 插补模式 + ///// + //[Description("插补模式")] + //Coordinate = 11 + } + } diff --git a/DH.Commons/Enums/SolidMotionCardEnum.cs b/DH.Commons/Enums/SolidMotionCardEnum.cs new file mode 100644 index 0000000..c2387bc --- /dev/null +++ b/DH.Commons/Enums/SolidMotionCardEnum.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace XKRS.Common.Model.SolidMotionCard +{ + + + + /// + /// 回零状态 + /// + public enum SearchHomeState + { + /// + /// 回零成功 + /// + [Description("回零成功")] + HomeSucess = 0, + + /// + /// 回零错误 + /// + [Description("回零错误")] + HomeError = 31, + + /// + /// 正在回零点 + /// + [Description("正在回零点")] + Homing = 32, + } + + + + + /// + /// 0.3 坐标模式 + /// + public enum PositionMode + { + /// + /// 绝对位置模式 + /// + [Description("绝对位置模式")] + Position_Absolute = 0, + + + /// + /// 相对位置模式 + /// + [Description("相对位置模式")] + Position_Opposite = 1, + + } + + + /// + /// 0.4 单轴点动曲线类型 + /// + public enum Profile + { + /// + /// T型曲线 + /// + [Description("T型曲线")] + Profile_T = 0, + + /// + /// S型曲线 + /// + [Description("S型曲线")] + Profile_S = 1, + + } + + + + /// + /// 3.1 伺服使能设置 + /// + public enum ServoLogic + { + /// + /// 触点闭合 + /// + [Description("触点闭合")] + Servo_Close = 0, + + + /// + /// 触点打开 + /// + [Description("触点打开")] + Servo_Open = 1, + + } + + /// + /// 3.2 报警复位电平设置 + /// + public enum AlarmLogic + { + /// + /// 触点闭合 + /// + [Description("触点闭合")] + Alarm_Close = 0, + + + /// + /// 触点打开 + /// + [Description("触点打开")] + Alarm_Open = 1, + + } + + + /// + /// 3.6 + /// + public enum HomeState + { + /// + /// 触点闭合,硬件灯亮 + /// + [Description("触点闭合,硬件灯亮")] + Home_Close = 0, + + + /// + /// 触点打开,硬件灯灭 + /// + [Description("触点打开,硬件灯灭")] + Home_Open = 1, + } + + + + /// + /// 4.1 脉冲模式 + /// + public enum PulseMode + { + /// + /// 脉冲方向(默认) + /// + [Description("模式0")] + Pulse_Dir_H = 0, + + + /// + /// 脉冲方向 + /// + [Description("模式1")] + Pulse_Dir_L = 1, + + + /// + /// 双脉冲 + /// + [Description("模式2")] + Pulse_CW_CCW = 2, + + + /// + /// 双脉冲 + /// + [Description("模式3")] + Pulse_CCW_CW = 3, + + + /// + /// AB相位 + /// + [Description("模式4")] + Pulse_AB = 4, + + + /// + /// AB相位 + /// + [Description("模式5")] + Pulse_BA = 5, + + + } + + + /**************************************************************************************************************** +5 轴硬件触发停止运动函数 +*****************************************************************************************************************/ + //5.1 EMG_Mode + public enum EMG_Mode + { + [Description("不使用紧急停止功能")] + EMG_Trigger_Close = 0, //不使用紧急停止功能 + + [Description("低电平触发紧急停止")] + EMG_Trigger_Low_IMD = 1, //低电平触发紧急停止 + + [Description("低电平触发减速停止")] + EMG_Trigger_Low_DEC = 2,//低电平触发减速停止 + + [Description("高电平触发紧急停止")] + EMG_Trigger_High_IMD = 3, //高电平触发紧急停止 + + } + + + + + + /// + /// 6.1.1 正负限位触发电平 + /// + public enum LimitLogic + { + /// + /// 低电平触发 + /// + [Description("低电平触发")] + Low_Logic = 0, + + + /// + /// 高电平触发 + /// + [Description("高电平触发")] + High_Logic = 1, + } + + /// + /// 6.1.2 回零限位触发电平 + /// + public enum HomeLogic + { + /// + /// 低电平触发 + /// + [Description("低电平触发")] + Low_Logic = 0, + + + /// + /// 高电平触发 + /// + [Description("高电平触发")] + High_Logic = 1, + } + + /// + /// 6.1.3 Index触发电平 + /// + public enum IndexLogic + { + /// + /// 低电平触发 + /// + [Description("低电平触发")] + Low_Logic = 0, + + + /// + /// 高电平触发 + /// + [Description("高电平触发")] + High_Logic = 1, + } + + + +} diff --git a/DH.Devices.Camera/CameraBase.cs b/DH.Devices.Camera/CameraBase.cs index 93cbbba..2e14880 100644 --- a/DH.Devices.Camera/CameraBase.cs +++ b/DH.Devices.Camera/CameraBase.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using System.Drawing.Imaging; +using DH.Commons.Enums; using DVPCameraType; using OpenCvSharp; @@ -21,8 +21,12 @@ namespace DH.Devices.Camera public string SerialNumber { get; set; } = string.Empty; public string CameraName { get; set; } = string.Empty; - public dvpStreamFormat dvpStreamFormat = dvpStreamFormat.S_RGB24; + public string CameraIP { get; set; } = string.Empty; + public string ComputerIP { get; set; } = string.Empty; + + // public StreamFormat dvpStreamFormat = dvpStreamFormat.; + public dvpStreamFormat dvpStreamFormat = dvpStreamFormat.S_RGB24; [Category("采图模式")] [Description("是否传感器直接硬触发。true:传感器硬触发,不通过软件触发;false:通过软件触发IO 的硬触发模式")] [DisplayName("是否传感器直接硬触发")] diff --git a/DH.Devices.Camera/DH.Devices.Camera.csproj b/DH.Devices.Camera/DH.Devices.Camera.csproj index ea384fe..428287d 100644 --- a/DH.Devices.Camera/DH.Devices.Camera.csproj +++ b/DH.Devices.Camera/DH.Devices.Camera.csproj @@ -2,6 +2,7 @@ net8.0-windows + false enable enable ..\ @@ -11,15 +12,28 @@ AnyCPU;x64 + + + + + + + + + + - ..\x64\Debug\DVPCameraCS64.dll + ..\X64\Debug\DVPCameraCS64.dll + + + ..\x64\Debug\MvCameraControl.Net.dll diff --git a/DH.Devices.Camera/Do3ThinkCamera.cs b/DH.Devices.Camera/Do3ThinkCamera.cs index ff85f68..49bb698 100644 --- a/DH.Devices.Camera/Do3ThinkCamera.cs +++ b/DH.Devices.Camera/Do3ThinkCamera.cs @@ -57,7 +57,7 @@ namespace DH.Devices.Camera throw new Exception($"Create device failed:{nRet:x8}"); } - nRet = DVPCamera.dvpSetTargetFormat(m_handle, dvpStreamFormat); + nRet = DVPCamera.dvpSetTargetFormat(m_handle, (dvpStreamFormat)dvpStreamFormat); if (dvpStatus.DVP_STATUS_OK != nRet) { throw new Exception($"Set image format failed:{nRet:x8}"); @@ -308,6 +308,8 @@ namespace DH.Devices.Camera public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer) { + Mat cvImage = new Mat(); + try { @@ -316,8 +318,7 @@ namespace DH.Devices.Camera int nWidth = refFrame.iWidth; int nHeight = refFrame.iHeight; - Mat cvImage = new Mat(); - + // 根据图像格式创建Mat switch (refFrame.format) { @@ -337,7 +338,8 @@ namespace DH.Devices.Camera default: throw new NotSupportedException($"Unsupported format: {refFrame.format}"); } - OnHImageOutput?.Invoke(DateTime.Now, this, cvImage); + Mat smat = cvImage.Clone(); + OnHImageOutput?.Invoke(DateTime.Now, this, smat); @@ -348,6 +350,10 @@ namespace DH.Devices.Camera catch (Exception ex) { + } + finally + { + cvImage?.Dispose(); } return 0; } diff --git a/DH.Devices.Camera/HikVisionCamera.cs b/DH.Devices.Camera/HikVisionCamera.cs new file mode 100644 index 0000000..0cb52a0 --- /dev/null +++ b/DH.Devices.Camera/HikVisionCamera.cs @@ -0,0 +1,492 @@ +using System.Diagnostics; +using OpenCvSharp; +using MvCamCtrl.NET; +using System.Runtime.InteropServices; +using System.Xml.Linq; +using DH.Commons.Enums; +using static MvCamCtrl.NET.MyCamera; + + + +namespace DH.Devices.Camera +{ + public class HikVisionCamera : CameraBase + { + readonly MyCamera cameraObj = new MyCamera(); + MyCamera.MV_CC_DEVICE_INFO stDevInfo = new MyCamera.MV_CC_DEVICE_INFO(); + int nRet = MyCamera.MV_OK; + MyCamera.cbExceptiondelegate pCallBackFunc; + public MyCamera.cbOutputExdelegate ImageCallback; + MyCamera.MV_FRAME_OUT _frame = new MyCamera.MV_FRAME_OUT(); + readonly ManualResetEvent _snapHandle = new ManualResetEvent(false); + bool _snapFlag = false; + + public HikVisionCamera() + { + + + + } + + public override bool CameraConnect() + { + try + { + pCallBackFunc = new MyCamera.cbExceptiondelegate(cbExceptiondelegate); + + #region 根据IP连接相机 + stDevInfo.nTLayerType = MyCamera.MV_GIGE_DEVICE; + MyCamera.MV_GIGE_DEVICE_INFO stGigEDev = new MyCamera.MV_GIGE_DEVICE_INFO(); + + + var parts = CameraIP.Split('.'); + int nIp1 = Convert.ToInt32(parts[0]); + int nIp2 = Convert.ToInt32(parts[1]); + int nIp3 = Convert.ToInt32(parts[2]); + int nIp4 = Convert.ToInt32(parts[3]); + stGigEDev.nCurrentIp = (uint)((nIp1 << 24) | (nIp2 << 16) | (nIp3 << 8) | nIp4); + + parts = ComputerIP.Split('.'); + nIp1 = Convert.ToInt32(parts[0]); + nIp2 = Convert.ToInt32(parts[1]); + nIp3 = Convert.ToInt32(parts[2]); + nIp4 = Convert.ToInt32(parts[3]); + stGigEDev.nNetExport = (uint)((nIp1 << 24) | (nIp2 << 16) | (nIp3 << 8) | nIp4); + + IntPtr stGigeInfoPtr = Marshal.AllocHGlobal(216); + Marshal.StructureToPtr(stGigEDev, stGigeInfoPtr, false); + stDevInfo.SpecialInfo.stGigEInfo = new Byte[540]; + Marshal.Copy(stGigeInfoPtr, stDevInfo.SpecialInfo.stGigEInfo, 0, 540); + //释放内存空间 + Marshal.FreeHGlobal(stGigeInfoPtr); + #endregion + // ch:创建设备 | en: Create device + nRet = cameraObj.MV_CC_CreateDevice_NET(ref stDevInfo); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Create device failed:{nRet:x8}"); + } + + // ch:打开设备 | en:Open device + nRet = cameraObj.MV_CC_OpenDevice_NET(); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Open device failed:{nRet:x8}"); + } + + + // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera) + if (stDevInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE) + { + int nPacketSize = cameraObj.MV_CC_GetOptimalPacketSize_NET(); + if (nPacketSize > 0) + { + nRet = cameraObj.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize); + if (nRet != MyCamera.MV_OK) + { + Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet); + } + } + else + { + Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize); + } + } + + // ch:注册异常回调函数 | en:Register Exception Callback + nRet = cameraObj.MV_CC_RegisterExceptionCallBack_NET(pCallBackFunc, IntPtr.Zero); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Register expection callback failed:{nRet}"); + } + GC.KeepAlive(pCallBackFunc); + + // ch:设置采集连续模式 | en:Set Continues Aquisition Mode + cameraObj.MV_CC_SetEnumValue_NET("AcquisitionMode", 2);// ch:工作在连续模式 | en:Acquisition On Continuous Mode + //if (IIConfig.IsContinueMode) + //{ + // cameraObj.MV_CC_SetEnumValue_NET("TriggerMode", 0); // ch:连续模式 | en:Continuous + + // // ch:注册回调函数 | en:Register image callback + // ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc); + // nRet = cameraObj.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Register image callback failed!"); + // } + //} + //else + //{ + // ch:设置触发模式为off || en:set trigger mode as off + nRet = cameraObj.MV_CC_SetEnumValue_NET("TriggerMode", 1); + if (MyCamera.MV_OK != nRet) + { + throw new Exception("Set TriggerMode failed!"); + } + + //if (IIConfig.IsHardwareTrigger) + //{ + // ch:触发源选择:0 - Line0; | en:Trigger source select:0 - Line0; + // 1 - Line1; + // 2 - Line2; + // 3 - Line3; + // 4 - Counter; + // 7 - Software; + nRet = cameraObj.MV_CC_SetEnumValue_NET("TriggerSource", 0); + if (MyCamera.MV_OK != nRet) + { + throw new Exception("Set Line0 Trigger failed!"); + } + + // ch:注册回调函数 | en:Register image callback + ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc); + nRet = cameraObj.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero); + if (MyCamera.MV_OK != nRet) + { + throw new Exception("Register image callback failed!"); + } + //} + //else + //{ + // nRet = cameraObj.MV_CC_SetEnumValue_NET("TriggerSource", 7); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Set Software Trigger failed!"); + // } + //} + //} + // ch:开启抓图 || en: start grab image + nRet = cameraObj.MV_CC_StartGrabbing_NET(); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Start grabbing failed:{nRet:x8}"); + } + + //if (IConfig.DefaultExposure != 0) + //{ + // cameraObj.MV_CC_SetEnumValue_NET("ExposureAuto", 0); + // nRet = cameraObj.MV_CC_SetFloatValue_NET("ExposureTime", IConfig.DefaultExposure); + // if (nRet != MyCamera.MV_OK) + // { + // throw new Exception($"Exposure set failed:{nRet}"); + // } + //} + //if (IIConfig.Gain >= 0) + //{ + // nRet = cameraObj.MV_CC_SetFloatValue_NET("Gain", IIConfig.Gain); + // if (nRet != MyCamera.MV_OK) + // { + // throw new Exception($"Gain set failed:{nRet}"); + // } + //} + // 设置 触发延迟 + //if (IIConfig.TriggerDelay > 0) + //{ + // nRet = cameraObj.MV_CC_SetFloatValue_NET("TriggerDelay", IIConfig.TriggerDelay); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Set TriggerDelay failed!"); + // } + //} + //if (IIConfig.LineDebouncerTime > 0) + //{ + // nRet = cameraObj.MV_CC_SetIntValue_NET("LineDebouncerTime", (uint)IIConfig.LineDebouncerTime); + // if (nRet != MyCamera.MV_OK) + // { + // throw new Exception($"LineDebouncerTime set failed:{nRet}"); + // } + //} + //IIConfig.PropertyChanged -= IIConfig_PropertyChanged; + //IIConfig.PropertyChanged += IIConfig_PropertyChanged; + return true; + } + catch (Exception ex) + { + return false; + } + + + } + + private void IIConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + //if (e.PropertyName == "IsHardwareTrigger" && !IIConfig.IsContinueMode) + //{ + // // ch:停止抓图 | en:Stop grab image + // nRet = cameraObj.MV_CC_StopGrabbing_NET(); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception($"Stop grabbing failed{nRet:x8}"); + // } + + // if (IIConfig.IsHardwareTrigger) + // { + // // ch:触发源选择:0 - Line0; | en:Trigger source select:0 - Line0; + // // 1 - Line1; + // // 2 - Line2; + // // 3 - Line3; + // // 4 - Counter; + // // 7 - Software; + // nRet = cameraObj.MV_CC_SetEnumValue_NET("TriggerSource", 0); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Set Line0 Trigger failed!"); + // } + + // // ch:注册回调函数 | en:Register image callback + // ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc); + // nRet = cameraObj.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Register image callback failed!"); + // } + // } + // else + // { + // nRet = cameraObj.MV_CC_SetEnumValue_NET("TriggerSource", 7); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Set Software Trigger failed!"); + // } + // } + + // // ch:开启抓图 || en: start grab image + // nRet = cameraObj.MV_CC_StartGrabbing_NET(); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception($"Start grabbing failed:{nRet:x8}"); + // } + + // if (IConfig.DefaultExposure != 0) + // { + // cameraObj.MV_CC_SetEnumValue_NET("ExposureAuto", 0); + // nRet = cameraObj.MV_CC_SetFloatValue_NET("ExposureTime", IConfig.DefaultExposure); + // if (nRet != MyCamera.MV_OK) + // { + // throw new Exception($"Exposure set failed:{nRet}"); + // } + // } + // if (IIConfig.Gain >= 0) + // { + // nRet = cameraObj.MV_CC_SetFloatValue_NET("Gain", IIConfig.Gain); + // if (nRet != MyCamera.MV_OK) + // { + // throw new Exception($"Gain set failed:{nRet}"); + // } + // } + + // // 设置 触发延迟 + // if (IIConfig.TriggerDelay > 0) + // { + // nRet = cameraObj.MV_CC_SetFloatValue_NET("TriggerDelay", IIConfig.TriggerDelay); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception("Set TriggerDelay failed!"); + // } + // } + // if (IIConfig.LineDebouncerTime > 0) + // { + // nRet = cameraObj.MV_CC_SetIntValue_NET("LineDebouncerTime", (uint)IIConfig.LineDebouncerTime); + // if (nRet != MyCamera.MV_OK) + // { + // throw new Exception($"LineDebouncerTime set failed:{nRet}"); + // } + // } + //} + } + + public override bool CameraDisConnect() + { + //IIConfig.PropertyChanged -= IIConfig_PropertyChanged; + + //base.Stop(); + + // ch:停止抓图 | en:Stop grab image + + try + { + nRet = cameraObj.MV_CC_StopGrabbing_NET(); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Stop grabbing failed{nRet:x8}"); + } + + // ch:关闭设备 | en:Close device + nRet = cameraObj.MV_CC_CloseDevice_NET(); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Close device failed{nRet:x8}"); + } + + // ch:销毁设备 | en:Destroy device + nRet = cameraObj.MV_CC_DestroyDevice_NET(); + if (MyCamera.MV_OK != nRet) + { + throw new Exception($"Destroy device failed:{nRet:x8}"); + } + return true; + } + catch (Exception ex) + { + return false ; + } + } + + + + + void ImageCallbackFunc(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) + { + Mat cvImage = new Mat(); + try + { + + Interlocked.Increment(ref SnapshotCount); + int nWidth = pFrameInfo.nWidth; + int nHeight = pFrameInfo.nHeight; + switch (pFrameInfo.enPixelType) + { + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8: + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8: + cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC1, pData); + break; + case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed: + cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC3, pData); + Cv2.CvtColor(cvImage, cvImage, ColorConversionCodes.RGB2BGR); + break; + case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed: + cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC3, pData); + break; + case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8: + cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC1, pData); + break; + + default: + throw new NotSupportedException($"Unsupported pixel type: {pFrameInfo.enPixelType}"); + } + + OnHImageOutput?.Invoke(DateTime.Now, this, cvImage); + + } + catch (Exception ex) + { + + } + finally + { + cvImage?.Dispose(); + } + } + + + + + + public MvGvspPixelType GetMvGvspPixelType(StreamFormat streamFormat) + { + switch (streamFormat) + { + // 原始数据格式映射 + case StreamFormat.S_RAW8: + return MvGvspPixelType.PixelType_Gvsp_Mono8; + case StreamFormat.S_RAW10: + return MvGvspPixelType.PixelType_Gvsp_Mono10_Packed; + case StreamFormat.S_RAW12: + return MvGvspPixelType.PixelType_Gvsp_Mono12_Packed; + case StreamFormat.S_RAW14: + return MvGvspPixelType.PixelType_Gvsp_Mono14; + case StreamFormat.S_RAW16: + return MvGvspPixelType.PixelType_Gvsp_Mono16; + + // RGB/BGR格式映射 + case StreamFormat.S_BGR24: + return MvGvspPixelType.PixelType_Gvsp_BGR8_Packed; + case StreamFormat.S_BGR32: + return MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed; + case StreamFormat.S_RGB24: + return MvGvspPixelType.PixelType_Gvsp_RGB8_Packed; + case StreamFormat.S_RGB32: + return MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed; + case StreamFormat.S_BGR48: + return MvGvspPixelType.PixelType_Gvsp_BGR10_Packed; + case StreamFormat.S_RGB48: + return MvGvspPixelType.PixelType_Gvsp_RGB16_Packed; + + // YUV格式映射 + case StreamFormat.S_YCBCR_411: + return MvGvspPixelType.PixelType_Gvsp_YCBCR411_8_CBYYCRYY; + case StreamFormat.S_YCBCR_422: + return MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed; + case StreamFormat.S_YCBCR_444: + return MvGvspPixelType.PixelType_Gvsp_YUV444_Packed; + + // 灰度图像映射 + case StreamFormat.S_MONO8: + return MvGvspPixelType.PixelType_Gvsp_Mono8; + case StreamFormat.S_MONO10: + return MvGvspPixelType.PixelType_Gvsp_Mono10; + case StreamFormat.S_MONO12: + return MvGvspPixelType.PixelType_Gvsp_Mono12; + case StreamFormat.S_MONO14: + return MvGvspPixelType.PixelType_Gvsp_Mono14; + case StreamFormat.S_MONO16: + return MvGvspPixelType.PixelType_Gvsp_Mono16; + + // 特殊格式映射 + case StreamFormat.S_B8_G8_R8: + return MvGvspPixelType.PixelType_Gvsp_RGB8_Planar; + case StreamFormat.S_B16_G16_R16: + return MvGvspPixelType.PixelType_Gvsp_RGB16_Planar; + + default: + throw new ArgumentException($"Unsupported stream format: {streamFormat}"); + } + } + + + + + // ch:回调函数 | en:Callback function + private void cbExceptiondelegate(uint nMsgType, IntPtr pUser) + { + //if (nMsgType == MyCamera.MV_EXCEPTION_DEV_DISCONNECT) + //{ + // if (CurrentState != EnumHelper.DeviceState.DSClose) + // { + // int reTryTimes = 3; + // do + // { + // try + // { + // Task.Delay(1000).Wait(); + // Stop(); + + // Start(); + // reTryTimes = -1; + // } + // catch (Exception ex) + // { + // reTryTimes--; + + // if (reTryTimes > 0) + // { + // LogAsync(DateTime.Now, LogLevel.Information, $"{this.Name}重新连接异常,{ex.GetExceptionMessage()}"); + // } + // else + // { + // throw ex; + // } + // } + // } while (reTryTimes > 0); + // } + //} + } + + + + + + } +} diff --git a/DH.Devices.Motion/DH.Devices.Motion.csproj b/DH.Devices.Motion/DH.Devices.Motion.csproj new file mode 100644 index 0000000..3dffe2d --- /dev/null +++ b/DH.Devices.Motion/DH.Devices.Motion.csproj @@ -0,0 +1,29 @@ + + + + net8.0-windows + false + enable + enable + ..\ + output + true + true + AnyCPU;x64 + + + + + + + + + + + + + + + + + diff --git a/DH.Devices.Motion/MCDLL_NET.cs b/DH.Devices.Motion/MCDLL_NET.cs new file mode 100644 index 0000000..1081449 --- /dev/null +++ b/DH.Devices.Motion/MCDLL_NET.cs @@ -0,0 +1,621 @@ +using System.Reflection; +using System.Runtime.InteropServices; +/******************************************************************************************************************************************************************** +1 ÿԵô,Ӧ಻ͬ +2 ״̬ʵʱԴ洢10,ֹʵʱ +3 ´ﶯûʹ +4 ڸֹֹOKNGռͬһͨ +********************************************************************************************************************************************************************/ +namespace MCDLL_NET +{ + + + ///// + ///// + ///// + //public static class SolidMotionCardRetCode + //{ + // public const int RetOK = 0; + //} + + /// + /// ֹͣģʽ + /// + public static class AxisStopMode + { + /// + /// ֹͣ + /// + public const int AxisStopIMD = 0; + /// + /// ֹͣ + /// + public const int AxisStopDEC = 1; + } + + + + public class CMCDLL_NET + { + /******************************************************************************************************************************************************************** + 1 ƿ򿪺 + ********************************************************************************************************************************************************************/ + //1.0 粢ģʽú(򿪿ǰ) 궨1.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Switch_State_Net")] + public static extern short MCF_Set_Switch_State_Net(ushort Mode = 0); + // ú(򿪿ǰ) + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Card_Number_Net")] + public static extern short MCF_Set_Card_Number_Net(ushort Card_Number = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Card_Number_Net")] + public static extern short MCF_Get_Card_Number_Net(ref ushort Card_Number); + //1.1 ʼ [1,100] [0,99] 궨1.1 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Open_Net")] + public static extern short MCF_Open_Net(ushort Connection_Number, ref ushort Station_Number, ref ushort Station_Type); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Open_Net")] + public static extern short MCF_Get_Open_Net(ref ushort Connection_Number, ref ushort Station_Number, ref ushort Station_Type); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Close_Net")] + public static extern short MCF_Close_Net(); + //1.2 ӳʱֹͣ [0,60000] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Link_TimeOut_Net")] + public static extern short MCF_Set_Link_TimeOut_Net(uint Time_1MS, uint TimeOut_Output, ushort StationNumber = 0); + // ӳʱֹͣʹܺ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Trigger_Output_Bit_Net")] + public static extern short MCF_Set_Trigger_Output_Bit_Net(ushort Bit_Output_Number, ushort Bit_Output_Enable, ushort StationNumber = 0); + //1.3 Ӽ⺯ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Link_State_Net")] + public static extern short MCF_Get_Link_State_Net(ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 2 ͨ + ********************************************************************************************************************************************************************/ + //2.1 ͨIOȫ [OUT31,OUT0] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Output_Net")] + public static extern short MCF_Set_Output_Net(uint All_Output_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Output_Net")] + public static extern short MCF_Get_Output_Net(ref uint All_Output_Logic, ushort StationNumber = 0); + //2.2 ͨIOλ 궨2.3.1 궨2.3.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Output_Bit_Net")] + public static extern short MCF_Set_Output_Bit_Net(ushort Bit_Output_Number, ushort Bit_Output_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Output_Bit_Net")] + public static extern short MCF_Get_Output_Bit_Net(ushort Bit_Output_Number, ref ushort Bit_Output_Logic, ushort StationNumber = 0); + //2.3 ͨIO1λʱ亯 궨2.3.1 궨2.3.2 [0,65535] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Output_Time_Bit_Net")] + public static extern short MCF_Set_Output_Time_Bit_Net(ushort Bit_Output_Number, ushort Bit_Output_Logic, ushort Output_Time_1MS, ushort StationNumber = 0); + // ͨIO2λʱ亯 궨2.3.1 [0,1000] [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Compare_Output_Bit_Net")] + public static extern short MCF_Set_Compare_Output_Bit_Net(ushort Compare_Output_Number, ushort Compare_Output_1MS, ushort Compare_dDist, ushort StationNumber = 0); + //2.4 ͨIOȫ뺯 [Input31,Input0] [Input48,Input32] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Net")] + public static extern short MCF_Get_Input_Net(ref uint All_Input_Logic1, ref uint All_Input_Logic2, ushort StationNumber = 0); + //2.5 ͨIOλ뺯 궨2.4.1 궨2.4.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Bit_Net")] + public static extern short MCF_Get_Input_Bit_Net(ushort Bit_Input_Number, ref ushort Bit_Input_Logic, ushort StationNumber = 0); + //2.6 ͨIOλظٲ [Bit_Input_0,Bit_Input_3] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_Input_Fall_Bit_Net")] + public static extern short MCF_Clear_Input_Fall_Bit_Net(ushort Bit_Input_Number, ushort StationNumber = 0); + //2.7 ͨIOλظٲȡ [Bit_Input_0,Bit_Input_3] 궨2.7 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Fall_Bit_Net")] + public static extern short MCF_Get_Input_Fall_Bit_Net(ushort Bit_Input_Number, ref ushort Bit_Input_Fall, ushort StationNumber = 0); + //2.9 ͨIOλظټȡ [Bit_Input_0,Bit_Input_3] [0,(2^32-1)] 10± &Array[10] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Fall_Count_Bit_Net")] + public static extern short MCF_Get_Input_Fall_Count_Bit_Net(ushort Bit_Input_Number, ref uint Input_Count_Fall, ref uint Lock_Data_Buffer, ushort StationNumber = 0); + //2.10 ͨIOλ汣(10)򿪺(MCF_Open_Netǰǰ) + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Open_Input_Lock_Bit_Net")] + public static extern short MCF_Open_Input_Lock_Bit_Net(ushort Lock_Mode = 0, ushort StationNumber = 0); + //2.11 ͨIOλ˲ [Bit_Input_0,Bit_Input_3] [1,100]MS [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Input_Filter_Time_Bit_Net")] + public static extern short MCF_Set_Input_Filter_Time_Bit_Net(ushort Bit_Input_Number, uint Filter_Time_1MS, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 3 ר + ********************************************************************************************************************************************************************/ + //3.1 ŷʹú 궨0.0 궨3.1 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Servo_Enable_Net")] + public static extern short MCF_Set_Servo_Enable_Net(ushort Axis, ushort Servo_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_Enable_Net")] + public static extern short MCF_Get_Servo_Enable_Net(ushort Axis, ref ushort Servo_Logic, ushort StationNumber = 0); + //3.2 ŷλú 궨0.0 궨3.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Servo_Alarm_Reset_Net")] + public static extern short MCF_Set_Servo_Alarm_Reset_Net(ushort Axis, ushort Alarm_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_Alarm_Reset_Net")] + public static extern short MCF_Get_Servo_Alarm_Reset_Net(ushort Axis, ref ushort Alarm_Logic, ushort StationNumber = 0); + //3.3 ŷȡ 궨0.0 궨3.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_Alarm_Net")] + public static extern short MCF_Get_Servo_Alarm_Net(ushort Axis, ref ushort Servo_Alarm_State, ushort StationNumber = 0); + //3.4 ŷλȡ 궨0.0 궨3.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_INP_Net")] + public static extern short MCF_Get_Servo_INP_Net(ushort Axis, ref ushort Servo_INP_State, ushort StationNumber = 0); + //3.5 Zȡ 궨0.0 궨3.5 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Z_Net")] + public static extern short MCF_Get_Z_Net(ushort Axis, ref ushort Z_State, ushort StationNumber = 0); + //3.6 ԭȡ 궨0.0 궨3.6 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Home_Net")] + public static extern short MCF_Get_Home_Net(ushort Axis, ref ushort Home_State, ushort StationNumber = 0); + //3.7 λȡ 궨0.0 궨3.7 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Positive_Limit_Net")] + public static extern short MCF_Get_Positive_Limit_Net(ushort Axis, ref ushort Positive_Limit_State, ushort StationNumber = 0); + //3.8 λȡ 궨0.0 궨3.8 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Negative_Limit_Net")] + public static extern short MCF_Get_Negative_Limit_Net(ushort Axis, ref ushort Negative_Limit_State, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 4 ú + ********************************************************************************************************************************************************************/ + //4.1 ͨú 궨0.0 궨4.1 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Pulse_Mode_Net")] + public static extern short MCF_Set_Pulse_Mode_Net(ushort Axis, uint Pulse_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Pulse_Mode_Net")] + public static extern short MCF_Get_Pulse_Mode_Net(ushort Axis, ref uint Pulse_Mode, ushort StationNumber = 0); + //4.2 λú 궨0.0 [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Position_Net")] + public static extern short MCF_Set_Position_Net(ushort Axis, int Position, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Position_Net")] + public static extern short MCF_Get_Position_Net(ushort Axis, ref int Position, ushort StationNumber = 0); + //4.3 ú 궨0.0 [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Encoder_Net")] + public static extern short MCF_Set_Encoder_Net(ushort Axis, int Encoder, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Encoder_Net")] + public static extern short MCF_Get_Encoder_Net(ushort Axis, ref int Encoder, ushort StationNumber = 0); + // ͨZABֵ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Z_Clear_Encoder_Net")] + public static extern short MCF_Z_Clear_Encoder_Net(ushort Axis, ushort Enable, ushort StationNumber = 0); + // ͨZ̶IO 궨0.0 [0,255] [0,65535] [0,255] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Z_Output_Bit_Net")] + public static extern short MCF_Z_Output_Bit_Net(ushort Axis, ushort Number, uint dDist, ushort Time_1MS, ushort StationNumber = 0); + //4.4 ٶȻȡ 궨0.0 [-2^15,(2^15-1)] [-2^15,(2^15-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Vel_Net")] + public static extern short MCF_Get_Vel_Net(ushort Axis, ref double Command_Vel, ref double Encode_Vel, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 5 Ӳֹͣ˶ + ********************************************************************************************************************************************************************/ + //5.1 5.1 ͨIO븴ãΪֹͣ 궨2.4.1 궨5.1 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_EMG_Bit_Net")] + public static extern short MCF_Set_EMG_Bit_Net(ushort EMG_Input_Number, ushort EMG_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_EMG_Output_Net")] + public static extern short MCF_Set_EMG_Output_Net(ushort EMG_Input_Number, ushort EMG_Mode, uint EMG_Output, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_EMG_Output_Enable_Net")] + public static extern short MCF_Set_EMG_Output_Enable_Net(ushort Bit_Output_Number, ushort Bit_Output_Enable, ushort StationNumber = 0); + // ͨIO븴ãΪֹͣ [0,3] 궨0.0 [Bit_Input_0,Bit_Input_15] 궨5.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Input_Trigger_Net")] + public static extern short MCF_Set_Input_Trigger_Net(ushort Channel, ushort Axis, ushort Bit_Input_Number, uint Trigger_Mode, ushort StationNumber = 0); + + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Trigger_Net")] + public static extern short MCF_Get_Input_Trigger_Net(ushort Channel, ref ushort Axis, ref ushort Bit_Input_Number, ref uint Trigger_Mode, ushort StationNumber = 0); + + //5.2 λ˶ֹͣ 궨0.0 [-2^31,2^31]P > [-2^31,2^31]P [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Soft_Limit_Net")] + public static extern short MCF_Set_Soft_Limit_Net(ushort Axis, int Positive_Position, int Negative_Position, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Soft_Limit_Net")] + public static extern short MCF_Get_Soft_Limit_Net(ushort Axis, ref int Positive_Position, ref int Negative_Position, ushort StationNumber = 0); + //5.3 λ˶ֹͣغ 궨0.0 궨5.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Soft_Limit_Enable_Net")] + public static extern short MCF_Set_Soft_Limit_Enable_Net(ushort Axis, uint Soft_Limit_Enable, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Soft_Limit_Enable_Net")] + public static extern short MCF_Get_Soft_Limit_Enable_Net(ushort Axis, ref uint Soft_Limit_Enable, ushort StationNumber = 0); + //5.4 ŷ˶ֹͣ 궨0.0 궨5.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Alarm_Trigger_Net")] + public static extern short MCF_Set_Alarm_Trigger_Net(ushort Axis, uint Trigger_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Alarm_Trigger_Net")] + public static extern short MCF_Get_Alarm_Trigger_Net(ushort Axis, ref uint Trigger_Mode, ushort StationNumber = 0); + //5.5 Index˶ֹͣ 궨0.0 궨5.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Index_Trigger_Net")] + public static extern short MCF_Set_Index_Trigger_Net(ushort Axis, uint Trigger_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Index_Trigger_Net")] + public static extern short MCF_Get_Index_Trigger_Net(ushort Axis, ref uint Trigger_Mode, ushort StationNumber = 0); + //5.6 ԭ㴥˶ֹͣ 궨0.0 궨5.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Home_Trigger_Net")] + public static extern short MCF_Set_Home_Trigger_Net(ushort Axis, uint Trigger_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Home_Trigger_Net")] + public static extern short MCF_Get_Home_Trigger_Net(ushort Axis, ref uint Trigger_Mode, ushort StationNumber = 0); + //5.7 λ˶ֹͣ 궨0.0 궨5.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_ELP_Trigger_Net")] + public static extern short MCF_Set_ELP_Trigger_Net(ushort Axis, uint Trigger_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_ELP_Trigger_Net")] + public static extern short MCF_Get_ELP_Trigger_Net(ushort Axis, ref uint Trigger_Mode, ushort StationNumber = 0); + //5.8 λ˶ֹͣ 궨0.0 궨5.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_ELN_Trigger_Net")] + public static extern short MCF_Set_ELN_Trigger_Net(ushort Axis, uint Trigger_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_ELN_Trigger_Net")] + public static extern short MCF_Get_ELN_Trigger_Net(ushort Axis, ref uint Trigger_Mode, ushort StationNumber = 0); + //5.9 ԭ㴥λü¼ 궨0.0 [-2^31,(2^31-1)] [0,99] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Home_Rise_Position_Net")] + public static extern short MCF_Get_Home_Rise_Position_Net(ushort Axis, ref int Position, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Home_Fall_Position_Net")] + public static extern short MCF_Get_Home_Fall_Position_Net(ushort Axis, ref int Position, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Home_Rise_Encoder_Net")] + public static extern short MCF_Get_Home_Rise_Encoder_Net(ushort Axis, ref int Encoder, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Home_Fall_Encoder_Net")] + public static extern short MCF_Get_Home_Fall_Encoder_Net(ushort Axis, ref int Encoder, ushort StationNumber = 0); + //5.10 ״̬ 궨0.0 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_Axis_State_Net")] + public static extern short MCF_Clear_Axis_State_Net(ushort Axis, ushort StationNumber = 0); + //5.11 ״ֹ̬ͣ˶ѯ 궨0.0 MC_Retrun.h[0,28] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Axis_State_Net")] + public static extern short MCF_Get_Axis_State_Net(ushort Axis, ref short Reason, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 6 ԭ㺯 + ********************************************************************************************************************************************************************/ + //6.1 û 궨0.0 [1,65535] [1,65535] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_dMaxA_Time_Net")] + public static extern short MCF_Search_Home_dMaxA_Time_Net(ushort Axis, ushort H_dMaxA_Time = 10, ushort L_dMaxA_Time = 10, ushort StationNumber = 0); + // 궨0.0 [1,35] 궨6.1.1 궨6.1.2 궨6.1.3 (0,10M]P/S (0,10M]P/S [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Set_Net")] + public static extern short MCF_Search_Home_Set_Net(ushort Axis, ushort Search_Home_Mode, ushort Limit_Logic, ushort Home_Logic, ushort Index_Logic, double H_dMaxV, double L_dMaxV, int Offset_Position, ushort Trigger_Source, ushort StationNumber = 0); + //6.2 û 궨0.0 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Start_Net")] + public static extern short MCF_Search_Home_Start_Net(ushort Axis, ushort StationNumber = 0); + //6.3 ûֹͣ 궨0.0 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Stop_Net")] + public static extern short MCF_Search_Home_Stop_Net(ushort Axis, ushort StationNumber = 0); + //6.4 ȡ״̬ 궨0.0 MC_Retrun.h{0,31,32} [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Get_State_Net")] + public static extern short MCF_Search_Home_Get_State_Net(ushort Axis, ref ushort Home_State, ushort StationNumber = 0); + //6.5 û㻺ͣʱ 궨0.0 [0,1000] λms [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Stop_Time_Net")] + public static extern short MCF_Search_Home_Stop_Time_Net(ushort Axis, ushort Stop_Time, ushort StationNumber = 0); + //6.6 ûɺ󱣳λֵ 궨0.0 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Keep_Position_Net")] + public static extern short MCF_Search_Home_Keep_Position_Net(ushort Axis, ushort StationNumber = 0); + //6.7 ûɺ󱣳ֱֵ 궨0.0 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Keep_Encoder_Net")] + public static extern short MCF_Search_Home_Keep_Encoder_Net(ushort Axis, ushort StationNumber = 0); + //6.8 ûλ뿪ٶ 궨0.0 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Search_Home_Leave_Vel_Net")] + public static extern short MCF_Search_Home_Leave_Vel_Net(ushort Axis, double M_dMaxV, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 7 λ˶ƺ + ********************************************************************************************************************************************************************/ + //7.1 ٶȿƺ 궨0.0 (0,10M]P/S (0,1T]P^2/S [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_JOG_Net")] + public static extern short MCF_JOG_Net(ushort Axis, double dMaxV, double dMaxA, ushort StationNumber = 0); + //7.2 ˶λøı亯 궨0.0 [-2^31,(2^31-1)] 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Uniaxial_dDist_Change_Net")] + public static extern short MCF_Uniaxial_dDist_Change_Net(ushort Axis, int dDist, ushort Position_Mode, ushort StationNumber = 0); + //7.3 ˶ٶȸı亯 궨0.0 (0,10M]P/S [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Uniaxial_dMaxV_Change_Net")] + public static extern short MCF_Uniaxial_dMaxV_Change_Net(ushort Axis, double dMaxV, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Uniaxial_dMaxA_Change_Net")] + public static extern short MCF_Uniaxial_dMaxA_Change_Net(ushort Axis, double dMaxA, ushort StationNumber = 0); + //7.4 ߺ 궨0.0 [0,dMaxV] (0,10M]P/S (0,1T]P^2/S (0,100T]P^3/S [0,dMaxV] 궨0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Axis_Profile_Net")] + public static extern short MCF_Set_Axis_Profile_Net(ushort Axis, double dV_ini, double dMaxV, double dMaxA, double dJerk, double dV_end, ushort Profile, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Axis_Profile_Net")] + public static extern short MCF_Get_Axis_Profile_Net(ushort Axis, ref double dV_ini, ref double dMaxV, ref double dMaxA, ref double dJerk, ref double dV_end, ref ushort Profile, ushort StationNumber = 0); + //7.5 ˶ 궨0.0 [-2^31,(2^31-1)] 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Uniaxial_Net")] + public static extern short MCF_Uniaxial_Net(ushort Axis, int dDist, ushort Position_Mode, ushort StationNumber = 0); + //7.6 ֹͣߺ 궨0.0 (0,1T]P^2/S (0,100T]P^3/S 궨0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Axis_Stop_Profile_Net")] + public static extern short MCF_Set_Axis_Stop_Profile_Net(ushort Axis, double dMaxA, double dJerk, ushort Profile, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Axis_Stop_Profile_Net")] + public static extern short MCF_Get_Axis_Stop_Profile_Net(ushort Axis, ref double dMaxA, ref double dJerk, ref ushort Profile, ushort StationNumber = 0); + //7.7 ֹͣ 궨0.0 궨7.7 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Axis_Stop_Net")] + public static extern short MCF_Axis_Stop_Net(ushort Axis, ushort Axis_Stop_Mode, ushort StationNumber = 0); + //7.8 ˶ıں 궨0.0 [1,1000]MS [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Uniaxial_Cycle_Change_Net")] + public static extern short MCF_Uniaxial_Cycle_Change_Net(ushort Axis, ushort Cycle, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 8 岹˶ƺ + ********************************************************************************************************************************************************************/ + //8.1 ϵߺ 궨0.1 [0,dMaxV] (0,10M]P/S (0,1T]P^2/S (0,100T]P^3/S [0,dMaxV] 궨0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Coordinate_Profile_Net")] + public static extern short MCF_Set_Coordinate_Profile_Net(ushort Coordinate, double dV_ini, double dMaxV, double dMaxA, double dJerk, double dV_end, ushort Profile, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Coordinate_Profile_Net")] + public static extern short MCF_Get_Coordinate_Profile_Net(ushort Coordinate, ref double dV_ini, ref double dMaxV, ref double dMaxA, ref double dJerk, ref double dV_end, ref ushort Profile, ushort StationNumber = 0); + //8.2 Բ뾶岹˶ 궨0.1 궨0.0 [-2^31,(2^31-1)] [-2^31,(2^31-1)] 궨0.5 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Arc2_Radius_Net")] + public static extern short MCF_Arc2_Radius_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, int Arc_Radius, ushort Direction, ushort Position_Mode, ushort StationNumber = 0); + //8.3 ԲԲIJ岹˶ 궨0.1 궨0.0 [-2^31,(2^31-1)] [-2^31,(2^31-1)] 궨0.5 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Arc2_Centre_Net")] + public static extern short MCF_Arc2_Centre_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, ref int Center_List, ushort Direction, ushort Position_Mode, ushort StationNumber = 0); + //8.4 ֱ߲岹˶ 궨0.1 궨0.0 [-2^31,(2^31-1)] 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Line2_Net")] + public static extern short MCF_Line2_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, ushort Position_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Line3_Net")] + public static extern short MCF_Line3_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, ushort Position_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Line4_Net")] + public static extern short MCF_Line4_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, ushort Position_Mode, ushort StationNumber = 0); + //8.5 ϵֹͣߺ 궨0.1 (0,1T]P^2/S (0,100T]P^3/S 궨0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Coordinate_Stop_Profile_Net")] + public static extern short MCF_Set_Coordinate_Stop_Profile_Net(ushort Coordinate, double dMaxA, double dJerk, ushort Profile, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Coordinate_Stop_Profile_Net")] + public static extern short MCF_Get_Coordinate_Stop_Profile_Net(ushort Coordinate, ref double dMaxA, ref double dJerk, ref ushort Profile, ushort StationNumber = 0); + //8.6 Բ뾶岹˶ 궨0.1 궨0.0 [-2^31,(2^31-1)] [-2^31,(2^31-1)] 궨0.5 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Screw3_Radius_Net")] + public static extern short MCF_Screw3_Radius_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, int Arc_Radius, ushort Direction, ushort Position_Mode, ushort StationNumber = 0); + //8.7 ԲԲIJ岹˶ 궨0.1 궨0.0 [-2^31,(2^31-1)] [-2^31,(2^31-1)] 궨0.5 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Screw3_Centre_Net")] + public static extern short MCF_Screw3_Centre_Net(ushort Coordinate, ref ushort Axis_List, ref int dDist_List, ref int Center_List, ushort Direction, ushort Position_Mode, ushort StationNumber = 0); + //8.8 ϵֹͣ 궨0.1 궨5.6 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Coordinate_Stop_Net")] + public static extern short MCF_Coordinate_Stop_Net(ushort Coordinate, ushort Coordinate_Stop_Mode, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 9 + ********************************************************************************************************************************************************************/ + //9.1 ֹͣߺ 궨0.2 (0,1T]P^2/S (0,100T]P^3/S 궨0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Set_Stop_Profile_Net")] + public static extern short MCF_Buffer_Set_Stop_Profile_Net(ushort Buffer_Number, double dMaxA, double dJerk, ushort Profile, ushort StationNumber = 0); + //9.2 ֹͣ 궨0.2 궨9.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Stop_Net")] + public static extern short MCF_Buffer_Stop_Net(ushort Buffer_Number, ushort Buffer_Stop_Mode, ushort StationNumber = 0); + //9.3 ߸ıٶȱ 궨0.2 (0,10] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Change_Velocity_Ratio_Net")] + public static extern short MCF_Buffer_Change_Velocity_Ratio_Net(ushort Buffer_Number, double Velocity_Ratio, ushort StationNumber = 0); + //9.4 ʼ 궨0.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Start_Net")] + public static extern short MCF_Buffer_Start_Net(ushort Buffer_Number, ushort StationNumber = 0); + //9.5 ٶȱ 궨0.2 궨9.5 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Set_Velocity_Ratio_Enable_Net")] + public static extern short MCF_Buffer_Set_Velocity_Ratio_Enable_Net(ushort Buffer_Number, ushort Velocity_Ratio_Enable = 0, ushort StationNumber = 0); + //9.6 ǰհٱ 궨0.2 (0,1] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Set_Reduce_Ratio_Net")] + public static extern short MCF_Buffer_Set_Reduce_Ratio_Net(ushort Buffer_Number, double Reduce_Ratio = 1.0, ushort StationNumber = 0); + //9.7 ߺ 궨0.2 [0,dMaxV] (0,10M]P/S (0,1T]P^2/S (0,100T]P^3/S [0,dMaxV] 궨0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Set_Profile_Net")] + public static extern short MCF_Buffer_Set_Profile_Net(ushort Buffer_Number, double dV_ini, double dMaxV, double dMaxA, double dJerk, double dV_end, ushort Profile, ushort StationNumber = 0); + //9.8 ˶ 궨0.2 궨0.0 [-2^31,(2^31-1)] 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Uniaxial_Net")] + public static extern short MCF_Buffer_Uniaxial_Net(ushort Buffer_Number, ushort Axis, int dDist, ushort Position_Mode, ushort StationNumber = 0); + //˶ͬ溯 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Sync_Follow_Net")] + public static extern short MCF_Buffer_Sync_Follow_Net(ushort Buffer_Number, ushort Axis, int dDist, ushort StationNumber = 0); + //9.9 ֱ߲岹˶ 궨0.2 궨0.0 [-2^31,(2^31-1)] 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Line2_Net")] + public static extern short MCF_Buffer_Line2_Net(ushort Buffer_Number, ref ushort Axis_List, ref int dDist_List, ushort Position_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Line3_Net")] + public static extern short MCF_Buffer_Line3_Net(ushort Buffer_Number, ref ushort Axis_List, ref int dDist_List, ushort Position_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Line4_Net")] + public static extern short MCF_Buffer_Line4_Net(ushort Buffer_Number, ref ushort Axis_List, ref int dDist_List, ushort Position_Mode, ushort StationNumber = 0); + //9.10 ƽԲ뾶岹˶ 궨0.2 궨0.0 [-2^31,(2^31-1)] [-2^31,(2^31-1)] 궨0.5 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Arc_Radius_Net")] + public static extern short MCF_Buffer_Arc_Radius_Net(ushort Buffer_Number, ref ushort Axis_List, ref int dDist_List, int Arc_Radius, ushort Direction, ushort Position_Mode, ushort StationNumber = 0); + //9.11 ƽԲԲIJ岹˶ 궨0.2 궨0.0 [-2^31,(2^31-1)] [-2^31,(2^31-1)] 궨0.5 궨0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Arc_Centre_Net")] + public static extern short MCF_Buffer_Arc_Centre_Net(ushort Buffer_Number, ref ushort Axis_List, ref int dDist_List, ref int Center_List, ushort Direction, ushort Position_Mode, ushort StationNumber = 0); + //9.12 ʱ 궨0.2 [0,2^31-1] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Delay_Net")] + public static extern short MCF_Buffer_Delay_Net(ushort Buffer_Number, uint number, ushort StationNumber = 0); + //9.13 IO 궨0.2 궨2.3.1 궨2.3.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Set_Output_Bit_Net")] + public static extern short MCF_Buffer_Set_Output_Bit_Net(ushort Buffer_Number, ushort Bit_Number, ushort output, ushort StationNumber = 0); + //9.14 IOȴ 궨0.2 궨2.4.1 궨2.4.2 (0,2^15-1] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Wait_Input_Bit_Net")] + public static extern short MCF_Buffer_Wait_Input_Bit_Net(ushort Buffer_Number, ushort Bit_Number, ushort Logic, ushort Time_Out, ushort StationNumber = 0); + //9.15 궨0.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_End_Net")] + public static extern short MCF_Buffer_End_Net(ushort Buffer_Number, ushort StationNumber = 0); + //9.16 ִк 궨0.2 궨9.16 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Execute_Net")] + public static extern short MCF_Buffer_Execute_Net(ushort Buffer_Number, ushort Execute_Mode, ushort StationNumber = 0); + //9.17 ϵ 궨0.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Execute_BreakPoint_Net")] + public static extern short MCF_Buffer_Execute_BreakPoint_Net(ushort Buffer_Number, ushort StationNumber = 0); + //9.18 ״̬ѯ 궨0.2 MC_Retrun.h{0,29,30} [0,2^15-1] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Get_State_Net")] + public static extern short MCF_Buffer_Get_State_Net(ushort Buffer_Number, ref ushort Execute_State, ref ushort Execute_Number, ushort StationNumber = 0); + //9.19 ʣɲָռٷֱȲѯ 궨0.2 [0,100] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Get_Remainder_Space_Net")] + public static extern short MCF_Buffer_Get_Remainder_Space_Net(ushort Buffer_Number, ref ushort Remainder_Space_Ratio, ushort StationNumber = 0); + //9.20 ʼ(ѯʣһϿռ) 궨0.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Insert_Start_Net")] + public static extern short MCF_Buffer_Insert_Start_Net(ushort Buffer_Number, ushort StationNumber = 0); + //9.22 궨0.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Insert_End_Net")] + public static extern short MCF_Buffer_Insert_End_Net(ushort Buffer_Number, ushort StationNumber = 0); + //9.23 ָռõĿռٷֱ 궨0.2 [0,100] [0,99] + // MCF_Buffer_Start_NetMCF_Buffer_Insert_Start_Netʼ0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Buffer_Count_Occupy_Space_Net")] + public static extern short MCF_Buffer_Count_Occupy_Space_Net(ushort Buffer_Number, ref ushort Occupy_Space_Ratio, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 10 ʾ10KƵݲ׽ + ********************************************************************************************************************************************************************/ + //10.1 ݲ׽/رպ(MCF_Open_Netǰǰ,ֻ֧һ˶ƿ) + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Open_Net")] + public static extern short MCF_Capture_Open_Net(ushort Capture_Mode = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Close_Net")] + public static extern short MCF_Capture_Close_Net(); + //10.2 ݲ׽ݸº 궨10.2 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_State_Net")] + public static extern short MCF_Capture_State_Net(ref ushort Capture_State); + //10.3 ȡ1000λ 궨0.0 &Array[Capture_Frequency*Capture_Time_1MS] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Read_Command_Net")] + public static extern short MCF_Capture_Read_Command_Net(ushort Axis, ref int Command); + //10.4 ȡ1000 궨0.0 &Array[Capture_Frequency*Capture_Time_1MS] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Read_Encoder_Net")] + public static extern short MCF_Capture_Read_Encoder_Net(ushort Axis, ref int Encoder); + //10.5 ȡ1000ģ 궨0.0 &Array[Capture_Frequency*Capture_Time_1MS] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Read_AD_Net")] + public static extern short MCF_Capture_Read_AD_Net(ushort Axis, ref int AD); + //10.6 ADC˲ 궨0.0 [0,1] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Filter_AD_Net")] + public static extern short MCF_Capture_Filter_AD_Net(ushort Axis, double Filter_Coefficient = 1); + //10.7 ݲ׽Ƶ 궨10.7 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Frequency_Net")] + public static extern short MCF_Capture_Frequency_Net(ushort Capture_Frequency = 1, ushort StationNumber = 0); + //10.8 ݲ׽ʱ [2,1000] 2ı + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Capture_Time_Net")] + public static extern short MCF_Capture_Time_Net(ushort Capture_Time_1MS = 100, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 11 ӳֿƺ + ********************************************************************************************************************************************************************/ + //11.1 ӳú 궨0.0 궨0.0 (0,(2^31-1)] (0,(2^31-1)] 궨11.1.1 궨11.1.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Gear_Net")] + public static extern short MCF_Set_Gear_Net(ushort Axis, ushort Follow_Axis, uint Denominator, uint Molecule, ushort Follow_Source, ushort Dir, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Gear_Net")] + public static extern short MCF_Get_Gear_Net(ushort Axis, ref ushort Follow_Axis, ref uint Denominator, ref uint Molecule, ref ushort Follow_Source, ref ushort Dir, ushort StationNumber = 0); + //11.2 ӳֿغ 궨0.0 궨11.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Gear_Enable_Net")] + public static extern short MCF_Set_Gear_Enable_Net(ushort Axis, ushort Gear_Enable, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Gear_Enable_Net")] + public static extern short MCF_Get_Gear_Enable_Net(ushort Axis, ref ushort Gear_Enable, ushort StationNumber = 0); + //11.3 ӳ˶Զر 궨0.0 [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Gear_Auto_Disable_Net")] + public static extern short MCF_Set_Gear_Auto_Disable_Net(ushort Axis, int dDist, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 12 λñȽ + ********************************************************************************************************************************************************************/ + //12.1 һάλñȽ 궨0.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Compare_Config_Net")] + public static extern short MCF_Set_Compare_Config_Net(ushort Axis, ushort Enable, ushort Compare_Source, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Compare_Config_Net")] + public static extern short MCF_Get_Compare_Config_Net(ushort Axis, ref ushort Enable, ref ushort Compare_Source, ushort StationNumber = 0); + //12.2 һάλ/ǰȽϵ/ر 궨0.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_Compare_Points_Net")] + public static extern short MCF_Clear_Compare_Points_Net(ushort Axis, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_Compare_Current_Points_Net")] + public static extern short MCF_Clear_Compare_Current_Points_Net(ushort Axis, ushort StationNumber = 0); + // MCF_Add_Compare_Point_Net ۼӼ 궨0.0 [1,(2^31-1)} + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Disable_Compare_Any_Points_Net")] + public static extern short MCF_Disable_Compare_Any_Points_Net(ushort Axis, uint Point_Number, ushort StationNumber = 0); + //12.3 һάλñȽϵ 궨0.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Add_Compare_Point_Net")] + public static extern short MCF_Add_Compare_Point_Net(ushort Axis, int Position, ushort Dir, ushort Action, ushort Actpara, ushort StationNumber = 0); + //12.4 ȡǰһάȽϵλ 궨0.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Compare_Current_Point_Net")] + public static extern short MCF_Get_Compare_Current_Point_Net(ushort Axis, ref int Position, ushort StationNumber = 0); + //12.5 ѯѾȽϹһάȽϵ(ע) 궨0.0 [0,256] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Compare_Points_Runned_Net")] + public static extern short MCF_Get_Compare_Points_Runned_Net(ushort Axis, ref ushort Point_Number, ushort StationNumber = 0); + //12.6 ѯԼһάȽϵ 궨0.0 [0,256] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Compare_Points_Remained_Net")] + public static extern short MCF_Get_Compare_Points_Remained_Net(ushort Axis, ref ushort Point_Number, ushort StationNumber = 0); + //12.7 ѯδһάȽϵλ 궨0.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Compare_Points_Incomplete_Net")] + public static extern short MCF_Get_Compare_Points_Incomplete_Net(ushort Axis, ref ushort Incomplete_Number, ref int Incomplete_Position, ushort StationNumber = 0); + + + + /******************************************************************************************************************************************************************** + 13 PWM + ********************************************************************************************************************************************************************/ + //13.1 PWM 궨13.1.1 궨13.1.2 궨13.1.3 궨13.1.4 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Pwm_Config_Net")] + public static extern short MCF_Set_Pwm_Config_Net(ushort Channel, ushort Enable, ushort Output_Port_Config, ushort Output_Start_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Pwm_Config_Net")] + public static extern short MCF_Get_Pwm_Config_Net(ushort Channel, ref ushort Enable, ref ushort Output_Port_Config, ref ushort Output_Start_Logic, ushort StationNumber = 0); + //13.2 PWMź 궨13.1.1 [0,1000000] [0,100] (0,(2^31-1)] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Pwm_Output_Net")] + public static extern short MCF_Set_Pwm_Output_Net(ushort Channel, uint Frequency, uint DutyCycle, uint Pwm_Number, ushort StationNumber = 0); + //13.3 PWMź 궨13.1.1 궨13.3.1 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Pwm_State_Net")] + public static extern short MCF_Get_Pwm_State_Net(ushort Channel, ref ushort Finish, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 14 ֺ + ********************************************************************************************************************************************************************/ + //14.1 ֹ 궨11.1.2 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Open_Net")] + public static extern short MCF_Hand_Wheel_Open_Net(ushort Dir, ushort StationNumber = 0); + //14.2 رֹ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Close_Net")] + public static extern short MCF_Hand_Wheel_Close_Net(ushort StationNumber = 0); + //14.3 Ӳֱͨ 궨0.0 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Config_Encoder_Net")] + public static extern short MCF_Hand_Wheel_Config_Encoder_Net(ushort Axis, ushort StationNumber = 0); + //14.4 Ӳ 궨2.4.1 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Config_X1_Net")] + public static extern short MCF_Hand_Wheel_Config_X1_Net(ushort Bit_Input_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Config_X10_Net")] + public static extern short MCF_Hand_Wheel_Config_X10_Net(ushort Bit_Input_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Config_X100_Net")] + public static extern short MCF_Hand_Wheel_Config_X100_Net(ushort Bit_Input_Number, ushort StationNumber = 0); + // ӲʴС [1,100] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Speed_X1_Net")] + public static extern short MCF_Hand_Wheel_Speed_X1_Net(ushort Speed_X = 1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Speed_X10_Net")] + public static extern short MCF_Hand_Wheel_Speed_X10_Net(ushort Speed_X = 10, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Speed_X100_Net")] + public static extern short MCF_Hand_Wheel_Speed_X100_Net(ushort Speed_X = 100, ushort StationNumber = 0); + //14.4 Ӳ 궨0.0 궨2.4.1 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Config_Axis_Net")] + public static extern short MCF_Hand_Wheel_Config_Axis_Net(ushort Axis, ushort Bit_Input_Number, ushort StationNumber = 0); + //14.5 ˶ƽ˲ʱ 궨0.0 [1,1000]MS + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Hand_Wheel_Config_Filter_Time_Net")] + public static extern short MCF_Hand_Wheel_Config_Filter_Time_Net(ushort Axis, uint Filter_Time_1MS, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 15 ģ + ********************************************************************************************************************************************************************/ + //15.1 ȡADC 궨0.0 [-2^15,(2^15-1)] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Single_Read_AD_Net")] + public static extern short MCF_Single_Read_AD_Net(ushort Channel, ref short AD, ushort StationNumber = 0); + //15.2 ȡDAC 궨0.0 [-2^15,(2^15-1)] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Single_Write_DA_Net")] + public static extern short MCF_Single_Write_DA_Net(ushort Channel, short DA, ushort StationNumber = 0); + //15.3 AD˫ȽֹͣӦ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_AD_Compare_Net")] + public static extern short MCF_Set_AD_Compare_Net(ushort Channel, short AD_Compare, ushort Stop_Axis, ushort StationNumber = 0); + //15.4 ADֵ [0,7] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_AD_Capture_Net")] + public static extern short MCF_Set_AD_Capture_Net(ushort Channel, short AD_Capture, ushort StationNumber = 0); + // 0ֲ 1λ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_AD_Capture_Net")] + public static extern short MCF_Clear_AD_Capture_Net(ushort C_1, ushort C_2, ushort C_3, ushort C_4, + ushort C_5, ushort C_6, ushort C_7, ushort C_8, ushort StationNumber = 0); + // ȡADֵ񵽵ĶӦͨADֵXλ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_1_Net")] + public static extern short MCF_Get_Capture_AD_1_Net(ref short AD_5, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_2_Net")] + public static extern short MCF_Get_Capture_AD_2_Net(ref short AD_6, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_3_Net")] + public static extern short MCF_Get_Capture_AD_3_Net(ref short AD_7, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_4_Net")] + public static extern short MCF_Get_Capture_AD_4_Net(ref short AD_8, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_5_Net")] + public static extern short MCF_Get_Capture_AD_5_Net(ref short AD_1, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_6_Net")] + public static extern short MCF_Get_Capture_AD_6_Net(ref short AD_2, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_7_Net")] + public static extern short MCF_Get_Capture_AD_7_Net(ref short AD_3, ref int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Capture_AD_8_Net")] + public static extern short MCF_Get_Capture_AD_8_Net(ref short AD_4, ref int Position_1, ushort StationNumber = 0); + //15.5 ôλֵ [0,7] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Position_Capture_AD_Net")] + public static extern short MCF_Set_Position_Capture_AD_Net(ushort Channel, int Position_1, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Position_Capture_AD_Net")] + public static extern short MCF_Get_Position_Capture_AD_Net(ushort Channel, ref short AD, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_Position_Capture_AD_Net")] + public static extern short MCF_Clear_Position_Capture_AD_Net(ushort C_1, ushort C_2, ushort C_3, ushort C_4, ushort C_5, ushort C_6, ushort C_7, ushort C_8, ushort StationNumber = 0); + //15.6 ȡADֵ [0,7] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Limit_AD_Net")] + public static extern short MCF_Get_Limit_AD_Net(ushort Channel, ref short MAX_AD, ref short MIN_AD, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Clear_Limit_AD_Net")] + public static extern short MCF_Clear_Limit_AD_Net(ushort C_1, ushort C_2, ushort C_3, ushort C_4, ushort C_5, ushort C_6, ushort C_7, ushort C_8, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 16 ϵͳ + ********************************************************************************************************************************************************************/ + //16.1 ģ汾 [0x00000000,0xFFFFFFFF] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Version_Net")] + public static extern short MCF_Get_Version_Net(ref uint Version, ushort StationNumber = 0); + //16.2 к [0x00000000,0xFFFFFFFF] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Serial_Number_Net")] + public static extern short MCF_Get_Serial_Number_Net(ref long Serial_Number, ushort StationNumber = 0); + //16.3 ģʱ [0x00000000,0xFFFFFFFF] [0,99] λ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Run_Time_Net")] + public static extern short MCF_Get_Run_Time_Net(ref uint Run_Time, ushort StationNumber = 0); + //16.4 Flash дĿǰʱС2Kbytes,Ҳһ unsigned int Array[256] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Flash_Write_Net")] + public static extern short MCF_Flash_Write_Net(uint Pass_Word_Setup, ref uint Flash_Write_Data, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Flash_Read_Net")] + public static extern short MCF_Flash_Read_Net(uint Pass_Word_Check, ref uint Flash_Read_Data, ushort StationNumber = 0); + //16.5 ·,һһգʹ(Ĭ) + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_LookBack_Enable_Net")] + public static extern short MCF_LookBack_Enable_Net(); + //16.6 ر·ֻգϻģʽʹ,߼ģǷ + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_LookBack_Disable_Net")] + public static extern short MCF_LookBack_Disable_Net(); + //16.7 ͨѶʱ &Array[12] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Connect_Time_Count_Net")] + public static extern short MCF_Get_Connect_Time_Count_Net(ref uint Connect_Count); + //16.8 ϵͳʱص + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_CallBack_Net")] + public static extern short MCF_Set_CallBack_Net(int CallBack, uint Time_1MS); + } + +} \ No newline at end of file diff --git a/DH.Devices.Motion/MCDLL_NET_Code.cs b/DH.Devices.Motion/MCDLL_NET_Code.cs new file mode 100644 index 0000000..080e5cb --- /dev/null +++ b/DH.Devices.Motion/MCDLL_NET_Code.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace XKRS.Device.SolidMotionCard +{ + + public enum FuncRet + { + /// + /// 正常命令执行成功 + /// + Function_Success = 0, + + + /// + /// 打开站点不成功 + /// + + ERR_Open_Station_Fail = -18, + + } + +} diff --git a/DH.Devices.Motion/MCDLL_NET_SORTING.cs b/DH.Devices.Motion/MCDLL_NET_SORTING.cs new file mode 100644 index 0000000..630ec86 --- /dev/null +++ b/DH.Devices.Motion/MCDLL_NET_SORTING.cs @@ -0,0 +1,338 @@ +using System.Runtime.InteropServices; +/******************************************************************************************************************************************************************** +1 每个相机可以单独设置触发参数,适应给更多不同相机 +2 物件状态实时可以存储10组数据,防止计算机不实时 +3 根据物件编号下达动作,方便用户使用 +4 吹气口各种工作,防止OK与NG占用同一个通道 +********************************************************************************************************************************************************************/ +namespace MCDLL_NET +{ + public class CMCDLL_NET_Sorting + { + /******************************************************************************************************************************************************************** + 1 系统设置函数 + ********************************************************************************************************************************************************************/ + //1.0 筛选功能初始化函数 必须在 MCF_Open_Net() 前调用 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Init_Net")] + public static extern short MCF_Sorting_Init_Net(ushort StationNumber = 0); + //1.1 控制卡打开关闭函数 [1,100] [0,99] 宏定义1.1 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Open_Net")] + public static extern short MCF_Open_Net(ushort Connection_Number, ref ushort Station_Number, ref ushort Station_Type); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Open_Net")] + public static extern short MCF_Get_Open_Net(ref ushort Connection_Number, ref ushort Station_Number, ref ushort Station_Type); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Close_Net")] + public static extern short MCF_Close_Net(); + //1.2 链接超时紧急停止函数 [0,60000] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Link_TimeOut_Net")] + public static extern short MCF_Set_Link_TimeOut_Net(uint Time_1MS, uint TimeOut_Output, ushort StationNumber = 0); + // 链接超时紧急停止触发使能函数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Trigger_Output_Bit_Net")] + public static extern short MCF_Set_Trigger_Output_Bit_Net(ushort Bit_Output_Number, ushort Bit_Output_Enable, ushort StationNumber = 0); + + //1.3 链接监测函数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Link_State_Net")] + public static extern short MCF_Get_Link_State_Net(ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 2 通用输入输出函数 + ********************************************************************************************************************************************************************/ + //2.1 通用IO全部输出函数 [OUT31,OUT0] [0,99] [10000,10099] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Output_Net")] + public static extern short MCF_Set_Output_Net(uint All_Output_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Output_Net")] + public static extern short MCF_Get_Output_Net(ref uint All_Output_Logic, ushort StationNumber = 0); + //2.2 通用IO按位输出函数 宏定义2.3.1 宏定义2.3.2 [0,99] [10000,10099] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Output_Bit_Net")] + public static extern short MCF_Set_Output_Bit_Net(ushort Bit_Output_Number, ushort Bit_Output_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Output_Bit_Net")] + public static extern short MCF_Get_Output_Bit_Net(ushort Bit_Output_Number, ref ushort Bit_Output_Logic, ushort StationNumber = 0); + //2.4 通用IO全部输入函数 [Input31,Input0] [Input48,Input32] [0,99] [10000,10099] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Net")] + public static extern short MCF_Get_Input_Net(ref uint All_Input_Logic1, ref uint All_Input_Logic2, ushort StationNumber = 0); + //2.5 通用IO按位输入函数 宏定义2.4.1 宏定义2.4.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Input_Bit_Net")] + public static extern short MCF_Get_Input_Bit_Net(ushort Bit_Input_Number, ref ushort Bit_Input_Logic, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 3 轴专用输入输出函数 + ********************************************************************************************************************************************************************/ + //3.1 伺服使能设置函数 宏定义0.0 宏定义3.1 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Servo_Enable_Net")] + public static extern short MCF_Set_Servo_Enable_Net(ushort Axis, ushort Servo_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_Enable_Net")] + public static extern short MCF_Get_Servo_Enable_Net(ushort Axis, ref ushort Servo_Logic, ushort StationNumber = 0); + //3.2 伺服报警复位设置函数 宏定义0.0 宏定义3.2 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Servo_Alarm_Reset_Net")] + public static extern short MCF_Set_Servo_Alarm_Reset_Net(ushort Axis, ushort Alarm_Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_Alarm_Reset_Net")] + public static extern short MCF_Get_Servo_Alarm_Reset_Net(ushort Axis, ref ushort Alarm_Logic, ushort StationNumber = 0); + //3.3 伺服报警输入获取函数 宏定义0.0 宏定义3.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Servo_Alarm_Net")] + public static extern short MCF_Get_Servo_Alarm_Net(ushort Axis, ref ushort Servo_Alarm_State, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 4 轴设置函数 + ********************************************************************************************************************************************************************/ + //4.1 脉冲通道输出设置函数 宏定义0.0 宏定义4.1 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Pulse_Mode_Net")] + public static extern short MCF_Set_Pulse_Mode_Net(ushort Axis, uint Pulse_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Pulse_Mode_Net")] + public static extern short MCF_Get_Pulse_Mode_Net(ushort Axis, ref uint Pulse_Mode, ushort StationNumber = 0); + //4.2 位置设置函数 宏定义0.0 [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Position_Net")] + public static extern short MCF_Set_Position_Net(ushort Axis, int Position, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Position_Net")] + public static extern short MCF_Get_Position_Net(ushort Axis, ref int Position, ushort StationNumber = 0); + //4.3 编码器设置函数 宏定义0.0 [-2^31,(2^31-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Encoder_Net")] + public static extern short MCF_Set_Encoder_Net(ushort Axis, int Encoder, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Encoder_Net")] + public static extern short MCF_Get_Encoder_Net(ushort Axis, ref int Encoder, ushort StationNumber = 0); + //4.4 速度获取 宏定义0.0 [-2^15,(2^15-1)] [-2^15,(2^15-1)] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Vel_Net")] + public static extern short MCF_Get_Vel_Net(ushort Axis, ref double Command_Vel, ref double Encode_Vel, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 5 轴硬件触发停止运动函数 + ********************************************************************************************************************************************************************/ + //5.1 通用IO输入复用:做为紧急停止函数 宏定义2.4.1 宏定义5.1 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_EMG_Bit_Net")] + public static extern short MCF_Set_EMG_Bit_Net(ushort EMG_Input_Number, ushort EMG_Mode, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_EMG_Output_Net")] + public static extern short MCF_Set_EMG_Output_Net(ushort EMG_Input_Number, ushort EMG_Mode, uint EMG_Output, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_EMG_Output_Enable_Net")] + public static extern short MCF_Set_EMG_Output_Enable_Net(ushort Bit_Output_Number, ushort Bit_Output_Enable, ushort StationNumber = 0); + //5.11 轴状态触发停止运动查询函数 宏定义0.0 MC_Retrun.h[0,28] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Axis_State_Net")] + public static extern short MCF_Get_Axis_State_Net(ushort Axis, ref short Reason, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 7 点位运动控制函数 + ********************************************************************************************************************************************************************/ + //7.1 速度控制函数 宏定义0.0 (0,10M]P/S (0,1T]P^2/S [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_JOG_Net")] + public static extern short MCF_JOG_Net(ushort Axis, double dMaxV, double dMaxA, ushort StationNumber = 0); + //7.4 单轴曲线函数 宏定义0.0 [0,dMaxV] (0,10M]P/S (0,1T]P^2/S (0,100T]P^3/S [0,dMaxV] 宏定义0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Axis_Profile_Net")] + public static extern short MCF_Set_Axis_Profile_Net(ushort Axis, double dV_ini, double dMaxV, double dMaxA, double dJerk, double dV_end, ushort Profile, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Axis_Profile_Net")] + public static extern short MCF_Get_Axis_Profile_Net(ushort Axis, ref double dV_ini, ref double dMaxV, ref double dMaxA, ref double dJerk, ref double dV_end, ref ushort Profile, ushort StationNumber = 0); + //7.5 单轴运动函数 宏定义0.0 [-2^31,(2^31-1)] 宏定义0.3 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Uniaxial_Net")] + public static extern short MCF_Uniaxial_Net(ushort Axis, int dDist, ushort Position_Mode, ushort StationNumber = 0); + //7.6 单轴停止曲线函数 宏定义0.0 (0,1T]P^2/S (0,100T]P^3/S 宏定义0.4 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Axis_Stop_Profile_Net")] + public static extern short MCF_Set_Axis_Stop_Profile_Net(ushort Axis, double dMaxA, double dJerk, ushort Profile, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Axis_Stop_Profile_Net")] + public static extern short MCF_Get_Axis_Stop_Profile_Net(ushort Axis, ref double dMaxA, ref double dJerk, ref ushort Profile, ushort StationNumber = 0); + //7.7 轴停止函数 宏定义0.0 宏定义7.7 [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Axis_Stop_Net")] + public static extern short MCF_Axis_Stop_Net(ushort Axis, ushort Axis_Stop_Mode, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 16 光源控制器函数 + ********************************************************************************************************************************************************************/ + //16.1 设置光源模式(1MS阻塞函数) 宏定义16.1.1 0:关闭 1:24V常亮 2:24V频闪 3:48V爆闪 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Light_Mode_Net")] + public static extern short MCF_Set_Light_Mode_Net(ushort Channel, ushort Light_Mode, ushort StationNumber = 0); + //16.2 设置电流保护(1MS阻塞函数) 宏定义16.1.1 [0,15000] 单位:MA Over_Current/1000*0.1*11/3.3 * 4095 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Light_Current_Net")] + public static extern short MCF_Set_Light_Current_Net(ushort Channel, ushort Max_Current, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Light_Current_1_4_Net")] + public static extern short MCF_Get_Light_Current_1_4_Net(ref ushort Current_1, ref ushort Current_2, ref ushort Current_3, ref ushort Current_4, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Light_Current_5_8_Net")] + public static extern short MCF_Get_Light_Current_5_8_Net(ref ushort Current_5, ref ushort Current_6, ref ushort Current_7, ref ushort Current_8, ushort StationNumber = 0); + //16.3 设置光源输出(1MS阻塞函数) 宏定义16.1.1 常亮:[0,255] 频闪[0,1000] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Light_Output_Net")] + public static extern short MCF_Set_Light_Output_Net(ushort Channel, ushort Light_Size, ushort StationNumber = 0); + + /******************************************************************************************************************************************************************** + 17 系统函数 + ********************************************************************************************************************************************************************/ + //17.1 模块版本号 [0x00000000,0xFFFFFFFF] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Version_Net")] + public static extern short MCF_Get_Version_Net(ref uint Version, ushort StationNumber = 0); + //17.2 序列号 [0x00000000,0xFFFFFFFF] [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Serial_Number_Net")] + public static extern short MCF_Get_Serial_Number_Net(ref long Serial_Number, ushort StationNumber = 0); + //17.3 模块运行时间 [0x00000000,0xFFFFFFFF] [0,99] 单位:秒 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Get_Run_Time_Net")] + public static extern short MCF_Get_Run_Time_Net(ref uint Run_Time, ushort StationNumber = 0); + //17.4 Flash 读写功能目前暂时大小2Kbytes,也即定义一个 unsigned int Array[256] 存放数据 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Flash_Write_Net")] + public static extern short MCF_Flash_Write_Net(uint Pass_Word_Setup, ref uint Flash_Write_Data, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Flash_Read_Net")] + public static extern short MCF_Flash_Read_Net(uint Pass_Word_Check, ref uint Flash_Read_Data, ushort StationNumber = 0); + //17.8 系统定时回调函数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_CallBack_Net")] + public static extern short MCF_Set_CallBack_Net(int CallBack, uint Time_1MS); + + + + /******************************************************************************************************************************************************************** + 101 关闭自动筛选功能并清除来料,相机,吹气计数 注意:调用该函数后才可以设置102,103,104项目参数 + ********************************************************************************************************************************************************************/ + //101.1 设置参数前必须调用先关闭筛选功能 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Close_Net")] + public static extern short MCF_Sorting_Close_Net(ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 102 设置来料检测功能,用户根据需要设置 注意:自动筛选时禁止设置 + ********************************************************************************************************************************************************************/ + //102.1 物件最大最小尺寸 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Piece_Size_Net")] + public static extern short MCF_Sorting_Set_Piece_Size_Net(uint Max_Size, uint Min_Size, ushort StationNumber = 0); + //102.2 物件安全距离,安全时间 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Piece_Place_Net")] + public static extern short MCF_Sorting_Set_Piece_Place_Net(uint Min_Distance, uint Min_Time_Intervel, ushort StationNumber = 0); + //102.3 来料检测设置 + // 来料检测使能(默认Bit_Output_0,Bit_Output_1开,0:关 1:开) [Bit_Input_0,Bit_Input_3] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Input_Enable_Net")] + public static extern short MCF_Sorting_Set_Input_Enable_Net(ushort Bit_Input_Number, ushort Bit_Input_Enable, ushort StationNumber = 0); + // 来料检测电平(默认全部低电平, 0:低电平 1:高电平) [Bit_Input_0,Bit_Input_3] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Input_Logic_Net")] + public static extern short MCF_Sorting_Set_Input_Logic_Net(ushort Bit_Input_Number, ushort Bit_Input_Logic, ushort StationNumber = 0); + // 来料检测编码器(默认全部跟随Axis_1编码器) [Bit_Input_0,Bit_Input_3] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Input_Source_Net")] + public static extern short MCF_Sorting_Set_Input_Source_Net(ushort Bit_Input_Number, ushort Axis, ushort Source, ushort StationNumber = 0); + // 来料检测捕获位置(默认全部捕获前部, 0:前部 1:中间) [Bit_Input_0,Bit_Input_3] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Input_Position_Net")] + public static extern short MCF_Sorting_Set_Input_Position_Net(ushort Bit_Input_Number, ushort Mode, ushort StationNumber = 0); + + //102.4 DI00 检测不连续物件强制保持连续 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Piece_Keep_Net")] + public static extern short MCF_Sorting_Set_Piece_Keep_Net(uint Keep_Length, ushort StationNumber = 0); + //102.5 DI00 物件检测无料超时停止轴运动(默认时间0,表示不启动) [0,60000] &Array[DO00,DO15],0:低 1:高 2:关闭 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Input_0_TimeOut_Net")] + public static extern short MCF_Sorting_Set_Input_0_TimeOut_Net(uint Time_1MS, ref uint TimeOut_Output, ushort StationNumber = 0); + //102.6 通用IO按位输入滤波函数 [Bit_Input_0,Bit_Input_1] [1,100]MS [0,99] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Set_Input_Filter_Time_Bit_Net")] + public static extern short MCF_Set_Input_Filter_Time_Bit_Net(ushort Bit_Input_Number, uint Filter_Time_1MS, ushort StationNumber = 0); + //102.7 多个来料检测绑定相机触发,OK吹气,NG吹气 [Bit_Input_1] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Input_Bind_Net")] + public static extern short MCF_Sorting_Set_Input_Bind_Net(ushort Bit_Input_Number, ushort Camera_Start_Number, ushort Bond_Start_Number, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 103 设置OK,NG安全保护参数,用户根据需要设置 注意:自动筛选时禁止设置 + ********************************************************************************************************************************************************************/ + //103.1 物件吹气OK超时停止轴运动(默认时间0,表示不启动) [0,60000] &Array[DO00,DO15],0:低 1:高 2:关闭 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Trig_Blow_OK_TimeOut_Net")] + public static extern short MCF_Sorting_Set_Trig_Blow_OK_TimeOut_Net(uint Time_1MS, ref uint TimeOut_Output, ushort StationNumber = 0); + //103.2 物件吹气连续NG停止轴运动(默认时间0,表示不启动) [0,60000] &Array[DO00,DO15],0:低 1:高 2:关闭 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Trig_Blow_NG_NumberOut_Net")] + public static extern short MCF_Sorting_Set_Trig_Blow_NG_NumberOut_Net(uint NG_Number, ref uint NumberOut_Output, ushort StationNumber = 0); + //103.3 HMC3432S/HMC3412S 可以设置物件重新检测确定功能,以此判定是否误吹 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Blow_Check_Again_Net")] + public static extern short MCF_Sorting_Set_Blow_Check_Again_Net(ushort Bit_Input_Number, ushort Bit_Input_Logic, int Input_Position, uint Piece_Size, + ushort Blow_OK_Check, + ushort Blow_NG_Check, + ushort Blow_1_Check, + ushort Blow_2_Check, + ushort Blow_3_Check, + ushort Blow_4_Check, + ushort Blow_5_Check, + ushort Blow_6_Check, + ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Blow_Check_Lose_Number_Net")] + public static extern short MCF_Sorting_Get_Blow_Check_Lose_Number_Net(ref uint Lose_Number, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 104 设置相机吹气参数,用户必须设置 注意:自动筛选时禁止设置 + ********************************************************************************************************************************************************************/ + //104.1 HMC3432S 可以配置相机和吹气个数 [1,30] [1,30] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Camera_Blow_Config_Net")] + public static extern short MCF_Sorting_Camera_Blow_Config_Net(ushort Camera_Number, ushort Blow_Number, ushort StationNumber = 0); + //104.2 设置相机参数 与检测装置的相对位置 编码器反馈的运行方向 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Net")] + public static extern short MCF_Sorting_Set_Camera_Net(ushort Camera_Number, int Camera_Position, ushort Motion_Dir, ushort Action_Mode, ushort Action_IO, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Light_Frequency_Net")] + public static extern short MCF_Sorting_Set_Camera_Light_Frequency_Net(ushort Camera_Number, ushort Light_Number, ushort Frequency_Enable, ushort StationNumber = 0); + //104.3 设置运动控制卡触发相机拍照后,延时多少毫秒计数增加1,一般设置为 大于 控制卡从触发相机拍照到软件出图像结果需要的时间, + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Trig_Camera_Delay_Count_Net")] + public static extern short MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(ushort Camera_Number, double Camera_Delay_Count_MS, ushort StationNumber = 0); + //104.4 设置OK吹气参数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Blow_OK_Net")] + public static extern short MCF_Sorting_Set_Blow_OK_Net(int Blow_OK_Position, ushort Motion_Dir, ushort Action_Mode, ushort Action_IO, ushort StationNumber = 0); + //104.5 设置NG吹气参数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Blow_NG_Net")] + public static extern short MCF_Sorting_Set_Blow_NG_Net(int Blow_NG_Position, ushort Motion_Dir, ushort Action_Mode, ushort Action_IO, ushort StationNumber = 0); + //104.6 设置吹气1到30参数 [1,30] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Blow_Net")] + public static extern short MCF_Sorting_Set_Blow_Net(ushort Blow_Number, int Blow_Position, ushort Motion_Dir, ushort Action_Mode, ushort Action_IO, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 105 自动筛选功能启动函数 注意:调用该函数后禁止设置102,103,104项目参数 + ********************************************************************************************************************************************************************/ + //105.1 筛选启动函数,在设置好参数后启动 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Start_Net")] + public static extern short MCF_Sorting_Start_Net(ushort Mode = 0, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 106 物料图像结果处理 + ********************************************************************************************************************************************************************/ + //106.0 设置相机处理结果最短时间和最大超时时间,允许连续超时最大个数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Handle_Time_Net")] + public static extern short MCF_Sorting_Set_Camera_Handle_Time_Net(ushort Camera_Number, double Handle_Time_1MS, double Handle_TimeOut_1MS, uint Handle_TimeOut_Number, ushort StationNumber = 0); + //106.1 吹气模式0:用户综合所有相机结果后发送吹气指令 + // 用户在图像处理回调函数中调用该函数通知图像处理结果 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Result_Data_Net")] + public static extern short MCF_Sorting_Set_Camera_Result_Data_Net(ushort Camera_Number, uint Result_Data, ushort StationNumber = 0); + // 用户开辟线程检查物料最新的图像结果 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Camera_Result_Updata_Net")] + public static extern short MCF_Sorting_Get_Camera_Result_Updata_Net(ushort Camera_Number, ref uint Piece_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Camera_Result_Buffer_Net")] + public static extern short MCF_Sorting_Get_Camera_Result_Buffer_Net(ushort Camera_Number, uint Piece_Number, ref uint Result_Buffer, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Camera_Handle_Time_Net")] + public static extern short MCF_Sorting_Get_Camera_Handle_Time_Net(ushort Camera_Number, uint Piece_Number, ref uint Handle_Time, ushort StationNumber = 0); + // 用户根据图像结果吹气 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Trig_Blow_OK_Net")] + public static extern short MCF_Sorting_Set_Trig_Blow_OK_Net(uint Piece_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Trig_Blow_NG_Net")] + public static extern short MCF_Sorting_Set_Trig_Blow_NG_Net(uint Piece_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Trig_Blow_Net")] + public static extern short MCF_Sorting_Set_Trig_Blow_Net(ushort Blow_Number, uint Piece_Number, ushort StationNumber = 0); + //106.2 吹气模式1:用户直接发送每个相机结果,控制卡自动综合结果后吹气 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Result_OK_Net")] + public static extern short MCF_Sorting_Set_Camera_Result_OK_Net(ushort Camera_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Result_NG_Net")] + public static extern short MCF_Sorting_Set_Camera_Result_NG_Net(ushort Camera_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Blow_Result_OK_Net")] + public static extern short MCF_Sorting_Get_Blow_Result_OK_Net(ref uint Result_OK_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Blow_Result_NG_Net")] + public static extern short MCF_Sorting_Get_Blow_Result_NG_Net(ref uint Result_NG_Number, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Blow_Result_Miss_Net")] + public static extern short MCF_Sorting_Get_Blow_Result_Miss_Net(ref uint Result_Miss_Number, ushort StationNumber = 0); + + //106.3 吹气模式2:用户不需要发送相机结果,控制卡通过IO综合结果后吹气,全程通过硬件实现,可以直接替代PLC (0,500] + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Result_Input_OK_Net")] + public static extern short MCF_Sorting_Set_Camera_Result_Input_OK_Net(ushort Camera_Number, ushort Input_Number, ushort Logic, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Set_Camera_Result_Input_NG_Net")] + public static extern short MCF_Sorting_Set_Camera_Result_Input_NG_Net(ushort Camera_Number, ushort Input_Number, ushort Logic, ushort StationNumber = 0); + /******************************************************************************************************************************************************************** + 107 物件,相机,吹气状态监测函数 + ********************************************************************************************************************************************************************/ + //107.0 筛选监测函数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_State_Net")] + public static extern short MCF_Sorting_Get_State_Net(ref ushort State, ushort StationNumber = 0); + + //107.1 获取DI00物件不合格计数个数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Piece_Pass_Net")] + public static extern short MCF_Sorting_Get_Piece_Pass_Net(ushort Piece_Input_Number, ref uint Piece_Pass, ushort StationNumber = 0); + //107.2 获取DI00物件计数个数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Piece_State_Net")] + public static extern short MCF_Sorting_Get_Piece_State_Net(ushort Piece_Input_Number, //物件计数的输入端口号 + ref uint Piece_Find, //物件匹配统计数量 + ref uint Piece_Size, //物件大小,10组 + ref uint Piece_Distance_To_next, //物件间距,10组 + ref uint Piece_Cross_Camera, //物件经过所有相机个数 + ushort StationNumber = 0); + //107.3 获取判断控制卡触发相机拍照计数,图像结果输出结果一定要先于延时后的控制卡相机拍照计数,而且要一一对应,否则做为图像异常或者漏拍处理 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Trig_Camera_Count_Net")] + public static extern short MCF_Sorting_Get_Trig_Camera_Count_Net(ushort Camera_Number, ref uint Trig_Camera_Count, ushort StationNumber = 0); + //107.4 获取OK,NG触发计数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Trig_Blow_NG_Count_Net")] + public static extern short MCF_Sorting_Get_Trig_Blow_NG_Count_Net(ref uint Trig_Blow_NG_Count, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Trig_Blow_OK_Count_Net")] + public static extern short MCF_Sorting_Get_Trig_Blow_OK_Count_Net(ref uint Trig_Blow_OK_Count, ushort StationNumber = 0); + //107.5 获取OK,NG漏触发计数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Lose_Blow_NG_Count_Net")] + public static extern short MCF_Sorting_Get_Lose_Blow_NG_Count_Net(ref uint Lose_Blow_NG_Count, ushort StationNumber = 0); + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Lose_Blow_OK_Count_Net")] + public static extern short MCF_Sorting_Get_Lose_Blow_OK_Count_Net(ref uint Lose_Blow_OK_Count, ushort StationNumber = 0); + //107.6 获取气阀吹气计数 + [DllImport("MCDLL_NET.DLL", EntryPoint = "MCF_Sorting_Get_Trig_Blow_Count_Net")] + public static extern short MCF_Sorting_Get_Trig_Blow_Count_Net(ushort Blow_Number, ref uint Trig_Blow_Count, ushort StationNumber = 0); + + } +} \ No newline at end of file diff --git a/DH.Devices.Motion/MotionBase.cs b/DH.Devices.Motion/MotionBase.cs new file mode 100644 index 0000000..9540fe6 --- /dev/null +++ b/DH.Devices.Motion/MotionBase.cs @@ -0,0 +1,1239 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Design; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using DH.Commons.Enums; + +namespace DH.Devices.Motion +{ + public class MotionBase + { + //[Category("板卡配置")] + //[DisplayName("板卡站号")] + //[Description("板卡站号")] + //public virtual ushort StationNumber { get; set; } = 0; + + public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning); + protected Dictionary _axisAlarmRaisedFlag = new Dictionary(); + protected Dictionary _axisLimitTimer = new Dictionary(); + + //[Category("扩展卡设置")] + //[Description("扩展卡数量")] + //[DisplayName("扩展卡数量")] + //public ushort CardExtNum { get; set; } = 0; + + public List AxisStatusList { get; set; } = new List(); + + + + public virtual void Init() { } + + public virtual void Start() { } + + public virtual void Stop() { } + public virtual void ResetImmediatePause(bool isResumeMoving) { } + + public virtual bool AllAxisOn() { return false; } + + public virtual void SetImmediatePause() { } + + + + public virtual bool AllAxisOff() { return false; } + + public virtual async Task AxisOnAsync(int axisNum){ } + + public virtual async Task AxisOffAsync(int axisNum) { } + + public virtual List GetCurrentAxisInfo(params string[] axisName) { return new List(); } + + public bool isconnected=false; + + + [Category("板卡配置")] + [DisplayName("板卡型号")] + [Description("板卡型号")] + public BoardModelEnum BoardModel { get; set; } = BoardModelEnum.EC3416; + + + + + [Category("板卡配置")] + [DisplayName("扩展板类型")] + [Description("扩展板类型")] + public ExtensionBoardEnum ExtBoard { get; set; } = ExtensionBoardEnum.None; + + + + [Category("机台配置")] + [DisplayName("机台类型")] + [Description("机台类型")] + public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.DoubleDisk; + + + + + [Category("轴配置")] + [DisplayName("轴数量")] + [Description("AxisNum:轴数量")] + public int AxisNum { get; set; } = 4; + + + [Category("轴配置")] + [DisplayName("轴配置信息集合")] + [Description("AxisSettings:轴配置信息集合")] + public List AxisSettings { get; set; } = new List(); + + [Category("轴配置")] + [DisplayName("轴速度比率")] + [Description("AxisVelocityRatio:轴速度比率")] + public double AxisVelocityRatio { get; set; } = 1; + + //[Category("警报配置")] + //[Description("WarningSetCollection:警报配置列表")] + //[DisplayName("警报配置")] + //[TypeConverter(typeof(CollectionCountConvert))] + //[Editor(typeof(WarningSetsEditor), typeof(UITypeEditor))] + //public List WarningSetCollection { get; set; } = new List(); + + [Category("IO配置")] + [Description("输入IO总数")] + [DisplayName("输入IO总数")] + public int InputNums { get; set; } = 16; + + [Category("IO配置")] + [Description("输出IO总数")] + [DisplayName("输出IO总数")] + public int OutputNums { get; set; } = 16; + + //[Category("IO配置")] + //[DisplayName("IO定义集合")] + //[Description("IO定义集合")] + //[TypeConverter(typeof(CollectionCountConvert))] + //[Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] + //public List IODefinitionCollection { get; set; } = new List(); + + [Category("IO配置")] + [DisplayName("是否信号模式")] + [Description("true:信号模式,绿色表示有信号,灰色表示无信号 false:电平模式,绿色高电平,灰色低电平,一般情况下低电平表示有信号,板卡默认是电平模式")] + public bool IsSignalMode { get; set; } = false; + + #region IMonitorConfig + //[Category("监听设置")] + //[Description("MonitorSetCollection:监听操作配置集合")] + //[DisplayName("监听配置")] + //[TypeConverter(typeof(CollectionCountConvert))] + //[Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] + //public List MonitorSetCollection { get; set; } = new List(); + + [Category("监听设置")] + [Description("true:启动监听 false:关闭监听")] + [DisplayName("监听启用")] + public bool IsEnableMonitor { get; set; } = false; + + [Category("监听设置")] + [Description("扫描间隔时间,单位:ms")] + [DisplayName("扫描间隔")] + public int MonitorInterval { get; set; } = 20; + + [Category("监听设置")] + [Description("超时设置,单位:ms")] + [DisplayName("监听超时")] + public int MonitorTimeout { get; set; } = 500; + + //public List GetAllMonitorSet() + //{ + // WarningSetCollection.ForEach(m => m.SourceDevice = this.Name); + // MonitorSetCollection.ForEach(m => m.SourceDeviceId = this.Id); + // return MonitorSetCollection; + //} + #endregion + + + + + #region 转盘卡新增配置 + + + [Category("筛选配置")] + [DisplayName("启用转盘卡自动筛选功能")] + [Description("启用转盘卡自动筛选功能")] + public bool IsEnableFilter { get; set; } = true; + + [Category("筛选配置")] + [DisplayName("启用转盘卡盘2触发取反")] + [Description("启用转盘卡盘2触发取反")] + public bool DiskSnaptChange { get; set; } = false; + + + + [Category("筛选配置")] + [DisplayName("第二路来料检测配置")] + [Description("第二路来料检测配置")] + public SortingInputSetting SortingInputSetting { get; set; } = new SortingInputSetting(); + + + + [Category("筛选配置")] + [DisplayName("相机配置")] + [Description("相机配置")] + public List SnapshotSettings { get; set; } = new List(); + + + + + + [Category("筛选配置")] + [DisplayName("吹气口配置")] + [Description("吹气口配置")] + public List BlowSettings { get; set; } = new List(); + + + //[Category("筛选配置")] + //[DisplayName("转盘运转方向")] + //[Description("转盘运转方向,顺时针或逆时针")] + //[TypeConverter(typeof(EnumDescriptionConverter))] + //public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise; + + + + [Category("筛选配置")] + [DisplayName("物料尺寸最大值")] + [Description("物料尺寸最大值,单位:脉冲")] + public uint PieceMaxSize { get; set; } = 2000; + + + [Category("筛选配置")] + [DisplayName("物料尺寸最小值")] + [Description("物料尺寸最小值,单位:脉冲")] + public uint PieceMinSize { get; set; } = 1500; + + + [Category("筛选配置")] + [DisplayName("物料最小间隔")] + [Description("物料最小间隔,单位:脉冲")] + public uint MinDistance { get; set; } = 2000; + + [Category("筛选配置")] + [DisplayName("两个物料之间触发最小间隔时间")] + [Description("两个物料之间触发最小间隔时间,单位:ms")] + public uint MinTimeInterval { get; set; } = 10; + + + + [Category("急停配置")] + [DisplayName("启用转盘卡硬件急停")] + [Description("启用转盘卡硬件急停")] + public bool IsEnableEmgStop { get; set; } = false; + + + [Category("急停配置")] + [DisplayName("急停信号触发索引")] + [Description("急停信号触发索引")] + public ushort EmgStopSignalIoIndex { get; set; } = 4; + + + [Category("急停配置")] + [DisplayName("急停触发信号")] + [Description("急停触发信号")] + public EMG_Mode EmgMode { get; set; } = EMG_Mode.EMG_Trigger_High_IMD; + + + + + + + #endregion + + + public List CurrentIOs { get; set; } = new List(); + + } + + /// + /// 吹气口配置 + /// + public class BlowSetting + { + + [Category("板卡配置")] + [DisplayName("板卡站号")] + [Description("板卡站号")] + public virtual ushort StationNumber { get; set; } = 0; + + + + + [Category("吹气口配置")] + [DisplayName("是否启用")] + [Description("是否启用")] + public bool IsEnabled { get; set; } = false; + + [Category("吹气口配置")] + [DisplayName("转盘运转方向")] + [Description("转盘运转方向")] + public RotationDirectionEnum RotationDirection { get; set; } = RotationDirectionEnum.Clockwise; + + //[Category("吹气口配置")] + //[DisplayName("吹气口名称")] + //[Description("吹气口名称")] + //public string Name { get; set; } = ""; + + + [Category("吹气口配置")] + [DisplayName("吹气口位置")] + [Description("吹气口位置,即吹气口到入料检测传感器的相对位置,单位:脉冲")] + public int BlowPosition { get; set; } = 0; + + + [Category("吹气口配置")] + [DisplayName("输出信号")] + [Description("输出信号")] + public ActionMode ActionMode { get; set; } = ActionMode.OutputPulse10ms; + + [Category("吹气口配置")] + [DisplayName("吹气口IO")] + [Description("吹气口IO")] + public IODefinition BlowIO { get; set; } = new IODefinition() { IOType = IOType.OUTPUT }; + + + + [Category("吹气口配置")] + [DisplayName("吹气口类型")] + [Description("吹气口类型")] + public BlowType BlowType { get; set; } + + + //public string GetDisplayText() + //{ + // //return $"{BlowType.GetEnumDescription()} 距离{BlowPosition} 输出{BlowIO.GetDisplayText()}"; + //} + } + public class SnapshotSetting : IComparable + { + + [Category("板卡配置")] + [DisplayName("板卡站号")] + [Description("板卡站号")] + public virtual ushort StationNumber { get; set; } = 0; + + + [Category("取像相机设置")] + [DisplayName("转盘运转方向")] + [Description("转盘运转方向")] + public RotationDirectionEnum RotationDirection { get; set; } = RotationDirectionEnum.Clockwise; + + + [Category("取像相机设置")] + [DisplayName("是否启用")] + [Description("是否启用")] + public bool IsEnabled { get; set; } = false; + + + [Category("取像相机设置")] + [Description("取像相机")] + [DisplayName("取像相机")] + public string CameraId { get; set; } + + + [Category("取像相机设置")] + [DisplayName("相机触发延时毫秒")] + [Description("相机触发后延时显示,单位ms")] + public double CameraDelayCountMS { get; set; } = 0; + + + [Category("取像相机设置")] + [DisplayName("相机位置")] + [Description("相机位置,即相机到入料检测传感器的相对位置,单位:脉冲")] + public int CameraPosition { get; set; } = 0; + + + + [Category("取像相机设置")] + [DisplayName("相机IO")] + [Description("相机IO")] + public IODefinition CameraIO { get; set; } = new IODefinition() { IOType = IOType.OUTPUT }; + + + [Category("取像相机设置")] + [DisplayName("输出信号")] + [Description("输出信号,取决于相机触发模式及转盘速度")] + public ActionMode ActionMode { get; set; } = ActionMode.OutputPulse10ms; + + + + //[Category("获取结果")] + //[Description("调用方法")] + //[DisplayName("调用方法")] + //[TypeConverter(typeof(ProcessMethodSelectorConverter))] + //public string MethodCode { get; set; } + + + public int CompareTo(object obj) + { + if (obj is SnapshotSetting setting) + { + // return Math.Abs(CameraPosition).CompareTo(Math.Abs(setting.CameraPosition)); + return CameraPosition.CompareTo(setting.CameraPosition); + } + return 0; + } + + //public string GetDisplayText() + //{ + // //string cameraName = ""; + // //using (var scope = GlobalVar.Container.BeginLifetimeScope()) + // //{ + // // List devices = scope.Resolve>(); + // // cameraName = devices.FirstOrDefault(u => u.Id == CameraId)?.Name ?? ""; + // //} + + // //// return $"{cameraName} :{IOItem.GetDisplayText()};{cameraName} {DetectType.GetEnumDescription()}"; + // //return $"{cameraName} 距离{CameraPosition} 输出{CameraIO.GetDisplayText()}"; + //} + } + /// + /// 轴配置 + /// + public class AxisSetting + { + [Category("轴配置")] + [DisplayName("轴号索引")] + [Description("AxisIndex:轴号索引")] + public int AxisIndex { get; set; } + + [Category("轴配置")] + [DisplayName("轴名称")] + [Description("AxisName:轴名称")] + public string AxisName { get; set; } + + [Category("轴配置")] + [DisplayName("轴是否启用")] + [Description("IsAxisEnabled:轴是否启用")] + public bool IsAxisEnabled { get; set; } = false; + + [Category("换算配置")] + [DisplayName("脉冲数换算比例")] + [Description("脉冲数和其他计量单位的换算比例,例如设置为1000,表示1000个脉冲等于1uint")] + public int AxisRatio { get; set; } = 1; + + [Category("监听设置")] + [Description("true:监听位置信息 false:不监听位置信息")] + [DisplayName("位置监听")] + public bool IsMonitorPosition { get; set; } = true; + + [Category("监听设置")] + [Description("true:监听状态信息 false:不监听状态信息")] + [DisplayName("状态监听")] + public bool IsMonitorStatus { get; set; } = true; + + [Category("捕获设置")] + [Description("true:启用捕获监听 false:不启用捕获监听")] + [DisplayName("捕获监听")] + public bool IsMonitorCapture { get; set; } = true; + + [Category("速度配置")] + [DisplayName("默认速度参数")] + [Description("VelocityPara:默认速度参数")] + public VelocityPara VelocityPara { get; set; } = new VelocityPara(); + + //[Category("回原点设置")] + //[DisplayName("回原点模式")] + //[Description("HomeMode:回原点模式。0:一般模式 1:极限限位模式 2:外部触发模式")] + //public int HomeMode { get; set; } = 0; + + //[Category("回原点设置")] + //[DisplayName("回原点方向")] + //[Description("IsHomePositive:回原点方向。 true:正方向开始 false:负方向开始")] + //public bool IsHomePositive { get; set; } = true; + + //[Category("回原点设置")] + //[DisplayName("是否自动回原点")] + //[Description("IsAutoGoHome:是否自动回原点。 true:是 false:否")] + //public bool IsAutoGoHome { get; set; } = false; + + //[Category("超时设置")] + //[DisplayName("回原点超时")] + //[Description("TimeOutHome:回原点超时,单位毫秒")] + //public int TimeOutHome { get; set; } = 30000; + + //[Category("超时设置")] + //[DisplayName("运动超时")] + //[Description("TimeOutMove:运动超时,单位毫秒")] + //public int TimeOutMove { get; set; } = 10000; + + //[Category("开闭环设置")] + //[DisplayName("是否使用Cmmd回馈")] + //[Description("IsUseCmmdPosition:是否使用Cmmd回馈")] + //public bool IsUseCmmdPosition { get; set; } = false; + + //[Category("开闭环设置")] + //[DisplayName("是否使用板卡反馈停止信号")] + //[Description("IsUseMDNStopSignal:是否使用板卡反馈停止信号")] + //public bool IsUseMDNStopSignal { get; set; } = false; + + //[Category("开闭环设置")] + //[DisplayName("是否启用报警")] + //[Description("IsUseWarning:是否启用报警")] + //public bool IsUseWarning { get; set; } = false; + + + [Category("伺服报警")] + [DisplayName("是否启用报警")] + [Description("是否启用报警")] + public bool IsUseAlarm { get; set; } = true; + + + [Category("伺服报警")] + [DisplayName("报警复位电平")] + [Description("报警复位电平")] + public LogicLevelEnum AlarmLogic { get; set; } = LogicLevelEnum.LowLevel; + + + + [Category("原点配置")] + [DisplayName("回原点参数")] + [Description("回原点参数")] + + public GoHomePara GoHomePara { get; set; } = new GoHomePara(); + + + [Category("暂停配置")] + [DisplayName("是否启用立即暂停")] + [Description("IsImmediatePause:是否启用立即暂停")] + public bool IsImmediatePause { get; set; } = false; + + public string GetDisplayText() + { + return AxisIndex + "-" + AxisName + "-" + (IsAxisEnabled ? "启用" : "禁用"); + } + } + + /// + /// 速度参数对象 + /// + public class VelocityPara + { + [Category("速度配置")] + [DisplayName("速度")] + [Description("Velocity:速度,为0时表示不修改当前设置")] + public double Velocity { get; set; } = 0; + + [Category("速度配置")] + [DisplayName("加速度")] + [Description("Acc:加速度,为0时表示不修改当前设置")] + public double Acc { get; set; } = 0; + + [Category("速度配置")] + [DisplayName("减速度")] + [Description("减速度,为0时表示不修改当前设置")] + public double Dec { get; set; } = 0; + + + + public string GetDisplayText() + { + return $"速度:{Velocity} 加速度:{Acc} 减速度:{Dec}"; + } + } + + /// + /// 回原点参数对象 + /// + public class GoHomePara + { + [Category("回原点参数")] + [DisplayName("回原点方式")] + [Description("HomeMode:回原点方式")] + public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Stop_HNeO_Offset_Po; + + + [Category("回原点参数")] + [DisplayName("正负限位触发电平")] + [Description("LimitLogic:正负限位触发电平")] + public LogicLevelEnum LimitLogic { get; set; } = LogicLevelEnum.LowLevel; + + [Category("回原点参数")] + [DisplayName("原点限位触发电平")] + [Description("HomeLogic:原点限位触发电平")] + + public LogicLevelEnum HomeLogic { get; set; } = LogicLevelEnum.LowLevel; + + [Category("回原点参数")] + [DisplayName("Index触发电平")] + [Description("IndexLogic:Index触发电平")] + + public LogicLevelEnum IndexLogic { get; set; } = LogicLevelEnum.LowLevel; + + + [Category("回原点参数")] + [DisplayName("捕捉位置模式")] + [Description("TriggerSource:捕捉位置模式")] + + public PositionSourceEnum TriggerSource { get; set; } = PositionSourceEnum.CommandPosition; + + + + [Category("回原点加速时间")] + [DisplayName("高速段加速时间")] + [Description("高速段加速时间,单位:ms")] + public ushort H_dMaxA_Time { get; set; } = 10; + + + [Category("回原点加速时间")] + [DisplayName("低速段加速时间")] + [Description("低速段加速时间,单位:ms")] + public ushort L_dMaxA_Time { get; set; } = 10; + + + + [Category("回原点参数")] + [DisplayName("偏移位置")] + [Description("偏移位置,按回零模式中的方向偏移")] + public int OffsetPosition { get; set; } = 0; + + + + [Category("回原点参数")] + [DisplayName("碰撞原点缓停时间")] + [Description("SearchHomeStopTime:触发缓停时间,范围 0-1000ms,(默认:急停)。注意:设置碰撞原点缓停时间,需要配合回零设置的高速段速度,和低速度速度的搭配。设置大了会出现过冲的现象,设置小了停止的时候会有抖动,需要调节时间,尽量设置找到原点时候在开关中间。")] + public ushort SearchHomeStopTime { get; set; } = 0; + + + + + + [Category("回原点速度")] + [DisplayName("高速段速度")] + [Description("高速段速度")] + public double H_dMaxV { get; set; } = 10000; + + [Category("回原点速度")] + [DisplayName("低速段速度")] + [Description("低速段速度")] + public double L_dMaxV { get; set; } = 3000; + + + + + + [Category("回原点超时")] + [DisplayName("回原点超时")] + [Description("回原点超时,单位秒")] + public int GoHomeTimeOut { get; set; } = 60; + } + + + + /// + /// 回原点的状态 + /// + public class GoHomeStatus + { + [Category("回原点状态")] + [DisplayName("回原点状态")] + [Description("回原点状态,0:回零成功,31:回零错误,32:正在回零")] + public ushort Status { get; set; } + + + + } + + /// + /// 轴状态对象 + /// + public class AxisMovingStatus + { + /// + /// 卡号、 核号 + /// + public int StationNumber { get; set; } = 0; + + /// + /// 轴索引 + /// + public int AxisIndex { get; set; } + + /// + /// 轴名称 + /// + public string AxisName { get; set; } + + /// + /// 当前位置 + /// + public int CurPosition { get; set; } + + /// + /// 目的地 + /// + public int PrfPosition { get; set; } + + /// + /// 当前速度参数 + /// + public double CurVelocity { get; set; } + + /// + /// 规划速度参数 + /// + public double PrfVelocity { get; set; } + + /// + /// 轴状态 + /// + public int AxisStatus { get; set; } + + public bool Alarm { get; set; } = false; + public bool Enable { get; set; } = false; + public bool PositiveLimit { get; set; } = false; + public bool NegativeLimit { get; set; } = false; + + + public bool IsMonitorPosition { get; set; } + + public bool IsMonitorStatus { get; set; } + + //public string GetDisplayText() + //{ + // //return $"轴{AxisIndex}:{AxisName}-当前状态:{AxisStatus}-当前位置:{CurPosition}"; + //} + } + + + + + public class AxisInfo + { + public string AxisName { get; set; } + public double AxisLocation { get; set; } + + public string GetDisplayText() + { + return $"{AxisName}:{AxisLocation}"; + } + } + + + public class IODefinition : IOItem + { + [Category("IO配置")] + [Description("IO预定义")] + public IOPrestatement IOPreStatement { get; set; } = IOPrestatement.Customized; + + [Category("IO配置")] + [Description("IO用途描述")] + public string IODesc { get; set; } + + [Category("IO配置")] + [Description("备注说明")] + public string Remark { get; set; } + + + //[Category("IO配置")] + //[Description("IO初始值,Flase为0(低电平),Ture为1(高电平)")] + //public bool InitialValue { get; set; } = false; + + + + + [Browsable(false)] + [JsonIgnore] + public override IOValue IOValue { get; set; } + + //public override string GetDisplayText() + //{ + // return $"{(IOPreStatement == IOPrestatement.Customized ? IODesc : IOPreStatement.GetEnumDescription())} {IOType.GetEnumDescription()} {IOIndex}"; + //} + } + + + public class IOItem : IEqualityComparer + { + /// + /// IO点编号 + /// + [Category("IO配置")] + [Description("IO点索引")] + public virtual int IOIndex { get; set; } + + /// + /// IO点的值 + /// + [Category("IO配置")] + [Description("IO状态")] + public virtual IOValue IOValue { get; set; } + + /// + /// IO点是in还是out + /// + [Category("IO配置")] + [Description("IO类型")] + public virtual IOType IOType { get; set; } + + public new bool Equals(object x, object y) + { + if (x is IOItem a && y is IOItem b) + { + return a.IOType == b.IOType && a.IOIndex == b.IOIndex; + } + + return false; + } + + //public virtual string GetDisplayText() + //{ + // return $"{IOType.GetEnumDescription()}-{IOIndex}-{IOValue.GetEnumDescription()}"; + //} + + public int GetHashCode(object obj) + { + return obj.GetHashCode(); + } + } + + + public class SortingInputSetting + { + + [Category("入料检测配置")] + [DisplayName("启用入料检测")] + [Description("启用入料检测")] + public bool Enable { get; set; } = false; + + + [Category("入料检测配置")] + [DisplayName("位号")] + [Description("位号")] + + public BitInputNumberEnum BitInputNumber { get; set; } = BitInputNumberEnum.BitInput0; + + + [Category("入料检测配置")] + [DisplayName("物件检测有效电平")] + [Description("物件检测有效电平")] + public LogicLevelEnum InputLogic { get; set; } = LogicLevelEnum.LowLevel; + + + [Category("入料检测配置")] + [DisplayName("物件检测有效电平")] + [Description("物件检测有效电平")] + public ushort AxisIndex { get; set; } = 0; + + + + + [Category("入料检测配置")] + [DisplayName("跟随方式")] + [Description("跟随方式")] + public PositionSourceEnum PositionSource { get; set; } = PositionSourceEnum.EncoderPosition; + + + + [Category("入料检测配置")] + [DisplayName("入料检测捕获位置")] + [Description("入料检测捕获位置")] + public SortingInputPositionModeEnum SortingInputPositionMode { get; set; } = SortingInputPositionModeEnum.Front; + + + + [Category("相机绑定配置")] + [DisplayName("启用相机绑定")] + [Description("启用相机绑定")] + public bool EnableBindCamera { get; set; } = false; + + + [Category("相机绑定配置")] + [DisplayName("起始相机号")] + [Description("起始相机号")] + public ushort CameraStartNumber { get; set; } = 0; + + + + + [Category("吹气绑定配置")] + [DisplayName("启用吹气绑定")] + [Description("启用吹气绑定")] + public bool EnableBindBlow { get; set; } = false; + + + [Category("吹气绑定配置")] + [DisplayName("起始气阀号")] + [Description("起始气阀号")] + public ushort BlowStartNumber { get; set; } = 0; + + + + //public string GetDisplayText() + //{ + // return $"{BitInputNumber.GetEnumDescription()} 启用相机绑定{EnableBindCamera.ToString()} 启用吹气绑定{EnableBindBlow.ToString()}"; + //} + } + + #region 源程序运行调用类,未复制完,太复杂注释掉 + + public class ResponseMessage + { + public ResponseMessage() { } + + public int Code { get; set; } + + public int Result { get; set; } = 1; + + public string Message { get; set; } + + public string DataJson { get; set; } + + [JsonIgnore] + public object DataObj { get; set; } = null; + + /// + /// 执行结果数据集合 + /// + public List DataList { get; set; } = new List(); + + public void GetMessageFromException(Exception ex, int code = 9999) + { + Code = code; + //Message = ex.GetExceptionMessage(); + + Result = -1; + } + + public ResponseMessage(int result) + { + Result = result; + } + + public ResponseMessage(bool resultFlag, List datas = null) + { + Result = resultFlag ? 1 : -1; + + if (datas != null) + { + DataList = new List(datas); + } + } + + public ResponseMessage(int resultFlag, List datas = null) + { + Result = resultFlag; + + if (datas != null) + { + DataList = new List(datas); + } + } + + public ResponseMessage(bool result, string msg) + { + Result = result ? 1 : -1; + Message = msg; + } + + public string GetDisplayText() + { + return $"{Result} | {(DataList.Count > 0 ? string.Join(" ", DataList) : "NA")}"; + } + } + + public interface IOperationConfig //: IOperationResult + { + /// + /// 发生异常时的重新尝试次数 + /// + int ReTryTimes { get; set; } + + /// + /// 输入参数 + /// + List InputPara { get; set; } + + int TriggerValue { get; set; } + + /// + /// 当异常发生时的异常反馈值 + /// + int ExceptionValue { get; set; } + + /// + /// 指示该操作的监视配置来源 + /// + string MonitorSetId { get; set; } + + /// + /// 调用该操作配置的设备Id + /// + string ExecuteDeviceId { get; set; } + + /// + /// 操作执行后部分输出结果,目前拟采用序列化后的字符串方式保存 + /// + string OutputData { get; set; } + } + + + public class SolidMotionCardOperationConfigBase : OperationConfigBase + { + [Category("板卡操作")] + [Description("板卡操作配置基类集合,依次执行")] + + public List OperationCollection { get; set; } = new List(); + + + } + + public class OperationConfigBase : IOperationConfig//, ISourceDevice + { + /// + /// 输入参数 + /// + [JsonIgnore] + [Category("输入配置")] + [Description("输入参数配置")] + [DisplayName("输入参数")] + //[TypeConverter(typeof(SimpleCollectionConvert))] + public virtual List InputPara { get; set; } = new List(); + + /// + /// 异常反馈值 + /// + [Category("异常反馈设置")] + [Description("异常反馈值")] + [DisplayName("异常反馈值")] + public virtual int ExceptionValue { get; set; } = 0; + + /// + /// 发生异常时的重新尝试次数 + /// + [Category("异常反馈设置")] + [Description("发生异常时的重新尝试次数")] + [DisplayName("重试次数")] + public virtual int ReTryTimes { get; set; } = 3; + + [Browsable(false)] + public string MonitorSetId { get; set; } = ""; + + [Browsable(false)] + [JsonIgnore] + public virtual string ExecuteDeviceId { get; set; } = ""; + + //[Browsable(false)] + //[JsonIgnore] + //public virtual string SourceDeviceId { get; set; } = ""; + + [Browsable(false)] + [JsonIgnore] + public virtual string OutputData { get; set; } = ""; + + [Browsable(false)] + [JsonIgnore] + public virtual int TriggerValue { get; set; } + } + + public class SolidMotionCardOperationSet : IOOperationConfigBase + { + #region Ignore + [JsonIgnore] + [Browsable(false)] + public override List InputPara { get; set; } = new List(); + + /// + /// 异常反馈值 + /// + [JsonIgnore] + [Browsable(false)] + public override int ExceptionValue { get; set; } = 0; + + /// + /// 发生异常时的重新尝试次数 + /// + [JsonIgnore] + [Browsable(false)] + public override int ReTryTimes { get; set; } = 1; + #endregion + + [Category("2.板卡运动配置")] + [DisplayName("运动配置集合")] + [Description("MovingOps:多轴并发,运动配置集合")] + public List MovingOps { get; set; } = new List(); + + [Category("5.操作延时")] + [DisplayName("操作前延时")] + [Description("操作前延时,单位ms")] + public override int DelayBefore { get; set; } = 0; + + [Category("5.操作延时")] + [DisplayName("操作后延时")] + [Description("操作后延时,单位ms")] + public override int DelayAfter { get; set; } = 0; + + + } + + public class IOOperationConfigBase : OperationConfigBase + { + [Category("\t\t\tIO操作配置")] + [DisplayName("1.IO预检查")] + [Description("IO预检查定义集合")] + + public List PreCheckIOCollection { get; set; } = new List(); + + [Category("\t\t\tIO操作配置")] + [Description("超时设置,单位:ms")] + [DisplayName("2.IO预检查超时")] + public int PreCheckIOTimeout { get; set; } = 0; + + [Category("\t\t\tIO操作配置")] + [DisplayName("3.IO输出")] + [Description("IO输出定义集合")] + public List IOOutputCollection { get; set; } = new List(); + + [Category("\t\t\tIO操作配置")] + [DisplayName("4.IO输出确认")] + [Description("IO确认定义集合")] + public List IOConfirmCollection { get; set; } = new List(); + + [Category("\t\t\tIO操作配置")] + [Description("超时设置,单位:ms")] + [DisplayName("5.IO输出确认超时")] + public int IOConfirmTimeout { get; set; } = 0; + + [Category("\t\t\tIO操作配置")] + [Description("IO操作前延时,单位ms")] + public virtual int DelayBefore { get; set; } = 0; + + [Category("\t\t\tIO操作配置")] + [Description("IO操作后延时,单位ms")] + public virtual int DelayAfter { get; set; } = 0; + + + } + + /// + /// IO操作对象 + /// + public class IOOperationItem + { + [Category("IO操作配置")] + [Description("需要操作的IO")] + public IODefinition IOItem { get; set; } = new IODefinition(); + + [Category("IO操作配置")] + [Description("需要操作的IO的状态")] + public IOValue CheckValue + { + get => IOItem.IOValue; + set => IOItem.IOValue = value; + } + + //[Browsable(false)] + //[JsonIgnore] + public List IOItemSource = new List(); + + //public string GetDisplayText() + //{ + // return IOItem.IODesc + "-" + CheckValue.GetEnumDescription(); + //} + } + + /// + /// 运动对象 + /// + public class MovingOption + { + [Category("运动配置")] + [DisplayName("运动轴索引")] + [Description("AxisIndex:运动轴索引")] + // [TypeConverter(typeof(AxisIndexConvert))] + public int AxisIndex { get; set; } + + [Category("运动配置")] + [DisplayName("运动模式")] + [Description("MoveMode:运动模式")] + public MotionMode MoveMode { get; set; } = MotionMode.P2P; + + + [Category("运动配置")] + [DisplayName("运动方向")] + [Description("MoveDir:运动方向")] + public PulseMode MoveDir { get; set; } = PulseMode.Pulse_Dir_H; + + + [Category("运动配置")] + [DisplayName("点位运动误差带")] + [Description("点位运动误差带,单位plus")] + public int ErrorBand { get; set; } = 20; + + [Category("运动配置")] + [DisplayName("是否绝对运动")] + [Description("IsAbsolute:是否绝对运动")] + public bool IsAbsolute { get; set; } = true; + + [Category("运动配置")] + [DisplayName("目的地")] + [Description("Destination:目的地")] + public int Destination { get; set; } + + [Category("运动配置")] + [DisplayName("备注")] + [Description("Remark:备注")] + public string Remark { get; set; } + + [Category("运动配置")] + [DisplayName("速度参数")] + [Description("VelocityPara:速度参数")] + public VelocityPara VelocityPara { get; set; } = new VelocityPara(); + + + + + [Category("运动配置")] + [Description("超时设置,单位:ms")] + [DisplayName("运动超时")] + public int MovingTimeout { get; set; } = 0; + + internal List _axisSettingList = new List(); + + public void SetAxisSetting(List settings) + { + if (settings != null) + _axisSettingList = settings; + } + + public string GetDisplayText() + { + //string axisName = AxisIndexStr; + string axisName = AxisIndex.ToString(); + var axisSet = _axisSettingList.FirstOrDefault(a => a.AxisIndex == AxisIndex); + if (axisSet != null) + { + axisName += ("-" + axisSet.AxisName); + } + return axisName + "," + MoveMode.ToString() + "," + (IsAbsolute ? "Abs" : "Rel") + "," + Destination; + } + //public event PropertyChangedEventHandler PropertyChanged; + } + + public class SolidMotionOperationCollection : OperationConfigBase + { + [Category("运动配置")] + [DisplayName("运动配置集合")] + [Description("MovingOps:多轴并发,运动配置集合")] + public List MovingOps { get; set; } = new List(); + + [Category("运动配置")] + [Description("多轴并发运动超时设置,单位:s")] + [DisplayName("多轴并发运动超时")] + public int MovingOpsTimeout { get; set; } = 60; + + + } + #endregion + +} diff --git a/DH.Devices.Motion/SLDMotion.cs b/DH.Devices.Motion/SLDMotion.cs new file mode 100644 index 0000000..5b20630 --- /dev/null +++ b/DH.Devices.Motion/SLDMotion.cs @@ -0,0 +1,2688 @@ +using DH.Commons.Enums; +using DH.Devices.Motion; +using MCDLL_NET; +using System.Diagnostics; + + +namespace XKRS.Device.SolidMotionCard +{ + + + public class SLDMotion: MotionBase + { + + + + /// + /// 从板卡中获取的的物件计数 + /// + private Dictionary piecesCountDic = new Dictionary(); + + private ushort BoardCount + { + get + { + switch (ExtBoard) + { + default: + case ExtensionBoardEnum.None: + case ExtensionBoardEnum.ExtIO_1: + return 1; + + case ExtensionBoardEnum.ExtEC3216_1: + case ExtensionBoardEnum.ExtEC3224_1: + case ExtensionBoardEnum.ExtEC3416_1: + return 2; + } + } + } + + + + + + /// + /// 转盘数量 + /// + private ushort DiskCount + { + get + { + return MachineDiskType switch + { + MachineDiskType.DoubleDisk => 2, + _ => 1, + }; + } + } + + /// + /// 是否复位标志 + /// + private bool _isResetting = false; + + + /// + /// 是否暂停中 + /// + private bool _isPause = false; + + + /// + /// 运动轴立即暂停 + /// + private Dictionary axisImmediatePauseHandleDict = new Dictionary(); + private Dictionary axisImmediatePauseFlag = new Dictionary(); + private Dictionary axisPauseResumeFlag = new Dictionary(); + + /// + /// int,int 轴号 捕获位置 + /// + public event Action OnNewPieces; + + + public void NewPieces(int diskIndex, uint pieceNumber) + { + _taskFactory.StartNew(() => + { + Thread.CurrentThread.Priority = ThreadPriority.Highest; + + OnNewPieces?.Invoke(diskIndex, pieceNumber); + }); + } + public void SetResetFlag(bool isReset) + { + _isResetting = isReset; + } + + + public void ResetCount() + { + // piecesCountDic = new(); + + foreach (var item in piecesCountDic.Keys) + { + piecesCountDic[item] = 0; + } + } + + + public override List GetCurrentAxisInfo(params string[] axisName) + { + List axisInfos = new(); + AxisSettings.FindAll(a => a.IsAxisEnabled).ForEach(axisSetting => + { + AxisInfo axisInfo = new() + { + AxisName = axisSetting.AxisName + }; + + var axisMovingStatus = AxisStatusList.FirstOrDefault(u => u.AxisIndex == axisSetting.AxisIndex); + axisInfo.AxisLocation = axisMovingStatus == null ? 0 : Convert.ToDouble(axisMovingStatus.CurPosition); + + axisInfos.Add(axisInfo); + }); + return axisInfos; + } + + + #region DeviceBase + + public override void Init() + { + // 根据扩展卡数量,计算卡总数 + //if (0 < IIConfig.) + //{ + // _cardCount = (ushort)(1 + IIConfig.CardExtNum); + //} + try + { + piecesCountDic.Clear(); + + for (ushort disk = 0; disk < DiskCount; disk++) + { + piecesCountDic.Add(disk, 0); + } + + InitialMotionCard(); + axisImmediatePauseHandleDict = AxisSettings + .FindAll(a => a.IsAxisEnabled) + .ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true)); + + // 初始化时关闭所有轴,停止筛选 begin ======= + AllMoveStop(); + AllAxisOff(); + + StopSorting(); + + // 初始化时关闭所有轴,停止筛选 end ======= + + AllAxisOn(); + Start(); + MonitorPosition(); + MonitorAxisStatus(); + MonitorPieces(); + + CustomStart(); + isconnected = true; + + } + catch + { + isconnected = false; + } + } + + public override void Start() + { + var enabledList = AxisSettings.Where(a => a.IsAxisEnabled).ToList(); + AxisStatusList = enabledList.ConvertAll(a => + { + AxisMovingStatus axisSts = new AxisMovingStatus(); + axisSts.AxisIndex = a.AxisIndex; + axisSts.AxisName = a.AxisName; + axisSts.IsMonitorStatus = a.IsMonitorStatus; + axisSts.IsMonitorPosition = a.IsMonitorPosition; + + return axisSts; + }); + + _axisAlarmRaisedFlag = enabledList.ToDictionary(a => a.AxisIndex, a => false); + _axisLimitTimer = enabledList.ToDictionary(a => a.AxisIndex, a => new System.Threading.Timer(OnAxisLimitAlarm, a.AxisIndex, -1, -1)); + + Task.Run(() => + { + Monitor(); + }); + } + + + protected virtual void OnAxisLimitAlarm(object state) + { + int axisIndex = Convert.ToInt32(state); + + if (!_axisAlarmRaisedFlag[axisIndex]) + { + var curStatus = GetAxisStatus(axisIndex); + // lifayu + var msg = "卡/核:"; //+ IConfig.StationNumber; + if (((curStatus >> 5) & 1) == 1) + { + msg += $"轴{axisIndex}在 正极限"; + } + if (((curStatus >> 6) & 1) == 1) + { + msg += $"轴{axisIndex}在 负极限"; + } + AxisAlarmRaised(axisIndex, msg, true); + } + } + /// + /// 报警产生 与 取消 + /// + /// + /// + /// + public void AxisAlarmRaised(int axisIndex, string msg, bool isAlarm) + { + //_axisAlarmRaisedFlag[axisIndex] = isAlarm; + //IWarningSet ws = new SimpleWarningSet(); + //ws.WarningCode = msg; + //ws.WarningDescription = msg; + //ws.TriggerTime = DateTime.Now; + //ws.SourceDevice = this.Name; + //ws.CurrentStatus = isAlarm; + + //SaveAlarmCSVAsync(ws.TriggerTime, this.Name, ws); + //OnMonitorAlarm?.BeginInvoke(ws.TriggerTime, this, ws, null, null); + } + private ushort _stationNumber = 0; + public void CustomStart() + { + // 急停配置 + var ret = CMCDLL_NET.MCF_Set_EMG_Bit_Net(EmgStopSignalIoIndex, (ushort)EMG_Mode.EMG_Trigger_Close, _stationNumber); + if (IsEnableEmgStop) + { + ret = CMCDLL_NET.MCF_Set_EMG_Bit_Net(EmgStopSignalIoIndex, (ushort)EmgMode, _stationNumber); + } + + + if (IsEnableFilter) + { + StartSorting(); + } + } + + + /// + /// 开启筛选 + /// + public void StartSorting() + { + short rtn = 0; + var cardCount = 1; + switch (ExtBoard) + { + default: + case ExtensionBoardEnum.None: + case ExtensionBoardEnum.ExtIO_1: + break; + case ExtensionBoardEnum.ExtEC3216_1: + case ExtensionBoardEnum.ExtEC3224_1: + case ExtensionBoardEnum.ExtEC3416_1: + cardCount = 2; + break; + } + for (ushort station = 0; station < BoardCount; station++) + { + // 关闭调试测试后的位置比较 + for (int i = 0; i < 16; i++) + { + rtn = CMCDLL_NET.MCF_Set_Compare_Config_Net((ushort)i, 0, 0, station); + } + + // 2.配置物件设置 + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Piece_Size_Net(PieceMaxSize, PieceMinSize, station); + + + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Piece_Place_Net(MinDistance, MinTimeInterval, station); + } + + if (BoardCount < 2) + { + // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0); + // 3.配置相机设置 + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0); + //设置来料使能 0 是默认 1是开始 + // + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Enable_Net((ushort)SortingInputSetting.BitInputNumber, 1); + //设置物件检测有效电平 0是低电平 1是高电平 + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Logic_Net((ushort)SortingInputSetting.BitInputNumber, 0); + //设置来料检测编码器 双转盘要设置两个轴 + /*Bit_Input_Number:设置位号。 + 取值: Bit_Input_0, Bit_Input_1。 + Axis: 轴号。 + Source:跟随方式 + 取值:0:命令 + 1:编码器(默认) + StationNumber: 站点号;*/ + // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)IIConfig.SortingInputSetting.BitInputNumber, 0, 1); + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)SortingInputSetting.BitInputNumber, 1, 1); + + + //rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net( + // (ushort)IIConfig.SnapshotSettings.Count, + // (ushort)IIConfig.BlowSettings.Count, + // 0); + // rtn = CMCDLL_NET_Sorting.MCF_Set_Config_Camera_Net(); + //为防止转盘第二个盘不触发拍照 设置一键取反功能 + } + // 3.配置相机设置 + + ConfigCamera(); + + // 4.配置气阀 + ConfigBlow(); + + + + + // + //CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net() + + + + for (ushort card = 0; card < cardCount; card++) + { + //IIConfig.SortingInputSettings.ForEach(sortingInputSetting => + //{ + // var camStart = 0; + // if (sortingInputSetting.EnableBindCamera) + // { + // camStart = sortingInputSetting.CameraStartNumber; + // } + + // var blowStart = 0; + // if (sortingInputSetting.EnableBindBlow) + // { + // blowStart = sortingInputSetting.BlowStartNumber; + // } + + // var b = (ushort)sortingInputSetting.BitInputNumber; + // //var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(b, + // // (ushort)camStart, + // // (ushort)blowStart, + // // card); + + // var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(1, + // 1, + // 2, + // card); + + //}); + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net(); + if (cardCount < 2) + { + // 最小值 1 2 2 + var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net( + (ushort)SortingInputSetting.BitInputNumber, // 1 + SortingInputSetting.CameraStartNumber, // 7, + SortingInputSetting.BlowStartNumber, // 2, + card); + + } + + for (ushort station = 0; station < cardCount; station++) + { + // 5.开启筛选 + //开启自动筛选功能 + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Start_Net(0, station); + if (rtn != (short)FuncRet.Function_Success) + { + //LogAsync(DateTime.Now, LogLevel.Warning, $"卡{card}开启筛选异常,ret:{rtn}"); + } + } + } + } + + + + + /// + /// 停止筛选 + /// + public void StopSorting() + { + // 关闭筛选 + for (ushort station = 0; station < BoardCount; station++) + { + short rtn = CMCDLL_NET_Sorting.MCF_Sorting_Close_Net(station); + if (rtn != (short)FuncRet.Function_Success) + { + //LogAsync(DateTime.Now, LogLevel.Warning, $"卡{station}停止筛选异常,ret:{rtn}"); + } + piecesCountDic[station] = 0; + } + } + + + public override void Stop() + { + //base.Stop(); + AllMoveStop(); + AllAxisOff(); + + for (ushort station = 0; station < BoardCount; station++) + { + //2.关闭筛选 + var rtn = CMCDLL_NET_Sorting.MCF_Sorting_Close_Net(station); + rtn = CMCDLL_NET.MCF_Close_Net(); + } + } + + + #region 源程序运行方法注释掉 + ///// + ///// 设备 运行(执行 板卡系列的操作的 集合) + ///// + ///// + ///// + //public override ResponseMessage Run(IOperationConfig config) + //{ + // ResponseMessage responseMessage = new ResponseMessage(); + // if (config is SolidMotionCardOperationConfigBase motionCardOperationConfig) + // { + // foreach (var operationSet in motionCardOperationConfig.OperationCollection) + // { + // if (operationSet.DelayBefore > 0) + // { + // Task.Delay(operationSet.DelayBefore).Wait(); + // } + + // responseMessage = RunOperationSet(operationSet); + // if (responseMessage.Result != 1) + // { + // return responseMessage; + // } + + // if (operationSet.DelayAfter > 0) + // Task.Delay(operationSet.DelayAfter).Wait(); + // } + // } + // return responseMessage; + //} + + + ///// + ///// 执行 一个系列的操作 + ///// + //private ResponseMessage RunOperationSet(SolidMotionCardOperationSet operationSet) + //{ + // ResponseMessage responseMessage = new ResponseMessage(); + // // 1.预检查 + // if (CurrentState == DeviceState.DSOpen) + // { + // foreach (var preCheck in operationSet.PreCheckIOCollection) + // { + // _pauseHandle.Wait(); + + // IOValue? ioData = null; + // if (CurrentState == DeviceState.DSOpen) + // { + // int timeout = operationSet.PreCheckIOTimeout <= 0 ? 60 * 1000 : operationSet.PreCheckIOTimeout; + + // while (CurrentState == DeviceState.DSOpen) + // { + // Task.Delay(10).Wait(); + // ioData = CurrentIOs.FirstOrDefault(u => u.IOIndex == preCheck.IOItem.IOIndex && u.IOType == preCheck.IOItem.IOType)?.IOValue;//IO 是开、关 从MonitorValues 获取 + // timeout -= 10; + // if (preCheck.CheckValue == ioData || timeout < 0) + // { + // break; + // } + // } + // if (timeout < 0) + // { + // responseMessage.Result = -1; + // responseMessage.Message = $"{preCheck.GetDisplayText()}预检查超时:{preCheck.IOItem.GetDisplayText()},当前值:{ioData}"; + // return responseMessage; + // } + + // if (preCheck.CheckValue != ioData) + // { + // responseMessage.Result = -1; + // responseMessage.Message = $"{preCheck.GetDisplayText()}预检查不通过,配置:{preCheck.GetDisplayText()},当前值:{ioData}"; + // return responseMessage; + // } + // } + // } + // } + + // // 2.板卡运动 + // if (CurrentState == DeviceState.DSOpen) + // { + // _pauseHandle.Wait(); + + // if (CurrentState == DeviceState.DSOpen) + // { + // responseMessage = MoveToPoint(new SolidMotionOperationCollection() + // { + // MovingOps = operationSet.MovingOps + // }); + // if (responseMessage.Result != 1) + // { + // return responseMessage; + // } + // } + // } + + + // // 3.IO输出 不需要超时 + // if (CurrentState == DeviceState.DSOpen) + // { + // foreach (var ioOutput in operationSet.IOOutputCollection) + // { + // _pauseHandle.Wait(); + + // if (CurrentState == DeviceState.DSOpen) + // { + // WriteOutput((short)ioOutput.IOItem.IOIndex, ioOutput.CheckValue); + // } + // } + // } + + // // 4.IO确认 + // if (CurrentState == DeviceState.DSOpen) + // { + // foreach (var ioConfirm in operationSet.IOConfirmCollection) + // { + // int timeout = operationSet.IOConfirmTimeout <= 0 ? 60 * 1000 : operationSet.IOConfirmTimeout; + // IOValue? ioData = null; + // while (CurrentState == DeviceState.DSOpen) + // { + // Task.Delay(10).Wait(); + // ioData = CurrentIOs.FirstOrDefault(u => u.IOIndex == ioConfirm.IOItem.IOIndex && u.IOType == ioConfirm.IOItem.IOType)?.IOValue;//IO 是开、关 从MonitorValues 获取 + // timeout -= 10; + // if (ioConfirm.CheckValue == ioData || timeout < 0) + // { + // break; + // } + // } + + // if (ioConfirm.CheckValue != ioData) + // { + // responseMessage.Result = -1; + // responseMessage.Message = $"IO确认不通过,配置:{ioConfirm.GetDisplayText()},当前值:{ioData}"; + // return responseMessage; + // } + // } + // } + + // return responseMessage; + //} + #endregion + #endregion + + #region ImmediatePause + ManualResetEventSlim _pauseHandle = new ManualResetEventSlim(true); + + /// + /// 启动立即暂停 + /// + public override void SetImmediatePause() + { + if (!_isResetting) + { + var immediatePauseAxis = AxisSettings.FindAll(a => a.IsAxisEnabled && a.IsImmediatePause).Select(u => u.AxisIndex).ToList(); + _pauseHandle.Reset(); + immediatePauseAxis.ForEach(async axisIndex => + { + axisImmediatePauseHandleDict[axisIndex].Reset(); + axisImmediatePauseFlag[axisIndex] = true; + + await MoveStop(axisIndex, 0);//所有轴都暂停 + }); + } + } + + /// + /// 恢复立即暂停 + /// + public override void ResetImmediatePause(bool isResumeMoving) + { + var immediatePauseAxis = AxisSettings.FindAll(a => a.IsAxisEnabled && a.IsImmediatePause).Select(u => u.AxisIndex).ToList(); + _pauseHandle.Set(); + immediatePauseAxis.ForEach(axisIndex => + { + axisImmediatePauseFlag[axisIndex] = false; + axisImmediatePauseHandleDict[axisIndex].Set(); + if (isResumeMoving) + { + axisPauseResumeFlag[axisIndex] = true; + } + else + { + axisPauseResumeFlag[axisIndex] = false; + } + }); + } + #endregion + + #region MotionCard + + + + public void InitialMotionCard() + { + short ret = (short)FuncRet.Function_Success; + + List stations = new List(); + List cardTypes = new List(); + + + // 初始化 + for (ushort station = 0; station < BoardCount; station++) + { + ret = CMCDLL_NET_Sorting.MCF_Sorting_Init_Net(station); + stations.Add(station); + cardTypes.Add(2); + } + + var stationsArr = stations.ToArray(); + var cardTypesArr = cardTypes.ToArray(); + + // 打开卡 + ret = CMCDLL_NET.MCF_Open_Net(BoardCount, ref stationsArr[0], ref cardTypesArr[0]); + + if (ret == (ushort)FuncRet.Function_Success) + { + uint Version = 0; + // 获取第一块控制板的软件版本号 + ret = CMCDLL_NET.MCF_Get_Version_Net(ref Version, _stationNumber); + + } + else + { + + } + MCF_Screen_Set_Trigger1(); + MCF_Screen_Set_Trigger1(1); + + } + + public static short MCF_Screen_Set_Trigger1(ushort StationNumber = 0) + { + short rtn = 0; + //配置触发器电平 + ushort Input_Number = 0; + uint Trigger_Enable = 1; + uint Trigger_Logic = 0; + uint Trigger_Filter_Time = 1; + uint Trigger_Axis = 0;//跟随轴 + uint Trigger_Source = 1;//跟随源 + uint Tirgger_Piece_Position = 1;//物件触发位置 + + + //使能 + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Enable_Net(Input_Number, (ushort)Trigger_Enable, StationNumber); + //有效电平 + //MotionTimeFunction.MCF_Screen_Read_Data(MotionTimeDataIndex.Index_DI00_Tirgger_Logic, out Trigger_Logic, StationNumber); + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Logic_Net(Input_Number, (ushort)Trigger_Logic, StationNumber); + //滤波时间 + //MotionTimeFunction.MCF_Screen_Read_Data(MotionTimeDataIndex.Index_DI00_Tirgger_Filter_Time, out Trigger_Filter_Time, ScreenExternData.StationNumber); + if (Trigger_Filter_Time != 0) + { + rtn = CMCDLL_NET_Sorting.MCF_Set_Input_Filter_Time_Bit_Net(Input_Number, Trigger_Filter_Time, StationNumber); + } + //默认跟随轴0 + //MotionTimeFunction.MCF_Screen_Read_Data(MotionTimeDataIndex.Index_DI00_Tirgger_Axis, out Trigger_Axis, ScreenExternData.StationNumber); + //MotionTimeFunction.MCF_Screen_Read_Data(MotionTimeDataIndex.Index_DI00_Tirgger_Source, out Trigger_Source, ScreenExternData.StationNumber); + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net(Input_Number, (ushort)Trigger_Axis, (ushort)Trigger_Source, StationNumber); + + //物件触发位置 + // MotionTimeFunction.MCF_Screen_Read_Data(MotionTimeDataIndex.Index_DI00_Tirgger_Piece_Position, out Tirgger_Piece_Position, ScreenExternData.StationNumber); + CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Position_Net(Input_Number, (ushort)Tirgger_Piece_Position, StationNumber); + + + return rtn; + } + + public override bool AllAxisOn() + { + List> taskList = new List>(); + // 如果是多个轴的运动 等每个轴开启 + AxisSettings.FindAll(a => a.IsAxisEnabled) + .ForEach(axisNum => + { + var task = AxisOnAsync(axisNum.AxisIndex); + taskList.Add(task); + }); + Task.WaitAll(taskList.ToArray()); + var resultOK = taskList.All(u => u.GetAwaiter().GetResult()); + return resultOK; + } + + public override bool AllAxisOff() + { + List> taskList = new List>(); ; + // 如果是多个轴的运动 等每个轴关闭 + AxisSettings.FindAll(a => a.IsAxisEnabled).ForEach(axisNum => + { + var task = AxisOffAsync(axisNum.AxisIndex); + taskList.Add(task); + }); + Task.WaitAll(taskList.ToArray()); + var resultOK = taskList.All(u => u.GetAwaiter().GetResult()); + return resultOK; + } + + + + /// + /// 单个板卡有4个轴,轴索引从0开始,大于3时,需要计算一下站点号及轴号 + /// + /// 原始轴号,在配置中累加,如第1张卡轴号0~3,第2张卡轴号4~7 + /// 换算后的站点号 + /// 换算后的轴号 + private void ConvertFromAxis(int axisNum, out ushort station, out ushort axis) + { + station = (ushort)(axisNum / 4); + axis = (ushort)(axisNum % 4); + } + + + /// + /// IO索引转换 + /// + /// + /// + /// + // TODO: 2023-11-14 完善IO索引转换函数 + private void ConvertFromIO(int ioIndex, out ushort station, out ushort io) + { + station = 0; + io = (ushort)ioIndex; + + + switch (BoardModel) + { + case BoardModelEnum.EC3216: + { + + } + break; + case BoardModelEnum.EC3224: + break; + case BoardModelEnum.EC3416: + { + switch (ExtBoard) + { + default: + case ExtensionBoardEnum.None: + return; + + case ExtensionBoardEnum.ExtIO_1: + case ExtensionBoardEnum.ExtEC3216_1: + case ExtensionBoardEnum.ExtEC3416_1: + station = (ushort)(ioIndex / 16); + io = (ushort)(ioIndex % 16); + break; + + case ExtensionBoardEnum.ExtEC3224_1: + break; + + } + } + break; + default: + break; + } + + + + + //if (ExtMainBoard) + //{ + // station = (ushort)(ioIndex / 16); + // io = (ushort)(ioIndex % 16); + //} + + //if (ExtIoBoard) + //{ + // station = 0; + // io = (ushort)ioIndex; + //} + + } + + + + /// + /// 单个轴开启 + /// + /// + public override async Task AxisOnAsync(int axisNum) + { + return await Task.Run(() => + { + bool result = false; + result = ClearStatus(axisNum); + if (!result) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴:{axisNum} 开启清除状态异常"); + return result; + } + result = PositionReset(axisNum, 1); + if (!result) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴:{axisNum} 开启位置清零异常"); + return result; + } + + // 单个板卡有4个轴,轴索引从0开始,大于3时,需要计算一下站点号及轴号 + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + + var ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(axis, (ushort)ServoLogic.Servo_Close, station); + + result = ret == 0; + if (!result) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴:{axisNum} 开启异常"); + } + return result; + }); + } + + /// + /// 单个轴关闭 + /// + /// + public override async Task AxisOffAsync(int axisNum) + { + return await Task.Run(() => + { + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + var ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(axis, (ushort)ServoLogic.Servo_Open, station); + + return ret == (short)FuncRet.Function_Success; + }); + } + + /// + /// 点位到点位运动 + /// + /// 运动对象 + /// 运动控制+停止判断 + public ResponseMessage MoveToPoint(IOperationConfig opConfig) + { + ResponseMessage responseMessage =new ResponseMessage(); + if (opConfig is SolidMotionOperationCollection motionCollection) + { + List> resultList = new List>(); + motionCollection.MovingOps.ForEach(movingOp => + { + if (movingOp.AxisIndex >= 0) + { + axisImmediatePauseFlag[movingOp.AxisIndex] = false; + axisPauseResumeFlag[movingOp.AxisIndex] = true; + var task = SingleAxisMoving(movingOp); + resultList.Add(task); + } + }); + var timeOut = motionCollection.MovingOpsTimeout <= 0 ? 60 * 1000 : motionCollection.MovingOpsTimeout * 1000; + var isMotionNotTimeout = Task.WaitAll(resultList.ToArray(), timeOut); + if (!isMotionNotTimeout) + { + responseMessage.Message = $"多轴并发点位运动超时,请设置合理的运动超时时间,或加快轴速度"; + } + var result = resultList.All(u => u.GetAwaiter().GetResult()); + if (!result) + { + responseMessage.Result = -1; + responseMessage.Message = $"多轴并发点位运动异常"; + } + } + return responseMessage; + } + + /// + /// 点到点运动设置参数 + /// + /// 运动参数对象 + /// + private bool SetAxisParam(MovingOption optionPara) + { + //List resultCode = new List() { 0 }; + //MotionCardAPI.TTrapPrm trapprm = new MotionCardAPI.TTrapPrm(); + ////设置误差带 + //resultCode.Add(MotionCardAPI.GT_SetAxisBand((short)IConfig.CardOrCoreNum, (short)optionPara.AxisIndex, optionPara.ErrorBand, 5)); + //resultCode.Add(MotionCardAPI.GT_PrfTrap((short)IConfig.CardOrCoreNum, (short)optionPara.AxisIndex)); + //resultCode.Add(MotionCardAPI.GT_GetTrapPrm((short)IConfig.CardOrCoreNum, (short)optionPara.AxisIndex, out trapprm)); + //trapprm.smoothTime = 1; + + //if (optionPara.VelocityPara.Acc != 0) + //{ + // trapprm.acc = optionPara.VelocityPara.Acc; + //} + + //if (optionPara.VelocityPara.Dec != 0) + //{ + // trapprm.dec = optionPara.VelocityPara.Dec; + //} + + //resultCode.Add(MotionCardAPI.GT_SetTrapPrm((short)IConfig.CardOrCoreNum, (short)optionPara.AxisIndex, ref trapprm)); + + // CMCDLL_NET.MCF_Set_Axis_Profile_Net((ushort)optionPara.AxisIndex,) + + //if (optionPara.VelocityPara.Velocity != 0) + //{ + // resultCode.Add(MotionCardAPI.GT_SetVel((short)IConfig.CardOrCoreNum, (short)optionPara.AxisIndex, optionPara.VelocityPara.Velocity * IConfig.AxisVelocityRatio)); + //} + + //var resultOK = resultCode.All(u => u == RetCode.Function_Success); + //if (!resultOK) + //{ + // throw new ProcessException("轴" + optionPara.AxisIndex + "设置参数异常,错误码:" + string.Join(",", resultCode)); + //} + var resultOK = true; + return resultOK; + } + + /// + /// 单个轴 运动(点到点 jog 回零...) + /// + /// 运动参数对象 + public Task SingleAxisMoving(MovingOption optionPara) + { + return _taskFactory.StartNew(() => + { + bool isSuccessAndStop = false; + do + { + axisImmediatePauseHandleDict[optionPara.AxisIndex].WaitOne(); + + if (axisPauseResumeFlag.ContainsKey(optionPara.AxisIndex) && !axisPauseResumeFlag[optionPara.AxisIndex]) + return true; + + try + { + if (AxisSettings.FirstOrDefault(a => a.AxisIndex == optionPara.AxisIndex)?.IsAxisEnabled ?? false) + { + string motionType = optionPara.MoveMode == MotionMode.P2P ? (optionPara.IsAbsolute ? "Abs" : "Rel") : optionPara.MoveMode.ToString(); + + switch (optionPara.MoveMode) + { + case MotionMode.P2P: // 点到点 + { + if (_isResetting) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"复位中启动运动异常 {optionPara.AxisIndex}"); + return false; + } + + if (optionPara.IsAbsolute) + { + isSuccessAndStop = P2PMoveAbs(optionPara); + } + else + { + isSuccessAndStop = P2PMoveRel(optionPara); + } + + } + break; + case MotionMode.GoHome: // 回零 + { + var axisSetting = AxisSettings.FirstOrDefault(u => u.AxisIndex == optionPara.AxisIndex); + if (axisSetting != null) + { + isSuccessAndStop = SmartGoHome((ushort)optionPara.AxisIndex, axisSetting.GoHomePara); + } + else + { + isSuccessAndStop = false; + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}回零异常,未获取到轴配置"); + } + } + break; + case MotionMode.Jog: // Jog + { + isSuccessAndStop = JogMove(optionPara); + } + break; + } + } + } + catch (Exception ex) + { + isSuccessAndStop = false; + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}运动异常 {ex.GetExceptionMessage()}"); + } + } while (axisImmediatePauseFlag.ContainsKey(optionPara.AxisIndex) && axisImmediatePauseFlag[optionPara.AxisIndex]); + return isSuccessAndStop; + }); + } + + /// + /// 获取规划位置 + /// + /// Axis number + /// + public int GetPrfPosition(int axisNum) + { + int prfpos = 0; + + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + var ret = CMCDLL_NET.MCF_Get_Position_Net(axis, ref prfpos, station); + if (ret == (short)FuncRet.ERR_Open_Station_Fail) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{axisNum}获取规划位置异常,{IConfig.Name}未打开"); + } + else if (ret != (short)FuncRet.Function_Success) + { + // LogAsync(DateTime.Now, LogLevel.Exception, "轴" + axisNum + "获取规划位置异常,错误码:" + ret); + // throw new ProcessException("轴" + axisNum + "获取规划位置异常,错误码:" + ret); + } + return prfpos; + } + + + /// + /// 获取目前当前位置 + /// + /// Axis number + /// + public int GetCurPosition(int axisNum) + { + int pPos = 0; + + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + int ret = CMCDLL_NET.MCF_Get_Encoder_Net(axis, ref pPos, station); + if (ret == (short)FuncRet.ERR_Open_Station_Fail) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{axisNum}获取目标当前位置异常,{IConfig.Name}未打开"); + } + else if (ret != (short)FuncRet.Function_Success) + { + // LogAsync(DateTime.Now, LogLevel.Exception, "轴" + axisNum + "获取目标当前位置异常,错误码:" + ret); + // throw new ProcessException("轴" + axisNum + "获取目标当前位置异常,错误码:" + ret); + } + return pPos; + } + + + /// + /// 获取规划速度及实际速度 + /// + /// Axis number + /// 速度脉冲 + public bool GetVelocity(int axisNum, ref double commandVel, ref double encodeVel) + { + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + var ret = CMCDLL_NET.MCF_Get_Vel_Net(axis, ref commandVel, ref encodeVel, station); + if (ret == (short)FuncRet.ERR_Open_Station_Fail) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{axisNum}获取速度异常,{IConfig.Name}未打开"); + } + else if (ret != (short)FuncRet.Function_Success) + { + // LogAsync(DateTime.Now, LogLevel.Exception, "轴" + axisNum + "获取速度异常,错误码:" + ret); + //throw new ProcessException("轴" + axisNum + "获取速度异常,错误码:" + ret); + } + return true; + } + + + + /// + /// Set Single Axis Do Jog Move + /// + /// AxisNo + /// Motion Direction 0: Negative, 1: Positive + /// max velocity + /// + public bool JogMove(MovingOption optionPara) + { + try + { + //MotionCardAPI.TJogPrm jogprm = new MotionCardAPI.TJogPrm(); + short ret = 0; + int repeatTime = 100; + do + { + ConvertFromAxis(optionPara.AxisIndex, out ushort station, out ushort axis); + + + ret = CMCDLL_NET_Sorting.MCF_Set_Pulse_Mode_Net(axis, (ushort)optionPara.MoveDir, station); + ret = CMCDLL_NET_Sorting.MCF_Set_Servo_Enable_Net(axis, (ushort)ServoLogic.Servo_Close, station); + ret = CMCDLL_NET_Sorting.MCF_JOG_Net(axis, optionPara.VelocityPara.Velocity, optionPara.VelocityPara.Acc, station); + + + //ret = CMCDLL_NET.MCF_Set_Pulse_Mode_Net(axis, (ushort)PulseMode.Pulse_Dir_H, station); + //ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(axis, (ushort)ServoLogic.Servo_Close, station); + //ret = CMCDLL_NET.MCF_JOG_Net(axis, optionPara.VelocityPara.Velocity, optionPara.VelocityPara.Acc, station); + + if (ret != (short)FuncRet.Function_Success) + { + //LogAsync(DateTime.Now, LogLevel.Exception, "轴" + optionPara.AxisIndex + "JogMove异常 ,错误码:" + ret + ";" + "重试次数:" + repeatTime); + Task.Delay(10).Wait(); + } + repeatTime--; + } while (ret != (short)FuncRet.Function_Success && repeatTime > 0); + + return (ret == (short)FuncRet.Function_Success); + } + catch (Exception ex) + { + AllMoveStop(true); + //OnExceptionOccured?.Invoke(DateTime.Now, ex); + return false; + } + } + + /// + /// 相对位置运动 + /// + /// AxisNo + /// run distance + /// + public bool P2PMoveRel(MovingOption optionPara) + { + try + { + axisImmediatePauseHandleDict[optionPara.AxisIndex].WaitOne(); + int currentPosition = (int)GetCurPosition(optionPara.AxisIndex); + int dPosition = optionPara.Destination + currentPosition; + if (Math.Abs(dPosition - currentPosition) <= optionPara.ErrorBand) + { + //已经在位 直接返回 + return true; + } + if (_isResetting) + { + //LogAsync(DateTime.Now, LogLevel.Exception, "复位过程异常,轴" + optionPara.AxisIndex + "试图在复位过程中运动"); + //throw new ProcessException("轴" + optionPara.AxisIndex + "试图在复位过程中运动"); + } + + int repeatTime = 30; + //while (CurrentState != EnumHelper.DeviceState.DSOpen && repeatTime > 0) + //{ + // Task.Delay(10).Wait(); + // repeatTime--; + //} + + //if (CurrentState == EnumHelper.DeviceState.DSExcept) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, "板卡异常状态,轴" + optionPara.AxisIndex + "试图异常状态运动"); + // return false; + //} + + //if (CurrentState != EnumHelper.DeviceState.DSOpen) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, "非正常状态异常,轴" + optionPara.AxisIndex + $"试图在非正常状态({CurrentState})运动"); + // throw new ProcessException("轴" + optionPara.AxisIndex + "试图在非正常状态运动", null); + //} + + short ret = 0; + bool isSuccessSetAxisParam = false; + int timeout = optionPara.MovingTimeout <= 0 ? 60 * 1000 : optionPara.MovingTimeout; + int timeout2 = optionPara.MovingTimeout <= 0 ? 60 * 1000 : optionPara.MovingTimeout; + int repeatTime2 = 0; + //LogAsync(DateTime.Now, LogLevel.Action, $"轴{optionPara.AxisIndex} 开始运动,当前位置:{currentPosition} 目标位置:{dPosition}"); + //while (CurrentState == DeviceState.DSOpen) + while (isconnected) + { + // 设置 运动参数 + isSuccessSetAxisParam = SetAxisParam(optionPara); + + ConvertFromAxis(optionPara.AxisIndex, out ushort station, out ushort axis); + + // 设置速度参数 + ret = CMCDLL_NET.MCF_Set_Axis_Profile_Net(axis, + optionPara.VelocityPara.Velocity, + optionPara.VelocityPara.Velocity, + optionPara.VelocityPara.Acc, + optionPara.VelocityPara.Acc, + optionPara.VelocityPara.Velocity, + (ushort)Profile.Profile_T, + station); + + + ret = CMCDLL_NET.MCF_Uniaxial_Net(axis, optionPara.Destination, (ushort)PositionMode.Position_Opposite, station); + + if (ret != (short)FuncRet.Function_Success) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex} APS_rel_move异常,错误码:{ret};重试次数:{repeatTime2}"); + repeatTime2++; + Task.Delay(20).Wait(); + } + timeout -= 20; + if ((ret == (short)FuncRet.Function_Success && isSuccessSetAxisParam) || timeout < 0) + { + break; + } + } + + if (timeout < 0) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}APS_rel_move参数设置超时,错误码:{ret}"); + return false; + } + + //运动开始后 检查运动是否停止 + bool isStopSuccess = false; + int prfPosition = 0; + int curPosition = 0; + do + { + Task.Delay(20).Wait(); + prfPosition = GetPrfPosition(optionPara.AxisIndex); + curPosition = GetCurPosition(optionPara.AxisIndex); + isStopSuccess = IsStop((short)optionPara.AxisIndex) + && Math.Abs(dPosition - prfPosition) <= optionPara.ErrorBand + && Math.Abs(dPosition - curPosition) <= optionPara.ErrorBand; + timeout2 -= 20; + } while (!isStopSuccess && timeout2 > 0); + + if (timeout2 < 0) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}APS_rel_move运动到位超时,目标位置:{dPosition};规划位置:{prfPosition};当前位置:{curPosition}"); + return false; + } + // LogAsync(DateTime.Now, LogLevel.Action, $"轴{optionPara.AxisIndex}APS_rel_move运动到位,目标位置:{optionPara.Destination};规划位置:{prfPosition};当前位置:{curPosition}"); + return (ret == (short)FuncRet.Function_Success) && isStopSuccess; + } + catch (Exception ex) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}运动异常:{ex.GetExceptionMessage()}"); + AllMoveStop(true); + // OnExceptionOccured?.Invoke(DateTime.Now, ex); + return false; + } + } + + /// + /// 绝对位置运动 + /// + /// 运动参数对象 + public bool P2PMoveAbs(MovingOption optionPara) + { + try + { + axisImmediatePauseHandleDict[optionPara.AxisIndex].WaitOne(); + + int currentPosition = GetCurPosition(optionPara.AxisIndex); + + // 步进电机没有编码器 + if (currentPosition == 0) + { + currentPosition = GetPrfPosition(optionPara.AxisIndex); + } + + + if (Math.Abs(optionPara.Destination - currentPosition) <= optionPara.ErrorBand) + { + // 已经在位 直接返回 + return true; + } + //if (_isResetting) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, $"复位过程异常,轴{optionPara.AxisIndex}试图在复位过程中运动"); + // throw new ProcessException("轴" + optionPara.AxisIndex + "试图在复位过程中运动"); + //} + int repeatTime = 30; + //while (CurrentState != EnumHelper.DeviceState.DSOpen && repeatTime > 0) + //{ + // Task.Delay(10).Wait(); + // repeatTime--; + //} + //if (CurrentState == EnumHelper.DeviceState.DSExcept) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, $"板卡异常状态,轴{optionPara.AxisIndex}试图异常状态运动"); + // return false; + //} + + //if (CurrentState != EnumHelper.DeviceState.DSOpen) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, $"非正常状态异常,轴{optionPara.AxisIndex}试图在非正常状态({CurrentState})运动"); + // throw new ProcessException("轴" + optionPara.AxisIndex + "试图在非正常状态运动", null); + //} + short ret = 0; + // bool isSuccessSetAxisParam = false; + int timeout = optionPara.MovingTimeout <= 0 ? 60 * 1000 : optionPara.MovingTimeout; + int timeout2 = optionPara.MovingTimeout <= 0 ? 60 * 1000 : optionPara.MovingTimeout; + int repeatTime2 = 0; + // LogAsync(DateTime.Now, LogLevel.Action, $"轴{optionPara.AxisIndex}开始运动,当前位置:{currentPosition} 目标位置:{optionPara.Destination}"); + //while (CurrentState == DeviceState.DSOpen && !_isPause) + while (true) + { + // 设置 运动参数 + // isSuccessSetAxisParam = SetAxisParam(optionPara); + + ConvertFromAxis(optionPara.AxisIndex, out ushort station, out ushort axis); + + // 设置速度参数 + ret = CMCDLL_NET.MCF_Set_Axis_Profile_Net(axis, + optionPara.VelocityPara.Velocity, + optionPara.VelocityPara.Velocity, + optionPara.VelocityPara.Acc, + optionPara.VelocityPara.Acc, + optionPara.VelocityPara.Velocity, + (ushort)Profile.Profile_S, + station); + + // 开始运动 + ret = CMCDLL_NET.MCF_Uniaxial_Net(axis, optionPara.Destination, (ushort)PositionMode.Position_Absolute, station); + + if (ret != (short)FuncRet.Function_Success) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}APS_absolute_move异常,错误码:{ret};重试次数:{repeatTime2}"); + repeatTime2++; + Task.Delay(20).Wait(); + } + timeout -= 20; + // if ((ret == (short)RetCode.Function_Success && isSuccessSetAxisParam) || timeout < 0) + if (ret == (short)FuncRet.Function_Success || timeout < 0) + { + break; + } + } + + if (timeout < 0) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}APS_absolute_move参数设置超时,错误码:{ret}"); + return false; + } + + //运动开始后 检查运动是否停止 + bool isStopSuccess = false; + int prfPosition = 0; + int curPosition = 0; + do + { + Task.Delay(20).Wait(); + prfPosition = GetPrfPosition(optionPara.AxisIndex); + curPosition = GetCurPosition(optionPara.AxisIndex); + + var isStop = IsStop((short)optionPara.AxisIndex); + var prfOk = Math.Abs(optionPara.Destination - prfPosition) <= optionPara.ErrorBand; + var encoderOk = Math.Abs(optionPara.Destination - curPosition) <= optionPara.ErrorBand; + + // 步进电机没有编码器,curPosition一直为0,所以单独做一下处理 + if (prfOk && !encoderOk && curPosition == 0) + { + encoderOk = true; + } + + isStopSuccess = isStop && prfOk && encoderOk; + + timeout2 -= 20; + } while (!isStopSuccess && timeout2 > 0); + + if (optionPara.MovingTimeout > 0 && timeout2 < 0) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}APS_absolute_move运动到位超时,目标位置:{optionPara.Destination};规划位置:{prfPosition};当前位置:{curPosition}"); + return false; + } + // LogAsync(DateTime.Now, LogLevel.Action, $"轴{optionPara.AxisIndex}APS_absolute_move运动到位,目标位置:{optionPara.Destination};规划位置:{prfPosition};当前位置:{curPosition}"); + return (ret == (short)FuncRet.Function_Success) && isStopSuccess; + } + catch (Exception ex) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{optionPara.AxisIndex}运动异常 {ex.GetExceptionMessage()}"); + AllMoveStop(true); + // OnExceptionOccured?.Invoke(DateTime.Now, ex); + return false; + } + } + + /// + /// 某个轴运动停止 + /// + /// axisNo + /// 0表示平滑停止,1表示紧急停止 + /// + public async Task MoveStop(int axisNum, int option) + { + return await _taskFactory.StartNew(() => + { + bool isStop = false; + if (option == 1) + { + // StateChange(EnumHelper.DeviceState.DSExcept); + } + short ret = 0; + + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + + if (option == 1) + { + ret = CMCDLL_NET.MCF_Axis_Stop_Net(axis, AxisStopMode.AxisStopIMD, station); + } + else + { + ret = CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(0, 50000, 0, 0, station); + ret = CMCDLL_NET.MCF_Axis_Stop_Net(axis, AxisStopMode.AxisStopDEC, station); + } + + + if (ret != (short)FuncRet.Function_Success) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"轴{axisNum}运动停止异常,错误码:{ret}"); + } + int repeatTime = 100; + do + { + Task.Delay(20).Wait(); + isStop = IsStop((short)axisNum); + repeatTime--; + } while (!isStop && repeatTime > 0); + if (isStop) + { + //LogAsync(DateTime.Now, LogLevel.Action, "轴" + axisNum + "运动停止"); + } + + return (ret == (short)FuncRet.Function_Success) && isStop; + }); + } + + /// + /// 所有开启的轴停止 + /// + /// + public void AllMoveStop(bool emergencyStop = false) + { + int option = emergencyStop ? 1 : 0; + List> taskList = new List>(); + // 如果是多个轴的运动 等每个轴运动结束 + AxisSettings.Where(a => a.IsAxisEnabled).ToList().ForEach(axisNum => + { + var task = MoveStop(axisNum.AxisIndex, option); + taskList.Add(task); + }); + Task.WaitAll(taskList.ToArray()); + var resultOK = taskList.All(u => u.GetAwaiter().GetResult()); + } + + + /// + /// 读取IO输入 + /// + /// 卡号 + /// 输入口 + /// 有输入返回true,无输入返回false + public bool GetDi(short index) + { + int value = 0; + + if ((value & (1 << index)) == 0) + { + return true;//有输入返回true + } + else + { + return false; //无输入返回false + } + } + + /// + /// 读取IO输出 + /// + /// io索引 + /// + public bool GetDoSts(short index) + { + int outSts = 0; + short outNum = (short)(index % 100); + // MotionCardAPI.GT_GetDo((short)IConfig.CardOrCoreNum, MotionCardAPI.MC_GPO, out outSts); + if ((outSts & (1 << outNum)) == 0) return true; + else return false; + } + + /// + /// 按位设置数字 IO 输出状态 + /// + /// 输出口,返回0-15 + /// false表示关,true表示开,板卡要设置取反 + public void WriteOutput(short index, IOValue value) + { + + ConvertFromIO(index, out ushort station, out ushort ioIndex); + + if ((int)value <= 1) // 输出电平 + { + CMCDLL_NET.MCF_Set_Output_Bit_Net(ioIndex, (ushort)(value == IOValue.TRUE ? 0 : 1), station); + } + else // 反转 + { + var currentValue = (int)CurrentIOs.FirstOrDefault(u => u.IOIndex == index && u.IOType == IOType.OUTPUT).IOValue; + CMCDLL_NET.MCF_Set_Output_Bit_Net(ioIndex, (ushort)(currentValue == 1 ? 0 : 1), station); + } + } + + /// + /// 读取轴状态,判断电机是否停止 + /// + /// 板卡号 + /// 轴号 + /// + public bool IsStop(short axisNum) + { + int sts = GetAxisStatus(axisNum); + return sts == 0; + } + + + /// + /// 读取轴状态 + /// + /// 轴号 + /// + public int GetAxisStatus(int axisNum) + { + short reason = 0; + + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + CMCDLL_NET.MCF_Get_Axis_State_Net(axis, ref reason, station); + + return reason; + } + + + public AxisMovingStatus GetAxisStatus2(int axisNum) + { + ConvertFromAxis(axisNum, out ushort station, out ushort axis); + + + short reason = 0; + CMCDLL_NET.MCF_Get_Axis_State_Net(axis, ref reason, station); + + ushort positiveLimit = 0; + CMCDLL_NET.MCF_Get_Positive_Limit_Net(axis, ref positiveLimit, station); + + ushort negativeLimit = 0; + CMCDLL_NET.MCF_Get_Negative_Limit_Net(axis, ref negativeLimit, station); + + ushort enable = 0; + CMCDLL_NET.MCF_Get_Servo_Enable_Net(axis, ref enable, station); + + ushort alarm = 0; + CMCDLL_NET.MCF_Get_Servo_Alarm_Net(axis, ref alarm, station); + + AxisMovingStatus status = new AxisMovingStatus + { + AxisIndex = axisNum, + AxisStatus = reason, + Alarm = alarm == 0, + Enable = enable == 0, + PositiveLimit = positiveLimit == 0, + NegativeLimit = negativeLimit == 0, + }; + + + return status; + } + + + public bool ClearStatus(int startAxisIndex) + { + /* 固高板卡原函数的含义:清除驱动器报警标志、跟随误差越限标志、限位触发标志 + 1. 只有当驱动器没有报警时才能清除轴状态字的报警标志 + 2. 只有当跟随误差正常以后,才能清除跟随误差越限标志 + 3. 只有当离开限位开关,或者规划位置在软限位行程以内时才能清除轴状态字的限位触发标志 + */ + + ConvertFromAxis(startAxisIndex, out ushort station, out ushort axisIndex); + + + // 清除轴报警原本寄存器 + short ret = CMCDLL_NET.MCF_Clear_Axis_State_Net(axisIndex, station); + + if (ret != (short)FuncRet.Function_Success) + { + return false; + } + + + // 设置伺服报警复位 + var axisSetting = AxisSettings.First(a => a.AxisIndex == startAxisIndex);// IConfig.AxisSettings[startAxisIndex]; + + if (axisSetting.IsUseAlarm) + { + ret = CMCDLL_NET.MCF_Set_Servo_Alarm_Reset_Net(axisIndex, (ushort)axisSetting.AlarmLogic, station); + } + return ret == (short)FuncRet.Function_Success; + } + + + /// + /// 位置回零 + /// + /// + /// + /// + public bool PositionReset(int startAxisIndex, int count) + { + + ConvertFromAxis(startAxisIndex, out ushort station, out ushort axis); + + var ret = CMCDLL_NET.MCF_Set_Position_Net(axis, 0, station); + var ret2 = CMCDLL_NET.MCF_Set_Encoder_Net(axis, 0, station); + + return ret == (ushort)FuncRet.Function_Success && ret2 == (ushort)FuncRet.Function_Success; + + } + + #endregion + + + #region IMonitor + + /// + /// 位置捕获监听,入料检测。 + /// 入料检测对射开关接到了HOME口,每当有新料到达入料检测传感器时,程序把当前位置当作原点,并调用函数 + /// + private void MonitorPieces() + { + var axisList = AxisSettings.Where(u => u.IsMonitorCapture).ToList(); + if (axisList.Count == 0) + { + return; + } + + axisList.ForEach(axis => + { + #region 注释掉之前的实现 + //Task.Run(() => + //{ + // int ai = (int)axis.AxisIndex; + + // // 物件大小,返回10组数据 + // uint[] Piece_Size = new uint[10]; + // // 物件间距,返回10组数据 + // uint[] Piece_Distance_To_next = new uint[10]; + // // 物件经过所有相机个数 + // uint Piece_Cross_Camera = 0; + + // Thread.CurrentThread.Priority = ThreadPriority.Highest; + // while (CurrentState != DeviceState.DSClose && CurrentState != DeviceState.DSExcept && CurrentState != DeviceState.DSUninit) + // { + // // 50us循环一次 + // Stopwatch sw = new Stopwatch(); + // uint tmpPieceNumber = 0; + + + // sw.Start(); + // short ret = CMCDLL_NET.MCF_Sorting_Get_Piece_State_Net(0, + // ref tmpPieceNumber, + // ref Piece_Size[0], + // ref Piece_Distance_To_next[0], + // ref Piece_Cross_Camera, + // IConfig.StationNumber); + // sw.Stop(); + // // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 读取板卡数据,物料编号{tmpPieceNumber},结果{ret},耗时{sw.ElapsedMilliseconds}ms"); + + // //if (tmpPieceNumber > piecesCount) + // //{ + // // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 物料编号:{tmpPieceNumber}\t耗时:{sw.ElapsedMilliseconds}ms"); + // //} + + // if (ret == 0 && tmpPieceNumber > piecesCount) + // { + + // sw.Start(); + // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 产品入列触发{tmpPieceNumber}"); + // // LogAsync(DateTime.Now, LogLevel.Information, $"产品入列触发 {piecesCount}"); + // if (tmpPieceNumber != piecesCount + 1) + // { + // // LogAsync(DateTime.Now, LogLevel.Information, $"产品入列触发丢失,{piecesCount}\t{tmpPieceNumber}"); + // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}\t产品入列触发丢失,{piecesCount}\t{tmpPieceNumber}"); + // } + // piecesCount = tmpPieceNumber; + // NewPieces(ai, piecesCount); + // sw.Stop(); + // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 物料编号:{tmpPieceNumber}\t耗时:{sw.ElapsedMilliseconds}ms"); + + // } + // // Thread.SpinWait(5); + // Thread.Sleep(30); + // // Task.Delay(5).Wait(); + + // } + //}); + + #endregion + + { + ParameterizedThreadStart ts = new ParameterizedThreadStart(MonitorPiecesImpl); + Thread th = new Thread(ts); + th.Priority = ThreadPriority.AboveNormal; + th.IsBackground = false; + th.Start(axis.AxisIndex); + } + + }); + } + + + + /// + /// 入料监听 + /// + /// + private void MonitorPiecesImpl(object axisIndex) + { + int ai = (int)axisIndex; + + ushort station = (ushort)(ai / 4); + + // 物件大小,返回10组数据 + uint[] Piece_Size = new uint[10]; + // 物件间距,返回10组数据 + uint[] Piece_Distance_To_next = new uint[10]; + // 物件经过所有相机个数 + uint Piece_Cross_Camera = 0; + + Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; + while (isconnected) + { + // for (ushort station = 0; station < _cardCount; station++) + // for (ushort disk = 0; disk < (ushort)IIConfig.MachineDiskType; disk++) + { + Stopwatch sw = new Stopwatch(); + uint tmpPieceNumber = 0; + + sw.Start(); + var disk = (ushort)(int)axisIndex; + + short ret = CMCDLL_NET_Sorting.MCF_Sorting_Get_Piece_State_Net(0, + ref tmpPieceNumber, + ref Piece_Size[0], + ref Piece_Distance_To_next[0], + ref Piece_Cross_Camera, + station); + + var sum = Piece_Size.Sum(x => x); + if (sum > 0) + { + Console.WriteLine(); + } + + sw.Stop(); + + if (ret == 0 && tmpPieceNumber > piecesCountDic[station]) + { + sw.Start(); + //string Picese_sizeStr=""; + //string Picese_DistanceizeStr=""; + //for (int i = 0; i < Piece_Size.Length; i++) + //{ + // Picese_sizeStr += i.ToString()+":"+Piece_Size[i]+"\t"; + // Picese_DistanceizeStr += i.ToString()+":"+ Piece_Distance_To_next[i]+"\t"; + //} + // LogAsync(DateTime.Now, LogLevel.Information, $"转盘{station}产品入列 , {piecesCountDic[station]} size:{Piece_Size[Piece_Size.Length - 1]}。"); + // LogAsync(DateTime.Now, LogLevel.Information, $"转盘{station}产品入列 ,监听piece_find{tmpPieceNumber} 监听物件大小" + Picese_sizeStr+",物件间距"+ Picese_DistanceizeStr+"相机经过个数"+Piece_Cross_Camera); + if (tmpPieceNumber != piecesCountDic[station] + 1) + { + // LogAsync(DateTime.Now, LogLevel.Information, $"转盘{station}入列触发丢失,{piecesCountDic[station]}\t{tmpPieceNumber}"); + } + piecesCountDic[station] = tmpPieceNumber; + + NewPieces(station + 1, piecesCountDic[station]); + sw.Stop(); + + } + + Thread.Sleep(1); + } + + + } + } + + + /// + /// 配置相机 + /// + private void ConfigCamera() + { + if (!IsEnableFilter) + { + return; + } + + var settingsGroup = SnapshotSettings.Where(s => s.IsEnabled).GroupBy(s => s.StationNumber) + .ToList(); + for (int group = 0; group < settingsGroup.Count; group++) + { + var camSettings = settingsGroup[group].ToList(); + + // 配置所有相机 + for (ushort i = 1; i <= camSettings.Count; i++) + { + var camSetting = camSettings[i - 1]; + + if (!camSetting.IsEnabled) + { + continue; + } + + var rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(i, + camSetting.CameraDelayCountMS, camSetting.StationNumber); + + + int CameraPositionReal = camSetting.CameraPosition; + ushort RotationDirectionReal = (ushort)camSetting.RotationDirection; + RotationDirectionEnum rotationDirectionEnum = camSetting.RotationDirection; + if (DiskSnaptChange && i >= SortingInputSetting.CameraStartNumber)//转盘2 + { + CameraPositionReal = -CameraPositionReal; + if (RotationDirectionReal == 0) + { + RotationDirectionReal = 1; + rotationDirectionEnum = RotationDirectionEnum.AntiClockwise; + } + else + { + RotationDirectionReal = 0; + rotationDirectionEnum = RotationDirectionEnum.Clockwise; + } + } + //修改板卡的IO + if (BoardCount == 2) + { + var ioIndex = camSetting.CameraIO.IOIndex - (camSetting.StationNumber * 16); + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Camera_Net( + i, // CCD0 + CameraPositionReal, + RotationDirectionReal, + (ushort)camSetting.ActionMode, + (ushort)ioIndex, // 8 + camSetting.StationNumber); + } + else + { + rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Camera_Net( + i, // CCD0 + CameraPositionReal, + RotationDirectionReal, + (ushort)camSetting.ActionMode, + (ushort)camSetting.CameraIO.IOIndex, // 8 + camSetting.StationNumber); + } + + //rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Camera_Net( + //i, // CCD0 + //camSetting.CameraPosition, + //(ushort)camSetting.RotationDirection, + //(ushort)camSetting.ActionMode, + //(ushort)camSetting.CameraIO.IOIndex, // 8 + //camSetting.StationNumber); + + // LogAsync(DateTime.Now, LogLevel.Action, $"相机{i}\t方向{rotationDirectionEnum.GetEnumDescription()}"); + + //配置图像处理时间 + // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Camera_Handle_Time_Net((ushort)(i + 1), (double)Handle_Time_1MS[i], (double)Handle_TimeOut_1MS[i], (uint)Handle_TimeOut_Number[i], StationNumber); + + } + + } + + + + // List settings = IIConfig.SnapshotSettings.Where(s => s.IsEnabled).ToList(); + + // 配置所有相机 + //for (ushort i = 1; i <= settings.Count; i++) + //{ + // var setting = settings[i - 1]; + + // if (!setting.IsEnabled) + // { + // continue; + // } + + // var rtn = CMCDLL_NET.MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(i, setting.CameraDelayCountMS, setting.StationNumber); + + // rtn = CMCDLL_NET.MCF_Sorting_Set_Camera_Net( + // i, + // setting.CameraPosition, + // (ushort)IIConfig.MotionDir, + // (ushort)setting.ActionMode, + // (ushort)setting.CameraIO.IOIndex, + // setting.StationNumber); + //} + } + + + private void ConfigBlow() + { + if (!IsEnableFilter) + { + return; + } + + //// 从检测配置中找到相应的转盘起始相机起始气阀配置 + //Dictionary listBlowStartD = new Dictionary(); + //var SortingInputGroup = IIConfig.SortingInputSettings.Where(s => s.Enable).ToList(); + //for (int group = 0; group < SortingInputGroup.Count; group++) + //{ + // if (!SortingInputGroup[group].EnableBindBlow) + // continue; + // var sets = SortingInputGroup[group].BlowStartNumber; + // listBlowStartD.Add((ushort)SortingInputGroup[group].BitInputNumber, sets); + //} + //// List settings = IIConfig.BlowSettings.Where(s => s.IsEnabled).ToList(); + + + var settingsGroup = BlowSettings.Where(s => s.IsEnabled).GroupBy(s => s.StationNumber) + .ToList(); + for (int group = 0; group < settingsGroup.Count; group++) + { + var blowSettings = settingsGroup[group].ToList(); + + // 配置所有吹气口 + for (ushort i = 0; i < blowSettings.Count; i++) + { + var blowSetting = blowSettings[i]; + //修改板卡的IO + var ioIndex = blowSetting.BlowIO.IOIndex - (blowSetting.StationNumber * 16); + if (!blowSetting.IsEnabled) + { + continue; + } + int CameraPositionReal = blowSetting.BlowPosition; + + RotationDirectionEnum rotationDirectionEnum = blowSetting.RotationDirection; + if (DiskSnaptChange)//转盘2 + { + CameraPositionReal = -CameraPositionReal; + if (rotationDirectionEnum == RotationDirectionEnum.Clockwise) + { + + rotationDirectionEnum = RotationDirectionEnum.AntiClockwise; + } + else + { + + rotationDirectionEnum = RotationDirectionEnum.Clockwise; + } + } + + switch (blowSetting.BlowType) + { + case BlowType.OK: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber); + break; + case BlowType.NG: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_NG_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber); + break; + case BlowType.Blow1: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(1, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber); + break; + ///第一路绑定OK NG 吹起口1 + case BlowType.Blow2: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(2, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber); + break; + case BlowType.Blow3: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(3, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber); + break; + case BlowType.Blow4: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(4, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber); + break; + //case BlowType.OK: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + //case BlowType.NG: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_NG_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + // TODO: 20231108 更新DLL调用类 + //case BlowType.Blow1: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_1_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + //case BlowType.Blow2: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_2_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + //case BlowType.Blow3: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_3_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + //case BlowType.Blow4: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_4_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + //case BlowType.Blow5: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_5_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + //case BlowType.Blow6: + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_6_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber); + // break; + default: + break; + } + } + + } + + } + + /// + /// 读取监听配置中的所有监听值 + /// + /// + public List GetMonitorValues() + { + var result = new List(); + + + for (ushort station = 0; station < 2; station++) + { + // 读取IO输入 + uint inValue = 0; + uint inValue2 = 0; + var ret = CMCDLL_NET.MCF_Get_Input_Net(ref inValue, ref inValue2, station); + + if (ret != (short)FuncRet.Function_Success) + { + return null; + } + + + // 读取IO输出 + uint outValue = 0; + ret = CMCDLL_NET.MCF_Get_Output_Net(ref outValue, station); + if (ret != (short)FuncRet.Function_Success) + { + return null; + } + var cardCount = 1; + switch (ExtBoard) + { + default: + case ExtensionBoardEnum.None: + case ExtensionBoardEnum.ExtIO_1: + break; + case ExtensionBoardEnum.ExtEC3216_1: + case ExtensionBoardEnum.ExtEC3224_1: + case ExtensionBoardEnum.ExtEC3416_1: + cardCount = 2; + break; + } + // 解析结果 + for (var index = 0; index < 16; index++) + //for (int index = 16 * station; index < 16 * (station + 1); index++) + { + IOItem inItem = new IOItem() + { + IOIndex = index + (station * 16), + IOValue = (inValue & (1 << index)) == 0 ? IOValue.TRUE : IOValue.FALSE, + IOType = IOType.INPUT + }; + IOItem outItem = new IOItem() + { + IOIndex = index + (station * 16), + IOValue = (outValue & (1 << index)) == 0 ? IOValue.TRUE : IOValue.FALSE, + IOType = IOType.OUTPUT + }; + result.Add(inItem); + result.Add(outItem); + } + } + + + return result; + } + + + private void MonitorPosition() + { + Task.Run(() => + { + Thread.CurrentThread.Priority = ThreadPriority.Highest; + while (isconnected) + { + try + { + if (!IsEnableMonitor) + { + return; + } + + Parallel.ForEach(AxisStatusList, a => + { + if (a.IsMonitorPosition) + { + int prfPosition = GetPrfPosition(a.AxisIndex); + int curPosition = GetCurPosition(a.AxisIndex); + a.PrfPosition = prfPosition; + + if (a.CurPosition != curPosition) + { + a.CurPosition = curPosition; + AxisPositionChangedAsync(a.AxisIndex, curPosition); + } + } + }); + } + catch (Exception ex) + { + //if (CurrentState == DeviceState.DSOpen) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}监听轴信息异常{ex.GetExceptionMessage()}"); + //} + } + } + }); + } + public void AxisPositionChangedAsync(int axisIndex, int currentPosition) + { + //OnAxisPositionChanged?.Invoke(axisIndex, currentPosition); + } + + private void MonitorAxisStatus() + { + Task.Run(() => + { + while (isconnected) + { + try + { + if (!IsEnableMonitor) + return; + + AxisStatusList.ForEach(axis => + { + if (!axis.IsMonitorStatus) + { + return; + } + + double prfVel = 0; + double curVel = 0; + GetVelocity(axis.AxisIndex, ref prfVel, ref curVel); + + axis.PrfVelocity = prfVel; + axis.CurVelocity = curVel; + + // int status = GetAxisStatus(axis.AxisIndex); + //if (axis.AxisStatus != status) + //{ + // int temp = axis.AxisStatus; + // axis.AxisStatus = status; + + // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}监听轴信息MonitorAxisStatus:{status}"); + + // AxisAlarmCheckAsync(axis.AxisIndex, temp, status); + // AxisStatusChanged(axis.AxisIndex, temp, status); + //} + + AxisMovingStatus status = GetAxisStatus2(axis.AxisIndex); + + axis.Alarm = status.Alarm; + axis.Enable = status.Enable; + axis.PositiveLimit = status.PositiveLimit; + axis.NegativeLimit = status.NegativeLimit; + + + if (axis.AxisStatus != status.AxisStatus) + { + int temp = axis.AxisStatus; + axis.AxisStatus = status.AxisStatus; + + AxisAlarmCheckAsync(axis.AxisIndex, temp, status.AxisStatus); + AxisStatusChanged(axis.AxisIndex, temp, status.AxisStatus); + } + + + }); + } + catch (Exception ex) + { + //if (CurrentState == DeviceState.DSOpen) + //{ + // // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}监听轴信息异常{ex.GetExceptionMessage()}"); + //} + } + } + }); + } + public void AxisStatusChanged(int axisIndex, int preStatus, int curStatus) + { + //OnAxisStatusChanged?.BeginInvoke(axisIndex, preStatus, curStatus, null, null); + } + private void AxisAlarmCheckAsync(int axisIndex, int temp, int curStatus) + { + ////TODO: 2022/10/22 13:00 暂时屏蔽报警 + return; + + if (curStatus >= 14 && curStatus <= 21) + { + #region 正负极限 + if (!_axisAlarmRaisedFlag[axisIndex]) + { + _axisLimitTimer[axisIndex].Change(3000, -1); + } + #endregion + } + else if (curStatus == 22 || curStatus == 23) + { + if (!_axisAlarmRaisedFlag[axisIndex]) + { + _axisLimitTimer[axisIndex].Change(3000, -1); + } + } + else + { + _axisLimitTimer[axisIndex].Change(-1, -1); + // 极限报警 可以自动清除 + if (_axisAlarmRaisedFlag[axisIndex]) + { + AxisAlarmRaised(axisIndex, $"轴{axisIndex}在 正极限", false); + AxisAlarmRaised(axisIndex, $"轴{axisIndex}在 负极限", false); + } + + bool flag = false; + string msg = ""; + if (((curStatus >> 1) & 1) == 1) + { + #region 轴报警 + if (!_axisAlarmRaisedFlag[axisIndex]) + { + flag = true; + msg = $"轴{axisIndex}伺服报警"; + } + #endregion + } + else if (((curStatus >> 8) & 1) == 1) + { + #region 轴急停 + if (!_axisAlarmRaisedFlag[axisIndex]) + { + flag = true; + msg = $"轴{axisIndex}急停报警"; + } + #endregion + } + if (flag) + { + //伺服报警 无法自动清除 + AxisAlarmRaised(axisIndex, msg, flag); + } + } + } + + private static readonly object ioLock = new object(); + + + public void Monitor() + { + //SpinWait _monitorWait = new SpinWait(); + if (!IsEnableMonitor) + return; + + Task.Run(() => + { + //Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; + Thread.CurrentThread.Priority = ThreadPriority.Highest; + + while (isconnected) + { + try + { + var newValues = GetMonitorValues(); + + //if (CurrentState == DeviceState.DSClose || CurrentState == DeviceState.DSExcept || CurrentState == DeviceState.DSUninit) + //{ + // break; + //} + + + if (newValues == null || newValues.Count == 0) + continue; + + if (CurrentIOs.Count == newValues.Count) + { + //if (IConfig.IsEnableMonitor) + //{ + var tempNew = new List(newValues);//clone + var tempOld = new List(CurrentIOs); + MonitorCheckAndInvoke(tempNew, tempOld); + //} + + } + CurrentIOs = new List(newValues); + + if (MonitorInterval > 0) + { + Task.Delay(MonitorInterval).Wait(); + } + } + catch (Exception ex) + { + //if (CurrentState == DeviceState.DSOpen) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}监听IO异常{ex.GetExceptionMessage()}"); + //} + } + } + }); + } + + + + public void OnMethodInvoked(IAsyncResult ar) + { + //MotionCardMonitorSet monitorSet = ar.AsyncState as MotionCardMonitorSet; + //ProcessResponse resValues = monitorSet.Response; + //if (resValues.ResultValue == (int)ReplyValue.IGNORE) + //{ + // return; + //} + + //Stopwatch sw = new Stopwatch(); + //sw.Start(); + //// 将指定IOItem写入板卡 + //foreach (var replyIOData in monitorSet.ReplyIODatas) + //{ + // //写入IO输出 + // if (replyIOData.IOType == IOType.OUTPUT) + // { + // GTSCardAPI.GT_SetDoBit((short)IConfig.CardNum, GTSCardAPI.MC_GPI, (short)replyIOData.IONum, (short)replyIOData.Value); + // } + // // in只读不能写 + //} + //sw.Stop(); + //LogAsync(DateTime.Now, $"{Name}反馈完成,耗时{sw.ElapsedMilliseconds}ms", $"{resValues.GetDisplayText()}"); + } + + protected async void MonitorCheckAndInvoke(List tempNew, List tempOld) + { + //await Task.Run(() => + //{ + // Thread.CurrentThread.Priority = ThreadPriority.Highest; + // #region 警报信息 + // WarningSetCollection.ForEach(wSet => + // { + // IOWarningSet warningSet = wSet as IOWarningSet; + + // var temp = tempNew.FirstOrDefault(u => u.IOIndex == warningSet.TriggerIndex && u.IOType == warningSet.IOType); + // if (temp != null) + // { + // bool isOn = ((int)temp.IOValue == (warningSet.TriggerValue ? 1 : 0)); + // if (warningSet.CurrentStatus != isOn) + // { + // warningSet.CurrentStatus = isOn; + // warningSet.TriggerTime = DateTime.Now; + // SaveAlarmCSVAsync(DateTime.Now, this.Name, warningSet); + // ExcuteMonitorAlarm(DateTime.Now, this, warningSet); + // } + // } + // }); + // #endregion + + // #region 监听信息 + // Parallel.ForEach(IConfig.MonitorSetCollection, mSet => + // MonitorSetCollection.ForEach(mSet => + // { + // IOMonitorSet monitorSet = mSet as IOMonitorSet; + // if (monitorSet.TriggerIndex < 0 || monitorSet.TriggerIndex > tempNew.Count) + // { + // return; + // } + + // if (monitorSet.MethodCode.Equals("InitialAirAlarm")) + // { + // Console.WriteLine(""); + // } + + + // if (!monitorSet.JumpEdgeMonitor) + // { + // var newIOItem = tempNew.FirstOrDefault(u => u.IOIndex == monitorSet.TriggerIndex && u.IOType == monitorSet.IOType); + + // if (monitorSet.TriggerValue == -999 || (int)newIOItem.IOValue == monitorSet.TriggerValue) + // { + // if (monitorSet.OpConfig == null) + // { + // monitorSet.OpConfig = new OperationConfigBase(); + // } + + // monitorSet.OpConfig.TriggerValue = (int)newIOItem.IOValue; + + // ExcuteMonitorInvoke(DateTime.Now, monitorSet.ExecuteDevice, this, monitorSet); + // } + + // } + // else + // { + // var newIOItem = tempNew.FirstOrDefault(u => u.IOIndex == monitorSet.TriggerIndex && u.IOType == monitorSet.IOType); + // var oldIOItem = tempOld.FirstOrDefault(u => u.IOIndex == monitorSet.TriggerIndex && u.IOType == monitorSet.IOType); + + // if (newIOItem?.IOValue != oldIOItem?.IOValue) + // { + // if (monitorSet.TriggerValue == -999 || (int)newIOItem.IOValue == monitorSet.TriggerValue) + // { + // if (monitorSet.OpConfig == null) + // { + // monitorSet.OpConfig = new OperationConfigBase(); + // } + + // monitorSet.OpConfig.InputPara = monitorSet.InputDataIndex.ConvertAll(index => + // { + // return tempNew[index].Value == IOValue.TRUE ? 1 : 0; + // }).ToList(); + + // monitorSet.OpConfig.TriggerValue = (int)newIOItem.IOValue; + // monitorSet.OpConfig.InputPara = new List() { (int)newIOItem.IOValue }; + // LogAsync(DateTime.Now, $"newIOItem:{newIOItem.GetDisplayText()}", $"oldIOItem:{oldIOItem.GetDisplayText()}"); + // ExcuteMonitorInvoke(DateTime.Now, monitorSet.ExecuteDevice, this, monitorSet); + // } + // } + // } + // }); + // #endregion + //}); + } + + public void ResetAlarm() + { + //int axis_sts; + //var axisSettings = IConfig.AxisSettings.FindAll(u => u.IsAxisEnabled); + + //axisSettings.ForEach(axisSetting => ClearStatus(axisSetting.AxisIndex)); + + //foreach (var axisSetting in axisSettings) + //{ + // ConvertFromAxis(axisSetting.AxisIndex, out ushort station, out ushort axis); + + // axis_sts = AxisStatusList.FirstOrDefault(u => u.AxisIndex == axisSetting.AxisIndex)?.AxisStatus ?? 0; + // if ((axis_sts & 0x200) == 0) // 0010 0000 0000 + // { + // // 关闭电机使能 + // var rst = CMCDLL_NET.MCF_Set_Servo_Enable_Net(axis, (ushort)ServoLogic.Servo_Close, station); + // } + + // // 正极限报警 + // if ((axis_sts & 0x20) != 0) + // { + // // 负向移动 + // MovingOption movingOption = new MovingOption(); + // movingOption.AxisIndex = (short)axisSetting.AxisIndex; + // movingOption.Destination = -50; // 负向移动 + // movingOption.VelocityPara.Velocity = 50; + // P2PMoveAbs(movingOption); + // } + + // // 负极限报警 + // if ((axis_sts & 0x40) != 0) + // { + // // 正向移动 + // MovingOption movingOption = new MovingOption(); + // movingOption.AxisIndex = (short)axisSetting.AxisIndex; + // movingOption.Destination = 50; // 正向移动 + // movingOption.VelocityPara.Velocity = 50; + // P2PMoveAbs(movingOption); + // } + //} + + //// 清除状态 + //axisSettings.ForEach(axisSetting => ClearStatus(axisSetting.AxisIndex)); + + //_axisAlarmRaisedFlag.Values.ToList().ForEach(u => u = false); + //_axisLimitTimer.Values.ToList().ForEach(u => u.Change(-1, -1)); + //base.ResetAlarm(); + } + + public bool SmartGoHome(ushort AxisIndex, GoHomePara goHomePara) + { + bool result = false; + + + result = ClearStatus(AxisIndex); + + + + if (!result) + { + //LogAsync(DateTime.Now, LogLevel.Exception, "SmartGoHome清除状态异常-Before"); + return result; + } + result = PositionReset(AxisIndex, 1); + if (!result) + { + //LogAsync(DateTime.Now, LogLevel.Exception, "SmartGoHome清除位置异常-Before"); + return result; + } + short sRtn; + + ConvertFromAxis(AxisIndex, out ushort station, out ushort axis); + + sRtn = CMCDLL_NET.MCF_Search_Home_Stop_Time_Net(axis, goHomePara.SearchHomeStopTime, station); + sRtn = CMCDLL_NET.MCF_Search_Home_Set_Net(axis, + (ushort)goHomePara.HomeMode, + (ushort)goHomePara.LimitLogic, + (ushort)goHomePara.HomeLogic, + (ushort)goHomePara.IndexLogic, + goHomePara.H_dMaxV, goHomePara.L_dMaxV, + goHomePara.OffsetPosition, + (ushort)goHomePara.TriggerSource, + station); + sRtn = CMCDLL_NET.MCF_Search_Home_Start_Net(axis, station); + + + Console.WriteLine($">>>> {AxisIndex}\t{goHomePara.SearchHomeStopTime}"); + Console.WriteLine($">>>> {AxisIndex}\t" + + $"{(ushort)goHomePara.HomeMode}\t" + + $"{(ushort)goHomePara.LimitLogic}\t" + + $"{(ushort)goHomePara.HomeLogic}\t" + + $"{(ushort)goHomePara.IndexLogic}\t" + + $"{goHomePara.H_dMaxV}\t" + + $"{goHomePara.L_dMaxV}\t" + + $"{goHomePara.OffsetPosition}\t" + + $"{(ushort)goHomePara.TriggerSource}"); + + //var rtn = CMCDLL_NET.MCF_Search_Home_Stop_Time_Net(1, 0, 0); + //rtn = CMCDLL_NET.MCF_Search_Home_Set_Net(1, 30, 0, 0, 0, 10000, 3000, 0, 0, 0); + //rtn = CMCDLL_NET.MCF_Search_Home_Start_Net(1, 0); + + + int timeout = goHomePara.GoHomeTimeOut * 1000; + + ushort homeState = 1; + do + { + sRtn = CMCDLL_NET.MCF_Search_Home_Get_State_Net(axis, ref homeState, station); + + Task.Delay(MonitorInterval).Wait(); + timeout -= MonitorInterval; + } while (homeState != (short)SearchHomeState.HomeSucess && timeout > 0);//100表示回原点完成 + + if (timeout < 0) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴号:{AxisIndex}-SmartGoHome超时"); + return false; + } + + timeout = goHomePara.GoHomeTimeOut * 1000; + result = ClearStatus(AxisIndex); + do + { + Task.Delay(20).Wait(); + result = ClearStatus(AxisIndex); + timeout -= 20; + } while (!result && timeout > 0); + if (timeout < 0) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴号:{AxisIndex}-SmartGoHome:ClearStatus超时"); + return false; + } + + timeout = goHomePara.GoHomeTimeOut * 1000; + result = PositionReset(AxisIndex, 1); + do + { + Task.Delay(20).Wait(); + result = PositionReset(AxisIndex, 1); + timeout -= 20; + } while (!result && timeout > 0); + if (timeout < 0) + { + //LogAsync(DateTime.Now, LogLevel.Exception, $"轴号:{AxisIndex}-SmartGoHome:PositionReset超时"); + return false; + } + + return result; + } + + public bool SmartGetHomeStatus(ushort AxisIndex, GoHomeStatus homeStatus) + { + ConvertFromAxis(AxisIndex, out ushort station, out ushort axis); + + ushort homeState = (ushort)SearchHomeState.Homing; + CMCDLL_NET.MCF_Search_Home_Get_State_Net(axis, ref homeState, station); + homeStatus.Status = homeState; + + return true; + } + #endregion + + public bool SetDac(short channel, short sValue) + { + short ret = 0; + return ret == (short)FuncRet.Function_Success; + } + + public short GetDac(short channel) + { + short resultValue = 0; + //short ret = MotionCardAPI.GT_GetDac((short)IConfig.CardOrCoreNum, channel, out short value, 1, out uint pLock); + //if (ret != RetCode.Function_Success) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, "通道" + channel + "读取模拟量输出异常,错误码:" + ret + ";"); + //} + //short resultValue = (short)((value - 3200) / 50); + return resultValue; + } + + public double GetAdc(short channel) + { + var resultValue = 0f; + //short ret = MotionCardAPI.GT_GetAdc((short)IConfig.CardOrCoreNum, channel, out double resultValue, 1, out uint pLock); + //if (ret != RetCode.Function_Success) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, "通道" + channel + "读取模拟量输入异常,错误码:" + ret + ";"); + //} + return resultValue; + } + + public short GetAdcValue(short channel) + { + short resultValue = 0; + //short ret = MotionCardAPI.GT_GetAdcValue((short)IConfig.CardOrCoreNum, channel, out short resultValue, 1, out uint pLock); + //if (ret != RetCode.Function_Success) + //{ + // LogAsync(DateTime.Now, LogLevel.Exception, "通道" + channel + "读取模拟量输入数字转换值异常, 错误码:" + ret + ";"); + //} + return resultValue; + } + + + /// + /// 吹气 + /// + /// + /// + /// + public void Blow(uint pieceNumber, BlowType blowType) + { + var bSetting = BlowSettings.FirstOrDefault(b => b.IsEnabled && b.BlowType == blowType); + if (bSetting == null) + { + return; + } + + // 板卡1队列及时处理 + switch (blowType) + { + case BlowType.OK: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Blow_OK_Net(pieceNumber, bSetting.StationNumber); + break; + case BlowType.NG: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Blow_NG_Net(pieceNumber, bSetting.StationNumber); + break; + + default: + CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Blow_Net((ushort)blowType, pieceNumber, bSetting.StationNumber); + break; + + } + } + + + ///// + ///// 吹气 + ///// + ///// + ///// + ///// + //public override void Blow(uint pieceNumber, ushort index) + //{ + // //var bSetting = IIConfig.BlowSettings.FirstOrDefault(b => b.IsEnabled && b.BlowType == blowType); + // //if (bSetting == null) + // //{ + // // return; + // //} + // CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Blow_Net(index, pieceNumber); + //} + + + } + + + +} diff --git a/DH.Devices.Motion/SolidMotionCardEnum.cs b/DH.Devices.Motion/SolidMotionCardEnum.cs new file mode 100644 index 0000000..74e9309 --- /dev/null +++ b/DH.Devices.Motion/SolidMotionCardEnum.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DH.Devices.Motion +{ + + + + /// + /// 回零状态 + /// + public enum SearchHomeState + { + /// + /// 回零成功 + /// + [Description("回零成功")] + HomeSucess = 0, + + /// + /// 回零错误 + /// + [Description("回零错误")] + HomeError = 31, + + /// + /// 正在回零点 + /// + [Description("正在回零点")] + Homing = 32, + } + + + + + /// + /// 0.3 坐标模式 + /// + public enum PositionMode + { + /// + /// 绝对位置模式 + /// + [Description("绝对位置模式")] + Position_Absolute = 0, + + + /// + /// 相对位置模式 + /// + [Description("相对位置模式")] + Position_Opposite = 1, + + } + + + /// + /// 0.4 单轴点动曲线类型 + /// + public enum Profile + { + /// + /// T型曲线 + /// + [Description("T型曲线")] + Profile_T = 0, + + /// + /// S型曲线 + /// + [Description("S型曲线")] + Profile_S = 1, + + } + + + + /// + /// 3.1 伺服使能设置 + /// + public enum ServoLogic + { + /// + /// 触点闭合 + /// + [Description("触点闭合")] + Servo_Close = 0, + + + /// + /// 触点打开 + /// + [Description("触点打开")] + Servo_Open = 1, + + } + + /// + /// 3.2 报警复位电平设置 + /// + public enum AlarmLogic + { + /// + /// 触点闭合 + /// + [Description("触点闭合")] + Alarm_Close = 0, + + + /// + /// 触点打开 + /// + [Description("触点打开")] + Alarm_Open = 1, + + } + + + /// + /// 3.6 + /// + public enum HomeState + { + /// + /// 触点闭合,硬件灯亮 + /// + [Description("触点闭合,硬件灯亮")] + Home_Close = 0, + + + /// + /// 触点打开,硬件灯灭 + /// + [Description("触点打开,硬件灯灭")] + Home_Open = 1, + } + + + + /// + /// 4.1 脉冲模式 + /// + public enum PulseMode + { + /// + /// 脉冲方向(默认) + /// + [Description("模式0")] + Pulse_Dir_H = 0, + + + /// + /// 脉冲方向 + /// + [Description("模式1")] + Pulse_Dir_L = 1, + + + /// + /// 双脉冲 + /// + [Description("模式2")] + Pulse_CW_CCW = 2, + + + /// + /// 双脉冲 + /// + [Description("模式3")] + Pulse_CCW_CW = 3, + + + /// + /// AB相位 + /// + [Description("模式4")] + Pulse_AB = 4, + + + /// + /// AB相位 + /// + [Description("模式5")] + Pulse_BA = 5, + + + } + + + /**************************************************************************************************************** +5 轴硬件触发停止运动函数 +*****************************************************************************************************************/ + //5.1 EMG_Mode + public enum EMG_Mode + { + [Description("不使用紧急停止功能")] + EMG_Trigger_Close = 0, //不使用紧急停止功能 + + [Description("低电平触发紧急停止")] + EMG_Trigger_Low_IMD = 1, //低电平触发紧急停止 + + [Description("低电平触发减速停止")] + EMG_Trigger_Low_DEC = 2,//低电平触发减速停止 + + [Description("高电平触发紧急停止")] + EMG_Trigger_High_IMD = 3, //高电平触发紧急停止 + + } + + + + + + /// + /// 6.1.1 正负限位触发电平 + /// + public enum LimitLogic + { + /// + /// 低电平触发 + /// + [Description("低电平触发")] + Low_Logic = 0, + + + /// + /// 高电平触发 + /// + [Description("高电平触发")] + High_Logic = 1, + } + + /// + /// 6.1.2 回零限位触发电平 + /// + public enum HomeLogic + { + /// + /// 低电平触发 + /// + [Description("低电平触发")] + Low_Logic = 0, + + + /// + /// 高电平触发 + /// + [Description("高电平触发")] + High_Logic = 1, + } + + /// + /// 6.1.3 Index触发电平 + /// + public enum IndexLogic + { + /// + /// 低电平触发 + /// + [Description("低电平触发")] + Low_Logic = 0, + + + /// + /// 高电平触发 + /// + [Description("高电平触发")] + High_Logic = 1, + } + + + +} diff --git a/DH.Devices.PLC/XinJEPLCTcpNet.cs b/DH.Devices.PLC/XinJEPLCTcpNet.cs index 5241bc9..ac98610 100644 --- a/DH.Devices.PLC/XinJEPLCTcpNet.cs +++ b/DH.Devices.PLC/XinJEPLCTcpNet.cs @@ -49,7 +49,7 @@ namespace DH.Devices.PLC { connected = true; MonitorPieces(); - TurntableOpen(2000,true); + TurntableOpen(12000,true); return true; } diff --git a/DHSoftware.sln b/DHSoftware.sln index 500edbf..0b768df 100644 --- a/DHSoftware.sln +++ b/DHSoftware.sln @@ -23,6 +23,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Camera", "DH.Dev EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.PLC", "DH.Devices.PLC\DH.Devices.PLC.csproj", "{458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Motion", "Motion", "{5C8472C6-EB6A-4D89-B519-7073BBF6A5D2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Motion", "DH.Devices.Motion\DH.Devices.Motion.csproj", "{144E3775-0BD7-4528-9FB0-A0F4ADC74313}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,6 +75,14 @@ Global {458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D}.Release|Any CPU.Build.0 = Release|Any CPU {458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D}.Release|x64.ActiveCfg = Release|x64 {458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D}.Release|x64.Build.0 = Release|x64 + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Debug|Any CPU.Build.0 = Debug|Any CPU + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Debug|x64.ActiveCfg = Debug|x64 + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Debug|x64.Build.0 = Debug|x64 + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|Any CPU.ActiveCfg = Release|Any CPU + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|Any CPU.Build.0 = Release|Any CPU + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|x64.ActiveCfg = Release|x64 + {144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -83,6 +95,8 @@ Global {97B55FCF-54A3-449E-8437-735E65C35291} = {F77AF94C-280D-44C5-B7C0-FC86AA9EC504} {1378A932-1C25-40EF-BA31-A3463B23F4E5} = {1591B03B-0015-42FC-B784-0D9F740E2A23} {458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D} = {2560C5A5-0CA2-48AD-B606-6C55BEFD8109} + {5C8472C6-EB6A-4D89-B519-7073BBF6A5D2} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0} + {144E3775-0BD7-4528-9FB0-A0F4ADC74313} = {5C8472C6-EB6A-4D89-B519-7073BBF6A5D2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6FC1A8DF-636E-434C-981E-10F20FAD723B} diff --git a/DHSoftware/MainWindow.cs b/DHSoftware/MainWindow.cs index d3e14cd..90b5eba 100644 --- a/DHSoftware/MainWindow.cs +++ b/DHSoftware/MainWindow.cs @@ -17,6 +17,8 @@ using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; +using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using static AntdUI.Math3D; @@ -209,7 +211,7 @@ namespace DHSoftware - + public List HKCameras { get; } = new List(); public List Cameras { get; } = new List(); public Dictionary Dectection { get; } = new Dictionary(); public XinJEPLCTcpNet PLC { get; } = new XinJEPLCTcpNet(); @@ -224,7 +226,10 @@ namespace DHSoftware { camera.CameraDisConnect(); } - + foreach (var camera in HKCameras) + { + camera.CameraDisConnect(); + } PLC.PLCDisConnect(); } @@ -339,6 +344,7 @@ namespace DHSoftware detectionList.Add(det3); detectionList.Add(det4); Cameras.Clear(); + HKCameras.Clear(); Dectection.Clear(); _cameraRelatedDetectionDict = new(); @@ -365,7 +371,34 @@ namespace DHSoftware } ); }); - + string inferenceDevice = "CPU"; + //for (int i = 1; i <= 8; i++) + //{ + // HikVisionCamera camera = new HikVisionCamera(); + // camera.CameraName = $"Cam{i}"; + // camera.CameraIP = $"192.168.{i}.1"; + // camera.ComputerIP = $"192.168.{i}.1"; + // camera.CameraConnect(); + // camera.OnHImageOutput += OnCameraHImageOutput; + // HKCameras.Add(camera); + // var simbo_1 = new SimboObjectDetection + // { + + // }; + // MLInit mLInit_1; + + + // mLInit_1 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam{i}.onnx", "images", inferenceDevice, 640, 640); + + + // simbo_1.Load(mLInit_1); + // Dectection.Add(camera.CameraName, simbo_1); + //} + + + + + //Add the code for the "启动" button click here Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera(); @@ -383,7 +416,7 @@ namespace DHSoftware do3ThinkCamera2.OnHImageOutput += OnCameraHImageOutput; var simbo1 = new SimboObjectDetection(); MLInit mLInit; - string inferenceDevice = "CPU"; + mLInit = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.onnx", "images", inferenceDevice, 640, 640); @@ -395,9 +428,9 @@ namespace DHSoftware var simbo2 = new SimboObjectDetection(); MLInit mLInit2; - string inferenceDevice2 = "CPU"; + - mLInit2 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam2.onnx", "images", inferenceDevice2, 640, 640); + mLInit2 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam2.onnx", "images", inferenceDevice, 640, 640); simbo2.Load(mLInit2); @@ -479,6 +512,7 @@ namespace DHSoftware { using (Mat localImageSet = imageSet.Clone()) // 复制 Mat 避免并发问题 { + // imageSet?.Dispose(); // 拍照计数与物件编号一致,查找对应的产品 ProductData product = null; //内外壁模组多个相机的处理方法 @@ -558,190 +592,148 @@ namespace DHSoftware return; } - - #region 1.预处理 - #endregion - #region 2.深度学习推理 - var req = new MLRequest(); - - req.mImage = localImageSet.Clone(); - //req.ResizeWidth = detectConfig.ModelWidth; - //req.ResizeHeight = detectConfig.ModelHeight; - //req.confThreshold = detectConfig.ModelconfThreshold; - //req.iouThreshold = 0.3f; - //req.out_node_name = detectConfig.ModeloutNodeName; - //req.in_lable_path = detectConfig.in_lable_path; - req.ResizeWidth = 640; - req.ResizeHeight = 640; - req.confThreshold = 0.5f; - req.iouThreshold = 0.3f; - req.out_node_name = "output0"; - req.in_lable_path = "D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.txt"; - //req.LabelNames = dc.GetLabelNames(); - - //HOperatorSet.WriteImage(req.HImage, "png", 0, @"D:\\666.png"); - Stopwatch - sw = new Stopwatch(); - sw.Start(); - - - var result = Dectection[detectionId].RunInference(req); - sw.Stop(); - //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms"); - #endregion - this.BeginInvoke(new MethodInvoker(delegate () + // 1. 预处理 + using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本 { - if (pictureBox1.Image != null) + #region 1.预处理 + #endregion + #region 2.深度学习推理 + var req = new MLRequest(); + + req.mImage = inferenceImage; + + req.ResizeWidth = 640; + req.ResizeHeight = 640; + req.confThreshold = 0.5f; + req.iouThreshold = 0.3f; + req.out_node_name = "output0"; + req.in_lable_path = "D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.txt"; + + Stopwatch sw = Stopwatch.StartNew(); + var result = Dectection[detectionId].RunInference(req); + sw.Stop(); + //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms"); + #endregion + this.BeginInvoke(new MethodInvoker(delegate () { - pictureBox1.Image.Dispose(); // 释放旧图像 - } - pictureBox1.Image = result.ResultMap; - richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess} 耗时 {sw.ElapsedMilliseconds}ms\n"); - })); - req.mImage.Dispose(); + pictureBox1.Image?.Dispose(); // 释放旧图像 + pictureBox1.Image = result.ResultMap; + richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess} 耗时 {sw.ElapsedMilliseconds}ms\n"); + })); + req.mImage.Dispose(); #if true - #region 3.后处理 - DetectStationResult detectResult = new DetectStationResult(); - if (result == null || (result != null && !result.IsSuccess)) - { - detectResult.IsMLDetectDone = false; - } - if (result != null && result.IsSuccess) - { - detectResult.DetectDetails = result.ResultDetails; - if (detectResult.DetectDetails != null) - { - } - else + #region 3.后处理 + DetectStationResult detectResult = new DetectStationResult(); + if (result == null || (result != null && !result.IsSuccess)) { detectResult.IsMLDetectDone = false; } - } - - #endregion - #region 3.后处理 - #endregion - //根据那些得分大于阈值的推理结果,判断产品是否成功 - #region 4.最终过滤(逻辑过滤) - detectResult.DetectDetails?.ForEach(d => - { - - - //当前检测项的 过滤条件 - //var conditionList = detectConfig.DetectionFilterList - // .Where(u => u.IsEnabled && u.LabelName == d.LabelName) - // .GroupBy(u => u.ResultState) - // .OrderBy(u => u.Key) - // .ToList(); - //当前检测项的 过滤条件 - var conditionList = detectConfig.DetectionFilterList - .Where(u => u.IsEnabled && u.LabelName == d.LabelName) - .GroupBy(u => u.ResultState) - .OrderBy(u => u.Key) - .ToList(); - - if (conditionList.Count == 0) + if (result != null && result.IsSuccess) { - - if (d.LabelName.ToLower() == "ok") + detectResult.DetectDetails = result.ResultDetails; + if (detectResult.DetectDetails != null) { - d.FinalResult = d.InferenceResult = ResultState.OK; } else { - d.FinalResult = d.InferenceResult = ResultState.DetectNG; + detectResult.IsMLDetectDone = false; } } - else + + #endregion + #region 3.后处理 + #endregion + //根据那些得分大于阈值的推理结果,判断产品是否成功 + #region 4.最终过滤(逻辑过滤) + detectResult.DetectDetails?.ForEach(d => { - if (detectConfig.IsMixModel) + + + //当前检测项的 过滤条件 + //var conditionList = detectConfig.DetectionFilterList + // .Where(u => u.IsEnabled && u.LabelName == d.LabelName) + // .GroupBy(u => u.ResultState) + // .OrderBy(u => u.Key) + // .ToList(); + //当前检测项的 过滤条件 + var conditionList = detectConfig.DetectionFilterList + .Where(u => u.IsEnabled && u.LabelName == d.LabelName) + .GroupBy(u => u.ResultState) + .OrderBy(u => u.Key) + .ToList(); + + if (conditionList.Count == 0) { - d.FinalResult = d.InferenceResult = ResultState.A_NG; + + d.FinalResult = d.LabelName.ToLower() == "ok" + ? ResultState.OK + : ResultState.DetectNG; } else { - //将所有已将筛选出来的缺陷进行过滤 - d.FinalResult = d.InferenceResult = ResultState.OK; + d.FinalResult = detectConfig.IsMixModel + ? ResultState.A_NG + : ResultState.OK; + + } - } - - - foreach (IGrouping group in conditionList) - { - bool b = group.ToList().Any(f => + foreach (IGrouping group in conditionList) { - return f.FilterOperation(d); - }); + //bool b = group.ToList().Any(f => + //{ + // return f.FilterOperation(d); + //}); - if (b) - { - d.FinalResult = group.Key; - break; + //if (b) + //{ + // d.FinalResult = group.Key; + // break; + //} + + if (group.Any(f => f.FilterOperation(d))) + { + d.FinalResult = group.Key; + break; + } + //else + //{ + // d.FinalResult = d.InferenceResult = ResultState.OK; + //} } - //else - //{ - // d.FinalResult = d.InferenceResult = ResultState.OK; - //} - } - }); - #endregion - #region 5.统计缺陷过滤结果或预处理直接NG - if (detectResult.DetectDetails?.Count > 0) - { - detectResult.ResultState = detectResult.DetectDetails.GroupBy(u => u.FinalResult).OrderBy(u => u.Key).First().First().FinalResult; + }); + #endregion + #region 5.统计缺陷过滤结果或预处理直接NG + //if (detectResult.DetectDetails?.Count > 0) + //{ + // detectResult.ResultState = detectResult.DetectDetails.GroupBy(u => u.FinalResult).OrderBy(u => u.Key).First().First().FinalResult; + // detectResult.ResultLabel = detectResult.ResultLabel; + // detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 + + + //} + detectResult.ResultState = detectResult.DetectDetails? + .GroupBy(u => u.FinalResult) + .OrderBy(u => u.Key) + .FirstOrDefault()?.Key ?? ResultState.OK; detectResult.ResultLabel = detectResult.ResultLabel; detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 - //////根据优先级设置ResultLabel - //if (detectionLabels.Count > 0) - //{ - // foreach (var l in detectionLabels) - // { - // var isExist = DetectDetails.Any(o => NormalizeAndClean(o.LabelName) == NormalizeAndClean(l.LabelName) && o.FinalResult == ResultState.DetectNG); - // if (isExist) - // { - // ResultLabelCategoryId = l.LabelCategoryId; - // break; - // } - // } - //} + #endregion + resultStates.Add(detectResult.ResultState); - return; - } - #endregion - resultStates.Add(detectResult.ResultState); - - product.ResultCollection.Add(detectResult); + product.ResultCollection.Add(detectResult); #endif - - //DetectStationResult temp; - ////LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.4,产品{productNumber}"); - //// 检测结果 - //if (temp != null) - //{ - // // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.5,产品{productNumber}"); - // //var totalElapsed = (temp.EndTime - temp.VisionImageSet.ImageTime).TotalMilliseconds; - // //totalTime += totalElapsed; - // resultStates.Add(temp.ResultState); - - // product.ResultCollection.Add(temp); - // // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.6,产品{productNumber}"); - //} - //else - //{ - // //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 检测失败,物料编号:{productNumber},检测项:{d}"); - //} - - // imageSet.Dispose(); + } + } catch (Exception ex) { @@ -749,15 +741,9 @@ namespace DHSoftware } } - //detectionDict.ForEach(d => - //{ + - //}); - - // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度2,产品{productNumber}"); - - - imageSet.Dispose(); + product.InferenceOne(() => { ; @@ -767,7 +753,7 @@ namespace DHSoftware }); // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}"); - + if (!product.InferenceFinished()) { @@ -786,24 +772,12 @@ namespace DHSoftware richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); - #region 6.统计产品结果 - if (product.ResultCollection.Any(u => u.ResultState != ResultState.OK)) - { - //检测结果TBD - // CurTrigger = TriggerSettings.FirstOrDefault(u => u.TriggerType == TriggerType.B_NG); - product.ProductResult = ResultState.B_NG; - product.ProductLabelCategory = ResultState.B_NG.GetEnumDescription(); - product.ProductLabel = ResultState.B_NG.GetEnumDescription(); - - - } - else - { - // CurTrigger = TriggerSettings.FirstOrDefault(u => u.TriggerType == TriggerType.OK); - product.ProductResult = ResultState.OK; - product.ProductLabelCategory = ResultState.OK.GetEnumDescription(); - product.ProductLabel = ResultState.OK.GetEnumDescription(); - } + #region 6. 统计产品结果 + product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK) + ? ResultState.B_NG + : ResultState.OK; + product.ProductLabelCategory = product.ProductResult.GetEnumDescription(); + product.ProductLabel = product.ProductResult.GetEnumDescription(); #endregion #region 7.产品吹气 @@ -811,110 +785,45 @@ namespace DHSoftware - //LogAsync(DateTime.Now, LogLevel.Information, $"推理完成,产品{product.PieceNumber}获取结果"); - - // 统计产品结果 - //Task resultTask = product.SetProductResult(_totalDetectionNum, X017Config.IsTBDPriority, labelCategoryLists); - - //await resultTask.ContinueWith(t => - //{ - // try - // { - // UpdateTriggerCount(DateTime.Now, "获取结果"); - // UpdateResult(DateTime.Now, camera, product.ProductResult.GetEnumDescription()); - // UpdateResultNew(DateTime.Now, camera, "合计"); - // LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}"); - - // } - // catch (Exception ex) - // { - // LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果异常:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}," + - // $"异常信息:{ex.GetExceptionMessage}"); - - // } - - // // 吹气 - // DateTime dtNow = DateTime.Now; - // product.BlowOutTime = dtNow; - - - // var setting = X017Config.ProductBlowSettings.FirstOrDefault(s => product.ProductResult.Equals(s.ProductResult)); - - // if (setting != null) - // { - // uint NGNumC = 0; - // uint OKNumC = 0; - - // CMCDLL_NET.MCF_Sorting_Get_Lose_Blow_NG_Count_Net(ref NGNumC, 0); - // CMCDLL_NET.MCF_Sorting_Get_Lose_Blow_OK_Count_Net(ref OKNumC, 0); - // _mainMotion.Blow(product.PieceNumber, setting.BindBlow); - // LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}吹气{NGNumC}+ {OKNumC}"); - // //if (product.ProductResult == ResultState.OK) - // //{ - // // //OKProcessNum++; - // // OKNum++; - // //} - // } - - // //判断超时出队 - // foreach (var kvp in tmpDic) - // { - // try - // { - // ProductData dataN = kvp.Value; - // TimeSpan timeDifference = DateTime.Now - dataN.CreateTime; - // if (timeDifference.TotalMinutes >= 1) - // { - - // //出队 - // bool isremoved = tmpDic.TryRemove(kvp.Key, out _); - // if (isremoved) - // { - // LogAsync(DateTime.Now, LogLevel.Error, $"====产品{kvp.Key}超时出列成功" + - // $"产品结果:{dataN.ProductResult.GetEnumDescription()} {dataN.ProductResult}," + - // $"当前队列产品数量:{tmpDic.Count}===="); - - // try - // { - // //重新生成实例 销毁之前的实例 - // var saveData = dataN.GetProductData(); - // var productDefects = dataN.GetDetectDetailData(); - // SaveProductDataAsync(saveData, productDefects); - // dataN = null; - // } - // catch (Exception) { } - - // dataN?.Dispose(); - // } - // else - // { - // LogAsync(DateTime.Now, LogLevel.Error, $"=====产品{kvp.Key}超时出列失败" + - // $"当前队列产品数量:{tmpDic.Count}====="); - // } - // } - // } - // catch (Exception ex) - // { - // LogAsync(DateTime.Now, LogLevel.Error, $"=====产品{kvp.Key}超时出列失败" + - // $"当前队列产品数量:{tmpDic.Count}====={ex.GetExceptionMessage}"); - // } - // } - // 出列 ProductData temp = null; - int tryTimes = 5; + int tryTimes = 10; while (temp == null && tryTimes > 0) { - var isSuccess = tmpDic.Remove(productNumber, out temp); - - if (isSuccess) + if (tmpDic.TryRemove(productNumber, out temp)) { - string logStr = $"{DateTime.Now}产品{productNumber}出列成功:{isSuccess}," + - $"产品结果:{temp.ProductResult.GetEnumDescription()}," + + break; + } + + tryTimes--; + Thread.Sleep(5); + } + if (temp == null) + { + string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true,"+ $"当前队列产品数量:{tmpDic.Count}"; + this.BeginInvoke(new MethodInvoker(delegate () + { + + int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; + + richTextBox1.AppendText(logStr); + + // 设置回原来的滚动位置 + richTextBox1.SelectionStart = richTextBox1.TextLength; + richTextBox1.ScrollToCaret(); + })); + } + else + { + try + { + string logStr = $"{DateTime.Now}产品{productNumber}出列成功:true," + + $"产品结果:{temp.ProductResult.GetEnumDescription()}," + + $"当前队列产品数量:{tmpDic.Count}"; this.BeginInvoke(new MethodInvoker(delegate () { @@ -926,22 +835,12 @@ namespace DHSoftware richTextBox1.SelectionStart = richTextBox1.TextLength; richTextBox1.ScrollToCaret(); })); - } - tryTimes--; - Thread.Sleep(1); - } - if (temp == null) - { - //LogAsync(DateTime.Now, LogLevel.Assist, $"产品{productNumber}出列失败," + - // $"当前队列产品数量:{tmpDic.Count}"); - } - else - { - try - { //重新生成实例 销毁之前的实例 var saveData = temp.GetProductData(); - + using(StreamWriter sw=new StreamWriter("D://123log.txt",true,Encoding.UTF8)) + { + sw.WriteLine(logStr); + } } catch (Exception) { }