using CommonLib.LOG; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.IO; using System.Diagnostics; namespace CommonLib.DAQ { public class VK70xNMC : INotifyPropertyChanged { // 定义常量 public const int MAX_CH_NUM = 4; // 通道数 //采集卡 // public const int DATA_COUNT_PERCH = 32000; // 每通道采样点数 public const int DATA_COUNT_PERCH = 32000; // 每通道采样点数 public const int SAMPLING_RATE = 32000; // 每通道采样率为128KS/s public static readonly int TCP_PORT = 8234; public int DataFail { get; private set; } = 0; //连续多少次接受不了数序,重启连接 /// /// 输出电压事件 /// //public EventHandler EventVoltage; /// /// 输出重连事件 /// //public EventHandler EventReconnectAll; public string HostName; public int CardNO; private static int AllConnectCardCount = 0; //卡的连接索引号 private int VK70xCardIndex = -1; protected static int AllCardCount; protected Thread ThreadRead = null; private bool m_Enable; EventHandler EventError = null; protected ManualResetEvent EventKill = new ManualResetEvent(false); protected double[,] readData = null; #region .ctor public VK70xNMC() { CardNO = AllCardCount; AllCardCount++; } #endregion public bool Enable { get { return m_Enable; } set { Boolean bPreEn = m_Enable; if (bPreEn != value) { if (value) { m_Enable = InitDevice(); } else { CloseDevice(); m_Enable = value; } if (bPreEn != m_Enable) OnPropertyChanged(); } } } private void DoEventError(int errCode, string ErrorInfo) { ErrInfo info = new ErrInfo(errCode, ErrorInfo); EventError?.Invoke(this, info); } /// /// 断开连接 /// private void CloseDevice() { int err = -1; //杀死线程 try { if (ThreadRead != null) { while (ThreadRead.IsAlive) { EventKill.Set(); Thread.Sleep(10); } } } catch (Exception ex) { string Info = $"{HostName} {ex.Message} \n{ex.StackTrace}"; LogStorage.Logs.Add(LogLevel.Error, Info); DoEventError(err, Info); } finally { } } private bool InitDevice() { string Info = string.Empty; bool bResult = true; ThreadRead = new Thread(TaskRead); ThreadRead.IsBackground = true; ThreadRead.Start(); string Info1 = $"{HostName}初始化完成"; LogStorage.Logs.Add(LogLevel.Trace, Info1); return bResult; } public virtual void DoEventVoltage() { } public virtual void DoReConnectAll() { //EventReconnectAll?.Invoke(this, new EventArgs()); } protected static int GetCardIndex(string IPaddr) { int cardIndex = -1; int res = VK70xNMC_Wrapper.Server_Get_ConnectedClientNumbers(ref AllConnectCardCount); if (res >= 0) { int handles = 0; for (int i = 0; i < AllConnectCardCount; i++) { int len = 128; Byte[] HostName = new Byte[len]; for (int j = 0; j < len; j++) { HostName[j] = 0; } int result = VK70xNMC_Wrapper.Server_Get_ConnectedClientHandle(i, ref handles, HostName); if (result >= 0) { string Name = Encoding.Default.GetString(HostName).Split(new string[] { "\0" }, StringSplitOptions.RemoveEmptyEntries)[0]; if (Name == IPaddr) { cardIndex = i; break; } } } } return cardIndex; } protected static int ScanListDevice(ref string[] hostNames, ref int devTotalCount) { devTotalCount = 0; int res = VK70xNMC_Wrapper.Server_TCPOpen(TCP_PORT); if (res < 0) return res; Thread.Sleep(15000); res = VK70xNMC_Wrapper.Server_Get_ConnectedClientNumbers(ref devTotalCount); if (res < 0) return res; int[] handles = new int[devTotalCount]; for (int i = 0; i < devTotalCount; i++) { int len = 128; Byte[] HostName = new Byte[len]; for (int j = 0; j < len; j++) { HostName[j] = 0; } VK70xNMC_Wrapper.Server_Get_ConnectedClientHandle(i, ref handles[i], HostName); string Name = Encoding.Default.GetString(HostName).Split(new string[] { "\0" }, StringSplitOptions.RemoveEmptyEntries)[0]; hostNames[i] = Name; } return res; } /// /// 关闭监听端口 /// protected static void CloseAllDevices( ) { VK70xNMC_Wrapper.Server_TCPClose(TCP_PORT); } protected void PostData(List ListData, int dpCnt ) { int i = 0; Stopwatch watch = new Stopwatch(); watch.Start(); float t = watch.ElapsedMilliseconds; const double gain02f = 0.2f; const double gain100f = 100.0f; Double[] DataArray = ListData.ToArray(); Double[] readData1 = new Double[dpCnt]; Array.Copy(DataArray, readData1, dpCnt); //一维数组转二维 for (i = 0; i < dpCnt; i += VK70xNMC.MAX_CH_NUM) { readData[i % VK70xNMC.MAX_CH_NUM, i / VK70xNMC.MAX_CH_NUM] = readData1[i] / gain02f; readData[i % VK70xNMC.MAX_CH_NUM + 1, i / VK70xNMC.MAX_CH_NUM] = readData1[i + 1] / gain100f; readData[i % VK70xNMC.MAX_CH_NUM + 2, i / VK70xNMC.MAX_CH_NUM] = readData1[i + 2] / gain02f; readData[i % VK70xNMC.MAX_CH_NUM + 3, i / VK70xNMC.MAX_CH_NUM] = readData1[i + 3] / gain100f; /* readData[i % VK70xNMC.MAX_CH_NUM, i / VK70xNMC.MAX_CH_NUM] = readData1[i] ; readData[i % VK70xNMC.MAX_CH_NUM + 1, i / VK70xNMC.MAX_CH_NUM] = readData1[i + 1] ; readData[i % VK70xNMC.MAX_CH_NUM + 2, i / VK70xNMC.MAX_CH_NUM] = readData1[i + 2] ; readData[i % VK70xNMC.MAX_CH_NUM + 3, i / VK70xNMC.MAX_CH_NUM] = readData1[i + 3] ; */ } //savevoltage(readData); DoEventVoltage(); } private void TaskRead() { int emptyCnt = 0; int Res = 0; int dpCnt = 0; try { Thread thread = Thread.CurrentThread; thread.Name = $"{HostName} Capture Thread"; EventKill.Reset(); dpCnt = VK70xNMC.MAX_CH_NUM * VK70xNMC.DATA_COUNT_PERCH; //需要传送的数量 List ListData = new List(dpCnt * 2); double[] rdata2 = new double[dpCnt]; int CountPerTime = 1000; readData = new double[4, dpCnt]; // 行为通道数,列为每通道采样点数 //传送到后端处理 int readcnt = 0; ; VK70xCardIndex = GetCardIndex(this.HostName); if (VK70xCardIndex < 0) return; Res = VK70xNMC_Wrapper.VK70xNMC_Set_SystemMode(VK70xCardIndex, 0, 0, 0);// power on then back to the normal mode Thread.Sleep(100); Res = VK70xNMC_Wrapper.VK70xNMC_Initialize(VK70xCardIndex, 4, 16, SAMPLING_RATE, 0, 0, 0, 0); if (VK70xCardIndex < 0) return; Thread.Sleep(100); Res = VK70xNMC_Wrapper.VK70xNMC_StartSampling(VK70xCardIndex); if (VK70xCardIndex < 0) return; while (EventKill.WaitOne(20) == false) { // int rlen = VK70xNMC_Wrapper.VK70xNMC_GetFourChannel(VK70xCardIndex, rdata2, CountPerTime); // 获取数据 if (rlen > 0) { emptyCnt = 0; //添加到list里 int subLen = rlen * 4; double[] subrdata2 = new double[subLen]; Array.Copy(rdata2, subrdata2, subLen); ListData.AddRange(subrdata2); readcnt++; if (ListData.Count >= dpCnt) { PostData(ListData, dpCnt); ListData.RemoveRange(0, dpCnt);//已经移除,所以要删除 readcnt = 0; } } else { emptyCnt++; if(emptyCnt>1000) { emptyCnt = 0; //如果超过N次 没有数据,重新连接 DoReConnectAll(); break; } } } if (VK70xCardIndex >= 0) VK70xNMC_Wrapper.VK70xNMC_StopSampling(VK70xCardIndex); } catch (Exception ex) { string Info = $" {ex.Message} \n{ex.StackTrace}"; LogStorage.Logs.Add(LogLevel.Error, Info); } finally { VK70xNMC.StopDevice(HostName); VK70xNMC.CloseDevice(HostName); LogStorage.Logs.Add(LogLevel.Trace, $"{HostName}采样线程结束"); } } private static void savevoltage(double[,] readData) { string FileName = "wav.csv"; int i0 = readData.GetLength(0); int i1 = readData.GetLength(1); FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs,Encoding.UTF8); string datahead = "index,A,B,C,D"; sw.WriteLine(datahead); for (int i = 0; i < i0; i++) { string strRow = i.ToString();// readData[i, 0]; for (int j = 0; j < i1; j++) { double v = readData[i, j]; strRow += ","+v.ToString(); } sw.WriteLine(strRow); } sw.Close(); fs.Close(); } private static void CloseDevice(string hostName) { } private static void StopDevice(string hostName) { } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; /// /// //属性更新事件 CallerMemberName 自动填写属性的名字 /// /// //[CallerMemberName] 需要 4.0以上才有 /// protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { //通过反射读取变量名,将值加入log if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion } }