using System; using System.Collections.Generic; using System.Drawing.Drawing2D; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Timers; using Advantech.Motion; using Automation.BDaq; using OpenCvSharp; namespace ProductionControl.Device { public class IOCard : IDisposable { private Automation.BDaq.InstantDiCtrl instantDiCtrl1; private Automation.BDaq.InstantDoCtrl instantDoCtrl; public string DeviceNum { get; private set; } /// /// 读取输入端口数量 /// public int DIPortCount { get; private set; } /// /// 写入输出端口数量 /// public int DOPortCount { get; private set; } /// /// 读取到的输入值 /// public byte[] DIData { get; private set; } public byte[] DOData { get; private set; } /// /// Log输出,(0-info,1-warning 2-error) /// public Action log; public Action INEvent; public Action OUTEvent; /// /// 是否打开设备成功 /// public bool IsInit { get; private set; } = false; private System.Timers.Timer timer = new System.Timers.Timer(); public IOCard() { } public void start(string deviceNum="") { instantDiCtrl1 = new Automation.BDaq.InstantDiCtrl(); instantDoCtrl = new Automation.BDaq.InstantDoCtrl(); if (deviceNum != "") { instantDiCtrl1.SelectedDevice = new Automation.BDaq.DeviceInformation(deviceNum); instantDoCtrl.SelectedDevice = new DeviceInformation(deviceNum); } //根据加载的文件设置设备的所有配置 string cfgPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DevCfg\\IOCard_1703.xml"; if (File.Exists(cfgPath)) { var result = instantDiCtrl1.LoadProfile(cfgPath);//Loads a profile to initialize the device. var result2 = instantDoCtrl.LoadProfile(cfgPath);//Loads a profile to initialize the device. if (BioFailed(result) && BioFailed(result2)) throw new Exception("CardIO Load Config Failed With Error Code: "+ result.ToString() + "]"); } DeviceNum = instantDiCtrl1.SelectedDevice.Description; DIPortCount = instantDiCtrl1.Features.PortCount; DIData = new byte[DIPortCount]; DOPortCount = instantDoCtrl.Features.PortCount; DOData = new byte[DOPortCount]; loadDOData(); IsInit = true; timer.Elapsed += Timer_Elapsed; timer.Interval = 100; timer.Enabled = true; } public void stop() { if (!IsInit) return; IsInit = false; timer.Elapsed -= Timer_Elapsed; //instantDiCtrl1.Cleanup(); instantDiCtrl1.Dispose(); //instantDoCtrl.Cleanup(); instantDoCtrl.Dispose(); } private void loadDOData(int portIndex=-1) { for (int i = 0; i < DOPortCount; ++i) { if (i == portIndex || portIndex < 0) { byte data; var reuslt = instantDoCtrl.Read(i, out data); if (reuslt != Automation.BDaq.ErrorCode.Success) { throw new Exception("加载CardIO输出状态失败!"); } if (DOData[i] != data) { DOData[i] = data; OUTEvent?.Invoke(i, DOData[i]); } } } } public bool writeData(int startPort,byte[] data) { var reuslt = instantDoCtrl.Write(startPort, data.Length, data); //errorCode = instantDoCtrl.WriteBit(startPort, bit, dataForWriteBit); if (BioFailed(reuslt)) return false; loadDOData(data.Length == 1 ? startPort : -1); return true; } public bool writeBitState(int portIndex, int bitIndex, bool state) { //byte bit = (byte)(DOData[portIndex] & (byte)(0x01< 0 && state) return true; //if (bit == 0 && !state) return true; //byte data = DOData[portIndex]; //data &= (byte)(~(0x1 << bitIndex)); //data |= (byte)((state ? 1 : 0) << bitIndex); //var reuslt = instantDoCtrl.Write(startPort, len, data); var reuslt = instantDoCtrl.WriteBit(portIndex, bitIndex, (byte)((state ? 1 : 0) << bitIndex)); if (BioFailed(reuslt)) return false; loadDOData(portIndex); return true; } public bool getDIBitState(int portIndex, int bitIndex) { byte data = 0x01; data=(byte)(data << bitIndex); return (DIData[portIndex] & data) > 0; } public bool getDOBitState(int portIndex, int bitIndex) { byte data = 0x01; data = (byte)(data << bitIndex); return (DOData[portIndex] & data) > 0; } private void Timer_Elapsed(object sender, ElapsedEventArgs e) { if (!IsInit) return; //byte data = 0;//data is used to the API ReadBit. //int bit = 0;//bit is used to the API ReadBit. Automation.BDaq.ErrorCode result; int startPort = 0; byte[] datas = new byte[DIPortCount]; do { result = instantDiCtrl1.Read(startPort, DIPortCount, datas); //errorCode = instantDiCtrl.ReadBit(startPort, bit, out data); if (BioFailed(result)) { //throw new Exception(); continue; } for (int i = 0; i < datas.Length; i++) { if (DIData[i] != datas[i]) { DIData[i]= datas[i]; INEvent?.Invoke(i, DIData[i]); } } Thread.Sleep(100); } while (IsInit); } private static bool BioFailed(Automation.BDaq.ErrorCode err) { return err < Automation.BDaq.ErrorCode.Success && err >= Automation.BDaq.ErrorCode.ErrorHandleNotValid; } public void Dispose() { stop(); } } }