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
}
}