|
@@ -1,5 +1,7 @@
|
|
|
#include "OscData.h"
|
|
|
#include <QApplication>
|
|
|
+#include <QRandomGenerator>
|
|
|
+
|
|
|
#include "ThreadPool/ThreadPool.h"
|
|
|
|
|
|
|
|
@@ -20,6 +22,16 @@ OscilloscopeData::~OscilloscopeData()
|
|
|
delete[] m_buffer;
|
|
|
m_buffer = nullptr;
|
|
|
}
|
|
|
+ if(m_bufferChnA != nullptr)
|
|
|
+ {
|
|
|
+ delete[] m_bufferChnA;
|
|
|
+ m_bufferChnA = nullptr;
|
|
|
+ }
|
|
|
+ if(m_bufferChnB != nullptr)
|
|
|
+ {
|
|
|
+ delete[] m_bufferChnB;
|
|
|
+ m_bufferChnB = nullptr;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* 初始化示波器 */
|
|
@@ -58,8 +70,6 @@ bool OscilloscopeData::openOSC()
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "打开示波器失败!");
|
|
|
return false;
|
|
|
}
|
|
|
- /* 设置缓冲区大小 */
|
|
|
- m_usbInterface->setInfo(BUFFER_SIZE);
|
|
|
/* 获取缓冲区首指针 */
|
|
|
m_devBuffer = m_usbInterface->bufferWR(-1);
|
|
|
if(m_devBuffer == nullptr)
|
|
@@ -67,6 +77,15 @@ bool OscilloscopeData::openOSC()
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "获取缓冲区指针失败!");
|
|
|
return false;
|
|
|
}
|
|
|
+ /* 设置硬件触发命令,关闭外部触发,好像是有的设备需要,有的不需要 */
|
|
|
+ m_ctrlByte1 &= 0xdf;
|
|
|
+ m_ctrlByte1 |= 0x00;
|
|
|
+ m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
|
|
|
+ /* 设置触发位置在缓冲区中间 */
|
|
|
+ m_usbInterface->usbCtrlTrans(0x18, 0xff);
|
|
|
+ m_usbInterface->usbCtrlTrans(0x17, 0x7f);
|
|
|
+ /* 设置缓冲区大小 */
|
|
|
+ m_usbInterface->setInfo(BUFFER_SIZE);
|
|
|
m_isOpen = true;
|
|
|
return true;
|
|
|
}
|
|
@@ -210,11 +229,6 @@ void OscilloscopeData::setChannelARange(OscChannelRange range)
|
|
|
m_ctrlByte1 |= 0x08;
|
|
|
m_usbInterface->usbCtrlTrans(0x22, 0x00);
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- SPDLOG_LOGGER_ERROR(m_logger, "输入量程设置错误!");
|
|
|
- return;
|
|
|
- }
|
|
|
m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
|
|
|
}
|
|
|
|
|
@@ -352,6 +366,7 @@ void OscilloscopeData::setExternalTrigger(bool enable)
|
|
|
{
|
|
|
m_usbInterface->usbCtrlTrans(0xE7, 0x00);
|
|
|
m_ctrlByte1 &= 0xdf;
|
|
|
+ m_ctrlByte1 |= 0x00;
|
|
|
m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
|
|
|
}
|
|
|
}
|
|
@@ -599,11 +614,16 @@ void OscilloscopeData::threadCaptureData()
|
|
|
m_isRunCapture = true;
|
|
|
uint64_t count = 0;
|
|
|
// unsigned char* buffer = nullptr;
|
|
|
- while(m_runCapture)
|
|
|
+ // while(m_runCapture)
|
|
|
{
|
|
|
// SPDLOG_LOGGER_DEBUG(m_logger, "开始采集数据");
|
|
|
/* 开始采集数据 */
|
|
|
m_usbInterface->usbCtrlTransSimple(0x33);
|
|
|
+ /* 清空数据缓冲区 */
|
|
|
+ for(uint32_t i = 0; i < BUFFER_SIZE; i++)
|
|
|
+ {
|
|
|
+ m_buffer[i] = 0;
|
|
|
+ }
|
|
|
/* 查询数据是否采集完成(应该是填充满128KB的SRAM)
|
|
|
* 注意,这里是十进制33,不是0x33 */
|
|
|
while(m_usbInterface->usbCtrlTransSimple(0x50) != 33)
|
|
@@ -612,13 +632,13 @@ void OscilloscopeData::threadCaptureData()
|
|
|
}
|
|
|
// SPDLOG_LOGGER_DEBUG(m_logger, "硬件缓冲区已满");
|
|
|
/* 将数据从示波器的SRAM中拷贝到电脑内存中,1次传输完成,设置超时时间1ms */
|
|
|
- m_usbInterface->readBulkData(BUFFER_SIZE, 1, 1, m_devBuffer);
|
|
|
+ m_usbInterface->readBulkData(BUFFER_SIZE, 1, 100, m_devBuffer);
|
|
|
/* 等待传输完成 */
|
|
|
auto ret = m_usbInterface->eventCheck(100);
|
|
|
if(ret == 0x555)
|
|
|
{
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "数据传输超时!");
|
|
|
- continue;
|
|
|
+ // continue;
|
|
|
}
|
|
|
// SPDLOG_LOGGER_DEBUG(m_logger, "数据通过USB传输完成");
|
|
|
/* 取出数据 */
|
|
@@ -630,6 +650,7 @@ void OscilloscopeData::threadCaptureData()
|
|
|
/* 清空缓冲区 */
|
|
|
m_usbInterface->resetPipe();
|
|
|
// SPDLOG_LOGGER_DEBUG(m_logger, "count: {}", count++);
|
|
|
+
|
|
|
}
|
|
|
m_isRunCapture = false;
|
|
|
}
|
|
@@ -638,7 +659,7 @@ void OscilloscopeData::threadCaptureData()
|
|
|
void OscilloscopeData::threadProcessData()
|
|
|
{
|
|
|
SPDLOG_LOGGER_INFO(m_logger, "开始处理数据线程");
|
|
|
- while(m_runCapture)
|
|
|
+ // while(m_runCapture)
|
|
|
{
|
|
|
if(m_isCaptureData.load())
|
|
|
{
|
|
@@ -652,10 +673,247 @@ void OscilloscopeData::threadProcessData()
|
|
|
m_isCaptureData = false;
|
|
|
m_mutexCaptureData.unlock();
|
|
|
/* 处理数据 */
|
|
|
- SPDLOG_LOGGER_DEBUG(m_logger, "开始处理数据,通道A数据: {}, 通道B数据: {}", m_bufferChnA[50], m_bufferChnB[50]);
|
|
|
+ SPDLOG_LOGGER_DEBUG(m_logger, "开始处理数据,通道A数据: {}, 通道B数据: {}", m_bufferChnA[32000], m_bufferChnB[32000]);
|
|
|
}
|
|
|
+ /* 打印1000个数据 */
|
|
|
+ // for(uint32_t i = 0; i < BUFFER_SIZE/2; i++)
|
|
|
+ // {
|
|
|
+ // if((m_bufferChnA[i] == 128) && (m_bufferChnB[i] == 128))
|
|
|
+ // continue;
|
|
|
+ // SPDLOG_LOGGER_DEBUG(m_logger, "A: {}, B: {}", m_bufferChnA[i], m_bufferChnB[i]);
|
|
|
+ // }
|
|
|
+ // SPDLOG_LOGGER_DEBUG(m_logger, "输出完成");
|
|
|
+ parseEyeMapData(m_bufferChnA, BUFFER_SIZE / 2);
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief 解析数据,眼图需要的数据,从C#代码中移植过来
|
|
|
+ *
|
|
|
+ * @param buffer 数据缓冲区
|
|
|
+ * @param size 缓冲区大小,单位字节
|
|
|
+ */
|
|
|
+void OscilloscopeData::parseEyeMapData(unsigned char* buffer, unsigned int size)
|
|
|
+{
|
|
|
+ int bufferSize = size;
|
|
|
+ uint8_t* array = buffer;
|
|
|
+ int num2 = 0;
|
|
|
+ int num3 = 0;
|
|
|
+ int num4 = 0;
|
|
|
+
|
|
|
+ uint8_t vaMax = 128;
|
|
|
+ uint8_t vaMin = 128;
|
|
|
+ uint8_t tmp = 128;
|
|
|
+ num3 = bufferSize; /* 赋值,数据个数 */
|
|
|
+
|
|
|
+ /* 数据预处理,找出最大值和最小值 */
|
|
|
+ for (int i = 0; i < bufferSize; i++)
|
|
|
+ {
|
|
|
+ /* 取出这组数据的最大值和最小值 */
|
|
|
+ tmp = array[i];
|
|
|
+ if (tmp < vaMin)
|
|
|
+ {
|
|
|
+ vaMin = tmp;
|
|
|
+ }
|
|
|
+ if (tmp > vaMax)
|
|
|
+ {
|
|
|
+ vaMax = tmp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 取绝对值,小于15丢弃,应该是丢弃幅度小于15的数据 */
|
|
|
+ int numAmp = std::abs(vaMax - vaMin);
|
|
|
+ if (numAmp <= 15)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ /* 计算最大值和最小值的中间数 */
|
|
|
+ uint8_t vaMid = (vaMax + vaMin) / 2;
|
|
|
+
|
|
|
+ /* 根据全局设置,进行缩放和插值,num7,缩放系数,可能是 1.0 * 100.0 / 100 */
|
|
|
+ // double num7 = globleVariables.g_GlobSetting_struc.g_dataNumPerPixar * globleVariables.g_GlobSetting_struc.g_Timescale / 100.0;
|
|
|
+ double num7 = 1.0 * 100.0 / 100; /* 这一行不知道是什么值,暂时用这个代替 */
|
|
|
+ /* num8屏幕像素数目? */
|
|
|
+ // long num8 = (long)(num7 * (double)globleVariables.g_Screen_PixarPts);
|
|
|
+ long num8 = 1600; /* 这一行不知道是什么值,暂时用这个代替 */
|
|
|
+ if (num8 % 2 != 0L)
|
|
|
+ {
|
|
|
+ num8++;
|
|
|
+ }
|
|
|
+ /* num9,四分之一的像素数目? */
|
|
|
+ int num9 = 0;
|
|
|
+ num9 = (int)((double)num8 * 0.25);
|
|
|
+ // List<pEyeDataT> list = new List<pEyeDataT>();
|
|
|
+ std::vector<EyeDataT> vecData;
|
|
|
+ int numMulti = 0; /* 倍率,可能是1可能是30 */
|
|
|
+ if (num7 >= 1.0)
|
|
|
+ {
|
|
|
+ /* 将数据放入到list中,带有bool标志位 */
|
|
|
+ for (int i = 0; i < bufferSize; i++)
|
|
|
+ {
|
|
|
+ vecData.push_back(EyeDataT(true, array[i]));
|
|
|
+ }
|
|
|
+ numMulti = 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // /* 缩放系数小于1.0,下面会进行插值 */
|
|
|
+ // num3 = bufferSize - 1;
|
|
|
+ // float num11 = 0.0;
|
|
|
+ // // Random random = new Random();
|
|
|
+ // QRandomGenerator* random = QRandomGenerator::global();
|
|
|
+ // bool flag2 = false;
|
|
|
+ // /* */
|
|
|
+ // for (num2 = 0; num2 < num3; num2++)
|
|
|
+ // {
|
|
|
+ // b2 = array[num2]; /* 偶数位 */
|
|
|
+ // b3 = array[num2 + 1]; /* 奇数位 */
|
|
|
+ // /* 在b2和b3之间添加30个插值 */
|
|
|
+ // num11 = (float)(b3 - b2) / 30.f; /* 将幅值分成30份 */
|
|
|
+ // vecData.push_back(EyeDataT(true, b2));
|
|
|
+ // num5 = 30;
|
|
|
+ // for (num4 = 0; num4 < num5; num4++)
|
|
|
+ // {
|
|
|
+ // b = (byte)(Math.Round(num11 * (float)num4, MidpointRounding.AwayFromZero) + (double)(int)b2);
|
|
|
+ // flag2 = ((1 == random.Next(1)) ? true : false);
|
|
|
+ // list.Add(new pEyeDataT(flag2, b));
|
|
|
+ // }
|
|
|
+ // list.Add(new pEyeDataT(_bIsTure: true, b3));
|
|
|
+ // }
|
|
|
+ // numMulti = 30;
|
|
|
+ }
|
|
|
+ if (vecData.size() <= 0)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ /* 屏幕的像素数目的1/4 * (1或30)? */
|
|
|
+ num9 *= numMulti; /* 这里的num9可能是400 */
|
|
|
+ long num12 = num8 * numMulti; /* num12可能是1600 */
|
|
|
+ // List<List<pEyeDataT>> list2 = new List<List<pEyeDataT>>();
|
|
|
+ std::vector<std::vector<EyeDataT>> list2;
|
|
|
+ // List<int> listSub = new List<int>();
|
|
|
+ /* 存储下标 */
|
|
|
+ std::vector<int> listSub;
|
|
|
+ num3 = vecData.size() - num9;
|
|
|
+ bool flag3 = true;
|
|
|
+ /* 找到数组中的上升沿和下降沿,并记录其坐标 */
|
|
|
+ uint8_t vaPre = 0;
|
|
|
+ uint8_t va = 0;
|
|
|
+ uint8_t vaNext = 0;
|
|
|
+ for (int i = 10; i < num3; i++)
|
|
|
+ {
|
|
|
+ /* 取出相邻的三个值 */
|
|
|
+ vaPre = vecData[i - 1].value;
|
|
|
+ va = vecData[i].value;
|
|
|
+ vaNext = vecData[i + 1].value;
|
|
|
+ if (flag3)
|
|
|
+ {
|
|
|
+ /* 上升沿,b6 = b7,就是中间值 */
|
|
|
+ if (vaPre <= vaMid && vaNext > vaMid)
|
|
|
+ {
|
|
|
+ listSub.push_back(i); /* 记录下标 */
|
|
|
+ flag3 = !flag3; /* 不再检测上升沿,检测下降沿 */
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* 下降沿 */
|
|
|
+ else if (vaPre >= vaMid && vaNext < vaMid)
|
|
|
+ {
|
|
|
+ listSub.push_back(num2);
|
|
|
+ flag3 = !flag3;
|
|
|
+ }
|
|
|
+ /* 采集到600个上升沿和下降沿 */
|
|
|
+ if (listSub.size() >= 600)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (listSub.size() <= 0)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ /* */
|
|
|
+ int num13 = 0;
|
|
|
+ int num14 = 0;
|
|
|
+ int num15 = 0;
|
|
|
+ int num16 = 0;
|
|
|
+ int num17 = 0;
|
|
|
+ num3 = listSub.size(); /* 下标的个数 */
|
|
|
+ num16 = (int)(num12 / 3);
|
|
|
+ /* */
|
|
|
+ int num5 = 0;
|
|
|
+ for (int i = 0; i < num3; i++)
|
|
|
+ {
|
|
|
+ std::vector<EyeDataT> vecDataTmp;
|
|
|
+ for (num4 = 0; num4 < num12; num4++)
|
|
|
+ {
|
|
|
+ vecDataTmp.push_back(EyeDataT(false, 0));
|
|
|
+ }
|
|
|
+ num5 = listSub[i];
|
|
|
+ num13 = num5 - num16;
|
|
|
+ num14 = num13;
|
|
|
+ if (num14 <= 0)
|
|
|
+ {
|
|
|
+ num14 = 0;
|
|
|
+ }
|
|
|
+ num15 = num5 + num16 * 2;
|
|
|
+ if (num15 >= vecData.size())
|
|
|
+ {
|
|
|
+ num15 = vecData.size() - 1;
|
|
|
+ }
|
|
|
+ num17 = 0;
|
|
|
+ if (num13 < 0)
|
|
|
+ {
|
|
|
+ num17 = std::abs(num13);
|
|
|
+ }
|
|
|
+ if (num13 > 0)
|
|
|
+ {
|
|
|
+ num17 = -num13;
|
|
|
+ }
|
|
|
+ for (num4 = num14; num4 < num15; num4++)
|
|
|
+ {
|
|
|
+ vecDataTmp[num17 + num4].isEyeData = vecData[num4].isEyeData;
|
|
|
+ vecDataTmp[num17 + num4].value = vecData[num4].value;
|
|
|
+ }
|
|
|
+ list2.push_back(vecDataTmp);
|
|
|
+ }
|
|
|
+ listSub.clear();
|
|
|
+ vecData.clear();
|
|
|
+ if (list2.size() <= 0)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int num18 = 0;
|
|
|
+ int num19 = 0;
|
|
|
+ float num20 = 0.0;
|
|
|
+ for (int i = 0; i < list2.size(); i++)
|
|
|
+ {
|
|
|
+ std::vector<EyeDataT> list5 = list2[i];
|
|
|
+ num3 = list5.size();
|
|
|
+ num20 = num3;
|
|
|
+ num20 /= 1000.f;
|
|
|
+ g_eyeDataMatrix.mutexEyeData.lock();
|
|
|
+ for (num4 = 0; num4 < num3; num4++)
|
|
|
+ {
|
|
|
+ if (list5[num4].isEyeData)
|
|
|
+ {
|
|
|
+ num5 = list5[num4].value;
|
|
|
+ num19 = num5;
|
|
|
+ num18 = (int)((float)num4 / num20);
|
|
|
+ /* 将数据添加到眼图矩阵中 */
|
|
|
+ // globleVariables.g_IeyeDataMatrix.eyeWeighted(num18, num19);
|
|
|
+ g_eyeDataMatrix.addData(num18, num19);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ g_eyeDataMatrix.mutexEyeData.unlock();
|
|
|
+ }
|
|
|
+ // globleVariables.g_IeyeDataMatrix.eyeStatisticalWeight();
|
|
|
+ g_eyeDataMatrix.eyeStatisticalWeight();
|
|
|
+ // globleVariables.g_IeyeDataMatrix.eyeLessenTheBurden();
|
|
|
+ g_eyeDataMatrix.eyeLessenTheBurden();
|
|
|
+ list2.clear();
|
|
|
+ // pEyeData[,] eyedata = globleVariables.g_IeyeDataMatrix.eyeZoomOut();
|
|
|
+ // GraphView.m_eyedMatrux.EyeDataMatrixCopy(eyedata);
|
|
|
+}
|
|
|
+
|
|
|
|