OneOscData.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259
  1. #include "OneOscData.h"
  2. #include <QApplication>
  3. #include <QRandomGenerator>
  4. #include <chrono>
  5. #include "ThreadPool/ThreadPool.h"
  6. OneOscilloscopeData::OneOscilloscopeData()
  7. {
  8. }
  9. OneOscilloscopeData::~OneOscilloscopeData()
  10. {
  11. if(m_isOpen)
  12. {
  13. closeOSC();
  14. }
  15. if(m_buffer != nullptr)
  16. {
  17. delete[] m_buffer;
  18. m_buffer = nullptr;
  19. }
  20. if(m_bufferChnA != nullptr)
  21. {
  22. delete[] m_bufferChnA;
  23. m_bufferChnA = nullptr;
  24. }
  25. if(m_bufferChnB != nullptr)
  26. {
  27. delete[] m_bufferChnB;
  28. m_bufferChnB = nullptr;
  29. }
  30. }
  31. /**
  32. * @brief 初始化示波器,传入通道A和B的通道号,1和2是主设备,其他都是从设备
  33. *
  34. * @param chA
  35. * @param chB
  36. */
  37. void OneOscilloscopeData::initOSC(int oscNum)
  38. {
  39. m_logger = spdlog::get("OscData");
  40. if(m_logger == nullptr)
  41. {
  42. SPDLOG_ERROR("获取 OscData logger 失败");
  43. return;
  44. }
  45. m_oscNum = oscNum;
  46. QString libName = QApplication::applicationDirPath();
  47. if(oscNum == 1)
  48. {
  49. libName = libName + QString("/USBInterFace.dll");
  50. }
  51. else if(oscNum == 2)
  52. {
  53. libName = libName + QString("/USBInterFace2.dll");
  54. }
  55. else if (oscNum == 3)
  56. {
  57. libName = libName + QString("/USBInterFace3.dll");
  58. }
  59. else if (oscNum == 4)
  60. {
  61. libName = libName + QString("/USBInterFace4.dll");
  62. }
  63. else
  64. {
  65. SPDLOG_LOGGER_ERROR(m_logger, "示波器编号错误!");
  66. return;
  67. }
  68. m_usbInterface = std::make_shared<USBInterface>();
  69. if(!m_usbInterface->loadLib(libName))
  70. {
  71. SPDLOG_LOGGER_ERROR(m_logger, "加载USBInterFace库失败! 路径:{}", libName.toStdString());
  72. return;
  73. }
  74. /* 分配缓冲区内存 */
  75. m_buffer = new unsigned char[BUFFER_SIZE];
  76. m_bufferChnA = new unsigned char[BUFFER_SIZE / 2];
  77. m_bufferChnB = new unsigned char[BUFFER_SIZE / 2];
  78. /* 设置默认的初始化参数 */
  79. m_oneTimeGrid = 200;
  80. }
  81. /* 打开示波器 */
  82. bool OneOscilloscopeData::openOSC()
  83. {
  84. if(m_usbInterface == nullptr)
  85. {
  86. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  87. return false;
  88. }
  89. /* 指定示波器设备型号,OSCA02是6 */
  90. m_usbInterface->specifyDevId(6);
  91. // auto ret = m_usbInterface->devOpen();
  92. auto ret = m_usbInterface->devOpenWithID(m_oscNum);
  93. if(ret != 0)
  94. {
  95. SPDLOG_LOGGER_ERROR(m_logger, "打开示波器失败!");
  96. return false;
  97. }
  98. /* 获取缓冲区首指针 */
  99. m_devBuffer = m_usbInterface->bufferWR(-1);
  100. if(m_devBuffer == nullptr)
  101. {
  102. SPDLOG_LOGGER_ERROR(m_logger, "获取缓冲区指针失败!");
  103. return false;
  104. }
  105. /* 设置硬件触发命令,关闭外部触发,好像是有的设备需要,有的不需要 */
  106. m_ctrlByte1 &= 0xdf;
  107. m_ctrlByte1 |= 0x00;
  108. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  109. /* 设置触发位置在缓冲区中间 */
  110. m_usbInterface->usbCtrlTrans(0x18, 0xff);
  111. m_usbInterface->usbCtrlTrans(0x17, 0x7f);
  112. /* 设置缓冲区大小 */
  113. m_usbInterface->setInfo(BUFFER_SIZE);
  114. /* 获取零电压值 */
  115. getZeroVoltage();
  116. /* 获取电压校准系数 */
  117. getVoltageCalibration();
  118. /* 获取内存指针 */
  119. if(!getEyeDataMatrixPtr())
  120. {
  121. SPDLOG_LOGGER_ERROR(m_logger, "获取眼图数据矩阵指针失败!");
  122. return false;
  123. }
  124. m_isOpen = true;
  125. return true;
  126. }
  127. /* 关闭示波器 */
  128. void OneOscilloscopeData::closeOSC()
  129. {
  130. if(m_runCapture)
  131. {
  132. stopCapture();
  133. }
  134. if(m_usbInterface != nullptr)
  135. {
  136. m_usbInterface->devClose();
  137. }
  138. m_isOpen = false;
  139. SPDLOG_INFO("示波器已关闭");
  140. }
  141. /* 开始采集数据 */
  142. bool OneOscilloscopeData::startCapture()
  143. {
  144. if(m_buffer == nullptr)
  145. {
  146. SPDLOG_LOGGER_ERROR(m_logger, "缓冲区指针为空!");
  147. return false;
  148. }
  149. /* 判断示波器是否已经打开成功 */
  150. if(!m_isOpen)
  151. {
  152. SPDLOG_LOGGER_ERROR(m_logger, "示波器{}未打开!", m_oscNum);
  153. return false;
  154. }
  155. /* 启动子线程 */
  156. m_runCapture = true;
  157. CPPTP.add_task(&OneOscilloscopeData::threadCaptureData, this);
  158. CPPTP.add_task(&OneOscilloscopeData::threadSeparateData, this);
  159. CPPTP.add_task(&OneOscilloscopeData::threadProcessData_A, this);
  160. CPPTP.add_task(&OneOscilloscopeData::threadProcessData_B, this);
  161. return true;
  162. }
  163. /* 停止采集数据 */
  164. void OneOscilloscopeData::stopCapture()
  165. {
  166. if(!m_runCapture)
  167. {
  168. return;
  169. }
  170. m_runCapture = false;
  171. while (m_isRunCapture)
  172. {
  173. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  174. }
  175. SPDLOG_LOGGER_INFO(m_logger, "示波器{}已停止采集数据", m_oscNum);
  176. }
  177. /* 设置示波器的采样率 */
  178. void OneOscilloscopeData::setSampleRate(OscSampleRate rate)
  179. {
  180. if(m_usbInterface == nullptr)
  181. {
  182. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  183. return;
  184. }
  185. m_ctrlByte0 &= 0xf0;
  186. if(rate == OscSampleRate::SR_49KHZ)
  187. {
  188. m_ctrlByte0 |= 0x0e;
  189. m_SampleIntervalTime.store(20408.16);
  190. }
  191. else if(rate == OscSampleRate::SR_96KHZ)
  192. {
  193. m_ctrlByte0 |= 0x04;
  194. m_SampleIntervalTime.store(10416.67);
  195. }
  196. else if(rate == OscSampleRate::SR_781KHZ)
  197. {
  198. m_ctrlByte0 |= 0x0c;
  199. m_SampleIntervalTime.store(1280.0);
  200. }
  201. else if(rate == OscSampleRate::SR_12_5MHZ)
  202. {
  203. m_ctrlByte0 |= 0x08;
  204. m_SampleIntervalTime.store(80.0);
  205. }
  206. else if(rate == OscSampleRate::SR_100MHZ)
  207. {
  208. m_ctrlByte0 |= 0x00;
  209. m_SampleIntervalTime.store(10);
  210. }
  211. else
  212. {
  213. SPDLOG_LOGGER_ERROR(m_logger, "采样率设置错误!");
  214. return;
  215. }
  216. m_usbInterface->usbCtrlTrans(0x94, m_ctrlByte0);
  217. }
  218. /**
  219. * @brief 将示波器两个通道合并为一个通道
  220. * 将AB两个通道的资源全部给A,B通道失效,A通道的采样率和带宽翻倍
  221. * @param merge 是否合并
  222. */
  223. void OneOscilloscopeData::setChannelMerge(bool merge)
  224. {
  225. if(m_usbInterface == nullptr)
  226. {
  227. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  228. return;
  229. }
  230. if(merge)
  231. {
  232. m_ctrlByte1 |= 0x80;
  233. }else {
  234. m_ctrlByte1 &= 0x7f;
  235. }
  236. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  237. }
  238. /**
  239. * @brief 设置通道A输入量程,这个函数需要在打开示波器之后调用
  240. *
  241. * @param range
  242. */
  243. void OneOscilloscopeData::setChannelARange(OscVoltageRange range)
  244. {
  245. if(m_usbInterface == nullptr)
  246. {
  247. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  248. return;
  249. }
  250. m_ctrlByte1 &= 0xf7;
  251. if(range == OscVoltageRange::CR_100MV)
  252. {
  253. m_usbInterface->usbCtrlTrans(0x22, 0x06);
  254. }
  255. else if(range == OscVoltageRange::CR_250MV)
  256. {
  257. m_usbInterface->usbCtrlTrans(0x22, 0x04);
  258. }
  259. else if(range == OscVoltageRange::CR_500MV)
  260. {
  261. m_usbInterface->usbCtrlTrans(0x22, 0x02);
  262. }
  263. else if(range == OscVoltageRange::CR_1V)
  264. {
  265. m_ctrlByte1 |= 0x08;
  266. m_usbInterface->usbCtrlTrans(0x22, 0x06);
  267. }
  268. else if(range == OscVoltageRange::CR_2V5)
  269. {
  270. m_ctrlByte1 |= 0x08;
  271. m_usbInterface->usbCtrlTrans(0x22, 0x04);
  272. }
  273. else if(range == OscVoltageRange::CR_5V)
  274. {
  275. m_ctrlByte1 |= 0x08;
  276. m_usbInterface->usbCtrlTrans(0x22, 0x02);
  277. }
  278. else if(range == OscVoltageRange::CR_8V)
  279. {
  280. m_ctrlByte1 |= 0x08;
  281. m_usbInterface->usbCtrlTrans(0x22, 0x00);
  282. }
  283. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  284. setZeroVoltageAndCalibration(OscChannel::CH_A, range);
  285. }
  286. /**
  287. * @brief 设置通道B输入量程
  288. *
  289. * @param range
  290. */
  291. void OneOscilloscopeData::setChannelBRange(OscVoltageRange range)
  292. {
  293. if(m_usbInterface == nullptr)
  294. {
  295. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  296. return;
  297. }
  298. m_ctrlByte1 &= 0xf9;
  299. if(range == OscVoltageRange::CR_100MV)
  300. {
  301. m_ctrlByte1 |= 0x06;
  302. m_usbInterface->usbCtrlTrans(0x23, 0x40);
  303. }
  304. else if(range == OscVoltageRange::CR_250MV)
  305. {
  306. m_ctrlByte1 |= 0x04;
  307. m_usbInterface->usbCtrlTrans(0x23, 0x40);
  308. }
  309. else if(range == OscVoltageRange::CR_500MV)
  310. {
  311. m_ctrlByte1 |= 0x02;
  312. m_usbInterface->usbCtrlTrans(0x23, 0x40);
  313. }
  314. else if(range == OscVoltageRange::CR_1V)
  315. {
  316. m_ctrlByte1 |= 0x06;
  317. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  318. }
  319. else if(range == OscVoltageRange::CR_2V5)
  320. {
  321. m_ctrlByte1 |= 0x04;
  322. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  323. }
  324. else if(range == OscVoltageRange::CR_5V)
  325. {
  326. m_ctrlByte1 |= 0x02;
  327. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  328. }
  329. else if(range == OscVoltageRange::CR_8V)
  330. {
  331. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  332. }
  333. else
  334. {
  335. SPDLOG_LOGGER_ERROR(m_logger, "输入量程设置错误!");
  336. return;
  337. }
  338. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  339. setZeroVoltageAndCalibration(OscChannel::CH_B, range);
  340. }
  341. /**
  342. * @brief 设置通道耦合方式
  343. *
  344. * @param channel 通道
  345. * @param coupling 耦合方式,DC或者AC
  346. */
  347. void OneOscilloscopeData::setChannelCoupling(OscChannel channel, OscChannelCoupling coupling)
  348. {
  349. if(m_usbInterface == nullptr)
  350. {
  351. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  352. return;
  353. }
  354. if(channel == OscChannel::CH_A)
  355. {
  356. m_ctrlByte0 &= 0xef;
  357. if(coupling == OscChannelCoupling::DC) {
  358. m_ctrlByte0 |= 0x10;
  359. }
  360. else if(coupling == OscChannelCoupling::AC) {}
  361. else {
  362. SPDLOG_LOGGER_ERROR(m_logger, "耦合方式设置错误!");
  363. return;
  364. }
  365. m_usbInterface->usbCtrlTrans(0x94, m_ctrlByte0);
  366. }
  367. else if(channel == OscChannel::CH_B)
  368. {
  369. m_ctrlByte1 &= 0xef;
  370. if(coupling == OscChannelCoupling::AC) {
  371. m_ctrlByte1 |= 0x10;
  372. }
  373. else if(coupling == OscChannelCoupling::DC) {}
  374. else {
  375. SPDLOG_LOGGER_ERROR(m_logger, "耦合方式设置错误!");
  376. return;
  377. }
  378. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  379. }
  380. else
  381. {
  382. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  383. return;
  384. }
  385. }
  386. /* 开启或关闭通道A触发 */
  387. void OneOscilloscopeData::setChannelATrigger(bool enable)
  388. {
  389. if(m_usbInterface == nullptr)
  390. {
  391. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  392. return;
  393. }
  394. if(enable)
  395. {
  396. m_usbInterface->usbCtrlTrans(0xE7, 0x01);
  397. }
  398. else
  399. {
  400. m_usbInterface->usbCtrlTrans(0xE7, 0x00);
  401. }
  402. }
  403. /* 开启外触发 */
  404. void OneOscilloscopeData::setExternalTrigger(bool enable)
  405. {
  406. if(m_usbInterface == nullptr)
  407. {
  408. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  409. return;
  410. }
  411. if(enable)
  412. {
  413. m_usbInterface->usbCtrlTrans(0xE7, 0x01);
  414. m_ctrlByte1 &= 0xdf;
  415. m_ctrlByte1 |= 0x20;
  416. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  417. }
  418. else
  419. {
  420. m_usbInterface->usbCtrlTrans(0xE7, 0x00);
  421. m_ctrlByte1 &= 0xdf;
  422. m_ctrlByte1 |= 0x00;
  423. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  424. }
  425. }
  426. /* 设置触发方式 */
  427. void OneOscilloscopeData::setTriggerMode(OscTriggerMode mode)
  428. {
  429. if(m_usbInterface == nullptr)
  430. {
  431. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  432. return;
  433. }
  434. if(mode == OscTriggerMode::TM_RISE)
  435. {
  436. m_usbInterface->usbCtrlTrans(0xC5, 0x00);
  437. }
  438. else if (mode == OscTriggerMode::TM_DOWN)
  439. {
  440. m_usbInterface->usbCtrlTrans(0xC5, 0x01);
  441. }
  442. else if (mode == OscTriggerMode::TM_DOUBLE)
  443. {
  444. m_usbInterface->usbCtrlTrans(0xC5, 0x03);
  445. }
  446. }
  447. /**
  448. * @brief 设置触发电平
  449. *
  450. * @param level 0~255的值
  451. */
  452. void OneOscilloscopeData::setTriggerLevel(unsigned char level)
  453. {
  454. if(m_usbInterface == nullptr)
  455. {
  456. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  457. return;
  458. }
  459. m_usbInterface->usbCtrlTrans(0x16, level);
  460. }
  461. /* 设置触发灵敏度 */
  462. void OneOscilloscopeData::setTriggerSensitivity(OscTriggerSensitivity sensitivity)
  463. {
  464. if(m_usbInterface == nullptr)
  465. {
  466. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  467. return;
  468. }
  469. if(sensitivity == OscTriggerSensitivity::TS_LOW)
  470. {
  471. m_usbInterface->usbCtrlTrans(0x2b, 0);
  472. }
  473. else if(sensitivity == OscTriggerSensitivity::TS_HIGH)
  474. {
  475. m_usbInterface->usbCtrlTrans(0x2b, 1);
  476. }
  477. else
  478. {
  479. SPDLOG_LOGGER_ERROR(m_logger, "触发灵敏度设置错误!");
  480. return;
  481. }
  482. }
  483. /* 设置触发在缓冲区的哪个位置 */
  484. void OneOscilloscopeData::setTriggerPosition(unsigned char lowByte, unsigned char highByte)
  485. {
  486. if(m_usbInterface == nullptr)
  487. {
  488. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  489. return;
  490. }
  491. m_usbInterface->usbCtrlTrans(0x18, lowByte);
  492. m_usbInterface->usbCtrlTrans(0x17, highByte);
  493. }
  494. /* 设置时间刻度 */
  495. void OneOscilloscopeData::setTimeGridValue(OscTimeGridValue value)
  496. {
  497. m_oneTimeGrid = static_cast<int>(value);
  498. /* 修改时间刻度理论上需要清空已有的缓存 */
  499. }
  500. /* 获取示波器不同档位下的零电压值 */
  501. void OneOscilloscopeData::getZeroVoltage()
  502. {
  503. if(m_usbInterface == nullptr)
  504. {
  505. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  506. return;
  507. }
  508. /* 获取通道A零电压值 */
  509. unsigned char zeroVoltage = 0;
  510. /* 2V档位,正负8V量程 */
  511. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x82);
  512. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_8V, zeroVoltage);
  513. /* 1V档位,正负5V量程 */
  514. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x01);
  515. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_5V, zeroVoltage);
  516. /* 500mV档位,正负2.5V量程 */
  517. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x0e);
  518. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_2V5, zeroVoltage);
  519. /* 200mV档位,正负1V量程 */
  520. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x14);
  521. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_1V, zeroVoltage);
  522. /* 100mV档位,正负500mV量程 */
  523. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x12);
  524. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_500MV, zeroVoltage);
  525. /* 50mV档位,正负250mV量程 */
  526. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x10);
  527. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_250MV, zeroVoltage);
  528. /* 20mV档位,正负100mV量程 */
  529. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0xa0);
  530. m_mapChAZeroVoltage.insert(OscVoltageRange::CR_100MV, zeroVoltage);
  531. /* 获取通道B零电压值 */
  532. /* 2V档位,正负8V量程 */
  533. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x72);
  534. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_8V, zeroVoltage);
  535. /* 1V档位,正负5V量程 */
  536. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x02);
  537. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_5V, zeroVoltage);
  538. /* 500mV档位,正负2.5V量程 */
  539. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x0f);
  540. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_2V5, zeroVoltage);
  541. /* 200mV档位,正负1V量程 */
  542. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x15);
  543. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_1V, zeroVoltage);
  544. /* 100mV档位,正负500mV量程 */
  545. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x13);
  546. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_500MV, zeroVoltage);
  547. /* 50mV档位,正负250mV量程 */
  548. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x11);
  549. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_250MV, zeroVoltage);
  550. /* 20mV档位,正负100mV量程 */
  551. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0xa1);
  552. m_mapChBZeroVoltage.insert(OscVoltageRange::CR_100MV, zeroVoltage);
  553. }
  554. /* 打印出零电压值 */
  555. void OneOscilloscopeData::printZeroVoltage(OscChannel channel)
  556. {
  557. if(channel == OscChannel::CH_A)
  558. {
  559. for(auto it = m_mapChAZeroVoltage.begin(); it != m_mapChAZeroVoltage.end(); ++it)
  560. {
  561. SPDLOG_LOGGER_INFO(m_logger, "通道A {} 量程下的零电压值为: {}", static_cast<int>(it.key()), it.value());
  562. }
  563. }
  564. else if(channel == OscChannel::CH_B)
  565. {
  566. for(auto it = m_mapChBZeroVoltage.begin(); it != m_mapChBZeroVoltage.end(); ++it)
  567. {
  568. SPDLOG_LOGGER_INFO(m_logger, "通道B {} 量程下的零电压值为: {}", static_cast<int>(it.key()), it.value());
  569. }
  570. }
  571. else
  572. {
  573. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  574. return;
  575. }
  576. }
  577. /* 获取不同档位下电压校准系数 */
  578. void OneOscilloscopeData::getVoltageCalibration()
  579. {
  580. if (m_usbInterface == nullptr)
  581. {
  582. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  583. return;
  584. }
  585. /* 获取通道A电压校准系数 */
  586. unsigned char voltageCalibration = 0;
  587. /* 2V档位,正负8V量程 */
  588. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0xc2);
  589. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_8V, voltageCalibration);
  590. /* 1V档位,正负5V量程 */
  591. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x03);
  592. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_5V, voltageCalibration);
  593. /* 500mV档位,正负2.5V量程 */
  594. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x08);
  595. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_2V5, voltageCalibration);
  596. /* 200mV档位,正负1V量程 */
  597. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x06);
  598. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_1V, voltageCalibration);
  599. /* 100mV档位,正负500mV量程 */
  600. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x09);
  601. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_500MV, voltageCalibration);
  602. /* 50mV档位,正负250mV量程 */
  603. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0a);
  604. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_250MV, voltageCalibration);
  605. /* 20mV档位,正负100mV量程 */
  606. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x2a);
  607. m_mapChAVoltageAmplitudeRatio.insert(OscVoltageRange::CR_100MV, voltageCalibration);
  608. /* 获取通道B电压校准系数 */
  609. /* 2V档位,正负8V量程 */
  610. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0xd2);
  611. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_8V, voltageCalibration);
  612. /* 1V档位,正负5V量程 */
  613. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x04);
  614. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_5V, voltageCalibration);
  615. /* 500mV档位,正负2.5V量程 */
  616. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0b);
  617. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_2V5, voltageCalibration);
  618. /* 200mV档位,正负1V量程 */
  619. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x07);
  620. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_1V, voltageCalibration);
  621. /* 100mV档位,正负500mV量程 */
  622. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0c);
  623. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_500MV, voltageCalibration);
  624. /* 50mV档位,正负250mV量程 */
  625. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0d);
  626. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_250MV, voltageCalibration);
  627. /* 20mV档位,正负100mV量程 */
  628. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x2d);
  629. m_mapChBVoltageAmplitudeRatio.insert(OscVoltageRange::CR_100MV, voltageCalibration);
  630. }
  631. /* 打印出电压校准系数 */
  632. void OneOscilloscopeData::printVoltageCalibration(OscChannel channel)
  633. {
  634. if(channel == OscChannel::CH_A)
  635. {
  636. for(auto it = m_mapChAVoltageAmplitudeRatio.begin(); it != m_mapChAVoltageAmplitudeRatio.end(); ++it)
  637. {
  638. SPDLOG_LOGGER_INFO(m_logger, "通道A {} 量程下的电压校准系数为: {}", static_cast<int>(it.key()), it.value());
  639. }
  640. }
  641. else if(channel == OscChannel::CH_B)
  642. {
  643. for(auto it = m_mapChBVoltageAmplitudeRatio.begin(); it != m_mapChBVoltageAmplitudeRatio.end(); ++it)
  644. {
  645. SPDLOG_LOGGER_INFO(m_logger, "通道B {} 量程下的电压校准系数为: {}", static_cast<int>(it.key()), it.value());
  646. }
  647. }
  648. else
  649. {
  650. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  651. return;
  652. }
  653. }
  654. /**
  655. * @brief 采集数据,这个是子线程
  656. *
  657. */
  658. void OneOscilloscopeData::threadCaptureData()
  659. {
  660. SPDLOG_LOGGER_INFO(m_logger, "开始采集数据线程");
  661. m_isRunCapture = true;
  662. /* 这个记录等待数据的时间间隔,超过一定时间就认为设备离线了 */
  663. std::chrono::steady_clock::time_point timePoint = std::chrono::steady_clock::now();
  664. // unsigned char* buffer = nullptr;
  665. while(m_runCapture)
  666. {
  667. // SPDLOG_LOGGER_DEBUG(m_logger, "开始采集数据");
  668. /* 开始采集数据 */
  669. m_usbInterface->usbCtrlTransSimple(0x33);
  670. /* 清空数据缓冲区 */
  671. for(uint32_t i = 0; i < BUFFER_SIZE; i++)
  672. {
  673. m_buffer[i] = 0;
  674. }
  675. /* 查询数据是否采集完成(应该是填充满128KB的SRAM)
  676. * 注意,这里是十进制33,不是0x33 */
  677. timePoint = std::chrono::steady_clock::now();
  678. while(m_usbInterface->usbCtrlTransSimple(0x50) != 33)
  679. {
  680. std::this_thread::sleep_for(std::chrono::microseconds(10));
  681. /* 如果超过1s还没有数据,就认为设备离线了 */
  682. if(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - timePoint).count() > 1)
  683. {
  684. SPDLOG_LOGGER_ERROR(m_logger, "示波器{}离线!", m_oscNum);
  685. m_isConnected.store(false);
  686. m_isRunCapture = false;
  687. return;
  688. }
  689. }
  690. // SPDLOG_LOGGER_DEBUG(m_logger, "硬件缓冲区已满");
  691. /* 将数据从示波器的SRAM中拷贝到电脑内存中,1次传输完成,设置超时时间1ms */
  692. m_usbInterface->readBulkData(BUFFER_SIZE, 1, 100, m_devBuffer);
  693. /* 等待传输完成 */
  694. auto ret = m_usbInterface->eventCheck(100);
  695. if(ret == 0x555)
  696. {
  697. SPDLOG_LOGGER_ERROR(m_logger, "数据传输超时!");
  698. // continue;
  699. }
  700. // SPDLOG_LOGGER_DEBUG(m_logger, "数据通过USB传输完成");
  701. /* 取出数据 */
  702. m_mutexBuffer.lock();
  703. std::memcpy(m_buffer, m_devBuffer, BUFFER_SIZE);
  704. m_mutexBuffer.unlock();
  705. // SPDLOG_LOGGER_DEBUG(m_logger, "count: {}", count++);
  706. m_isCapturedData = true;
  707. m_condCapture.notify_one();
  708. /* 清空缓冲区 */
  709. m_usbInterface->resetPipe();
  710. }
  711. m_isRunCapture = false;
  712. SPDLOG_LOGGER_INFO(m_logger, "采集数据线程结束");
  713. }
  714. /* 处理数据线程 */
  715. void OneOscilloscopeData::threadSeparateData()
  716. {
  717. SPDLOG_LOGGER_INFO(m_logger, "开始处理数据线程");
  718. while(m_runCapture)
  719. {
  720. {
  721. std::unique_lock<std::mutex> lock(m_mutexBuffer);
  722. m_condCapture.wait(lock, [this](){
  723. return m_isCapturedData.load();
  724. });
  725. /* 分离通道AB的数据 */
  726. m_mutexBuffer_A.lock();
  727. m_mutexBuffer_B.lock();
  728. for(uint32_t i = 0; i < BUFFER_SIZE / 2; i++)
  729. {
  730. m_bufferChnA[i] = m_buffer[i * 2];
  731. m_bufferChnB[i] = m_buffer[i * 2 + 1];
  732. }
  733. /* 处理数据 */
  734. // SPDLOG_LOGGER_DEBUG(m_logger, "开始处理数据,通道A数据: {}, 通道B数据: {}", m_bufferChnA[32000], m_bufferChnB[32000]);
  735. m_mutexBuffer_A.unlock();
  736. m_mutexBuffer_B.unlock();
  737. }
  738. }
  739. SPDLOG_LOGGER_INFO(m_logger, "处理数据线程结束");
  740. }
  741. /* 处理A通道数据 */
  742. void OneOscilloscopeData::threadProcessData_A()
  743. {
  744. while (m_runCapture)
  745. {
  746. std::unique_lock<std::mutex> lock(m_mutexBuffer_A);
  747. m_condBuffer_A.wait(lock);
  748. /* 矫正零电压值 */
  749. for(uint32_t i = 0; i < BUFFER_SIZE / 2; i++)
  750. {
  751. m_bufferChnA[i] = m_bufferChnA[i] + m_diffVoltageA;
  752. }
  753. /* 对零电平进行矫正 */
  754. /* 处理眼图数据 */
  755. parseEyeMapData(OscChannel::CH_A, m_bufferChnA, BUFFER_SIZE / 2);
  756. /* 添加颜色 */
  757. m_eyeMapMatrix_A->mutexEyeData.lock();
  758. m_eyeMapMatrix_A->addColorBySample();
  759. m_eyeMapMatrix_A->mutexEyeData.unlock();
  760. }
  761. }
  762. /* 处理B通道数据 */
  763. void OneOscilloscopeData::threadProcessData_B()
  764. {
  765. while (m_runCapture)
  766. {
  767. std::unique_lock<std::mutex> lock(m_mutexBuffer_B);
  768. m_condBuffer_B.wait(lock);
  769. /* 矫正零电压值 */
  770. for(uint32_t i = 0; i < BUFFER_SIZE / 2; i++)
  771. {
  772. m_bufferChnB[i] = m_bufferChnB[i] + m_diffVoltageB;
  773. }
  774. /* 对零电平进行矫正 */
  775. /* 处理眼图数据 */
  776. parseEyeMapData(OscChannel::CH_B, m_bufferChnB, BUFFER_SIZE / 2);
  777. /* 添加颜色 */
  778. m_eyeMapMatrix_B->mutexEyeData.lock();
  779. m_eyeMapMatrix_B->addColorBySample();
  780. m_eyeMapMatrix_B->mutexEyeData.unlock();
  781. }
  782. }
  783. /**
  784. * @brief 解析数据,眼图需要的数据,从C#代码中移植过来
  785. * 1、采样率为100MHz的时候,采样点间隔时间是10ns
  786. * x轴时间是1000分度,当x轴整体时间是10us的时候,采样点和分辨率一一对应
  787. * x轴时间大于10us,采样点比分辨率高,无需做什么操作
  788. * x轴时间小于10us,采样点数量会小于1000,那么绘制的矩形小点间隔会比较长,这时候就需要进行插帧
  789. * 2、屏幕中显示多少波形和波形的频率及时间屏幕可以显示的时间长度有关,波形的频率未知,所以这里只能通过调整时间长度来调整波形
  790. * 在屏幕中显示的数目
  791. * 3、当时间长度变小,小到整个屏幕的采样点数目不足1000的时候,就需要进行插值,插值到1000附近
  792. *
  793. * @param buffer 数据缓冲区
  794. * @param size 缓冲区大小,单位字节
  795. */
  796. void OneOscilloscopeData::parseEyeMapData(OscChannel chn, unsigned char* buffer, unsigned int size)
  797. {
  798. EyeDataMatrix* eyeDataMatrix = nullptr;
  799. EyeMapMatrix* eyeMapMatrix = nullptr;
  800. if(chn == OscChannel::CH_A)
  801. {
  802. eyeDataMatrix = m_eyeDataMatrix_A;
  803. eyeMapMatrix = m_eyeMapMatrix_A;
  804. }
  805. else if (chn == OscChannel::CH_B)
  806. {
  807. eyeDataMatrix = m_eyeDataMatrix_B;
  808. eyeMapMatrix = m_eyeMapMatrix_B;
  809. }
  810. else
  811. {
  812. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  813. return;
  814. }
  815. int bufferSize = size;
  816. uint8_t* array = buffer;
  817. uint8_t vaMax = 128;
  818. uint8_t vaMin = 128;
  819. uint8_t tmp = 128;
  820. /* 数据预处理,找出最大值和最小值 */
  821. for (int i = 0; i < bufferSize; i++)
  822. {
  823. /* 取出这组数据的最大值和最小值 */
  824. tmp = array[i];
  825. if (tmp < vaMin)
  826. {
  827. vaMin = tmp;
  828. }
  829. if (tmp > vaMax)
  830. {
  831. vaMax = tmp;
  832. }
  833. }
  834. /* 取绝对值,小于15丢弃,丢弃幅度小于15的数据,这部分可能不是触发的数据 */
  835. int numAmp = std::abs(vaMax - vaMin);
  836. if (numAmp <= 15)
  837. {
  838. return;
  839. }
  840. /* 计算最大值和最小值的中间数 */
  841. uint8_t vaMid = (vaMax + vaMin) / 2;
  842. /* ======================================================================== */
  843. /* 将采样点添加bool值,如果时间很短,就进行插值,每个采样点之间插入30个值 */
  844. /* 采样率为100MHz的时候,采样点间隔时间是10ns
  845. * x轴时间是1000分度,当x轴整体时间是10us的时候,采样点和分辨率一一对应
  846. * x轴时间大于10us,采样点比分辨率高,无需做什么操作
  847. * x轴时间小于10us,采样点数量会小于1000,那么绘制的矩形小点间隔会比较长,这时候就需要进行插帧 */
  848. /* 一个时间格子的采样率个数 */
  849. int oneGridSa = m_oneTimeGrid / m_SampleIntervalTime; /* 当前一个格子中采样点的数目 */
  850. int saTotal = oneGridSa * 10; /* 一个时间格子中采样点的总数 */
  851. /* 采样点个数小于颜色矩阵x方向的个数,就进行插帧 */
  852. bool isNeedFrameInsertion = ( saTotal < g_HorPixel ) ? true : false;
  853. int num9 = (int)((double)oneGridSa * 0.25); /* 1/4个时间格子长度 */
  854. /* 记录buffer的值,并添加bool */
  855. std::vector<EyeDataT> vecData;
  856. int numMulti = 0; /* 倍率,可能是1可能是30 */
  857. if (isNeedFrameInsertion == false)
  858. {
  859. /* 将数据放入到list中,带有bool标志位,全部启用 */
  860. for (int i = 0; i < bufferSize; i++)
  861. {
  862. vecData.push_back(EyeDataT(true, array[i]));
  863. }
  864. numMulti = 1;
  865. }
  866. else
  867. {
  868. /* 缩放系数小于1.0,下面会进行插值 */
  869. int numTmp = bufferSize - 1;
  870. float num11 = 0.0;
  871. uint8_t b2 = 0;
  872. uint8_t b3 = 0;
  873. uint8_t b = 0;
  874. /* 进行插值,每个采样点之间插值根据实际的采样点来计算,插值后的采样点个数比1000略大 */
  875. int numMulti2 = 0;
  876. double numMulti1 = g_HorPixel * 1.0 / saTotal;
  877. if(numMulti1 > 1.0 && numMulti1 < 2.0)
  878. {
  879. numMulti2 = 1;
  880. }
  881. else if(numMulti1 > 2.0 && numMulti1 < 3.0)
  882. {
  883. numMulti2 = 2;
  884. }
  885. else if(numMulti1 > 3.0)
  886. {
  887. numMulti2 = std::round(numMulti1);
  888. }
  889. for(int i = 0; i < numTmp; i++)
  890. {
  891. b2 = array[i];
  892. b3 = array[i + 1];
  893. num11 = (float)(b3 - b2) / numMulti2;
  894. vecData.push_back(EyeDataT(true, b2));
  895. for(int j = 0; j < numMulti2; j++)
  896. {
  897. b = std::round((num11 * (float)j) + (int)b2);
  898. vecData.push_back(EyeDataT(true, b));
  899. }
  900. vecData.push_back(EyeDataT(true, b3));
  901. }
  902. numMulti = numMulti2;
  903. }
  904. if (vecData.size() <= 0)
  905. {
  906. return;
  907. }
  908. num9 *= numMulti; /* 1/4个时间格子长度,乘以倍数 */
  909. /* 这里决定着时间的缩放关系,saTotal是整个显示区域的采样点个数 */
  910. long oneJumpSa = saTotal * numMulti;
  911. // long oneJumpSa = 1000;
  912. /* ======================================================================== */
  913. /* 寻找波形,找到上升沿和下降沿 */
  914. /* 存储下标 */
  915. std::vector<int> listSub;
  916. size_t numDataSize = vecData.size() - num9;
  917. bool flag3 = true;
  918. /* 找到数组中的上升沿和下降沿,并记录其坐标
  919. * 这里寻找上升沿和下降沿是检测的中间值,是每个跳变沿的中部
  920. * 中间值理论上是零值 */
  921. uint8_t vaPre = 0;
  922. // uint8_t va = 0;
  923. uint8_t vaNext = 0;
  924. for (int i = 10; i < numDataSize; i++)
  925. {
  926. /* 取出相邻的三个值 */
  927. vaPre = vecData[i - 1].value;
  928. // va = vecData[i].value;
  929. vaNext = vecData[i + 1].value;
  930. if (flag3)
  931. {
  932. /* 上升沿,就是中间值 */
  933. if (vaPre <= vaMid && vaNext > vaMid)
  934. {
  935. listSub.push_back(i); /* 记录下标 */
  936. flag3 = !flag3; /* 不再检测上升沿,检测下降沿 */
  937. }
  938. }
  939. /* 下降沿 */
  940. else if (vaPre >= vaMid && vaNext < vaMid)
  941. {
  942. listSub.push_back(i);
  943. flag3 = !flag3;
  944. }
  945. /* 采集到600个上升沿和下降沿 */
  946. if (listSub.size() >= 600)
  947. {
  948. break;
  949. }
  950. }
  951. if (listSub.size() <= 0)
  952. {
  953. return;
  954. }
  955. /* ======================================================================== */
  956. /* 这里应该是根据跳变沿的中间值,取出完整的跳变沿
  957. * 创建一个二维数组,每一行就是一个跳变沿 */
  958. std::vector<std::vector<EyeDataT>> vec2DEyeData;
  959. int jumpStart = 0; /* 跳变沿起点 */
  960. size_t jumpEnd = 0; /* 跳变沿终点 */
  961. int num17 = 0;
  962. size_t numSubSize = listSub.size(); /* 跳变沿下标的个数 */
  963. int oneThirdSa = (int)(oneJumpSa / 3); /* 一个时间格子中三分之一的采样点个数 */
  964. int numSub1 = 0;
  965. int numSub2 = 0;
  966. for (int i = 0; i < numSubSize; i++)
  967. {
  968. int j = 0;
  969. /* 这一个数组就是一个跳变沿,num12是一个跳变沿所有的采样点的个数 */
  970. std::vector<EyeDataT> vecDataTmp(oneJumpSa, EyeDataT(false, 0));
  971. numSub1 = listSub[i]; /* 取出下标值 */
  972. numSub2 = numSub1 - oneThirdSa; /* 下标往后倒退1/3个时间格子的采样点数,当作起点 */
  973. /* 判断是否小于0,这里是起点 */
  974. jumpStart = numSub2;
  975. if (jumpStart <= 0)
  976. {
  977. jumpStart = 0;
  978. }
  979. /* 终点往后2/3个时间格子的采样点数,当作终点 */
  980. jumpEnd = numSub1 + oneThirdSa * 2;
  981. if (jumpEnd >= vecData.size())
  982. {
  983. jumpEnd = vecData.size() - 1;
  984. }
  985. /* 这里为了去掉jumpStart前面的值,让vecDataTmp从0开始计数 */
  986. num17 = 0;
  987. if (numSub2 < 0)
  988. {
  989. num17 = std::abs(numSub2);
  990. }
  991. if (numSub2 > 0)
  992. {
  993. num17 = -numSub2;
  994. }
  995. /* num14是起点,num15是终点,num17应该是个负值,num17+j从0开始计数 */
  996. for (j = jumpStart; j < jumpEnd; j++)
  997. {
  998. vecDataTmp[num17 + j].isEyeData = vecData[j].isEyeData;
  999. vecDataTmp[num17 + j].value = vecData[j].value;
  1000. }
  1001. // for(j = 0; j < oneGridTime2; j++)
  1002. // {
  1003. // vecDataTmp[j].isEyeData = vecData[jumpStart + j].isEyeData;
  1004. // vecDataTmp[j].value = vecData[jumpStart + j].value;
  1005. // }
  1006. vec2DEyeData.push_back(vecDataTmp);
  1007. }
  1008. // listSub.clear();
  1009. // vecData.clear();
  1010. if (vec2DEyeData.size() <= 0)
  1011. {
  1012. return;
  1013. }
  1014. /* ======================================================================== */
  1015. int num18 = 0;
  1016. float num20 = 0.0;
  1017. /* 将数据拷贝到OscData的Matrix中 */
  1018. size_t numTmp = 0;
  1019. int ValTmp = 0;
  1020. /* 将跳变沿数据放入到全局变量中,并根据坐标进行排列
  1021. * x轴是这个跳变沿根据时间平分1000份
  1022. * y轴是这个值 */
  1023. eyeDataMatrix->mutexEyeData.lock();
  1024. for (int i = 0; i < vec2DEyeData.size(); i++)
  1025. {
  1026. /* 取出一个跳变沿,将其分布在整个 1000 * 256像素的矩阵中 */
  1027. std::vector<EyeDataT>& vecTmp = vec2DEyeData[i];
  1028. numTmp = vecTmp.size();
  1029. num20 = numTmp * 1.0 / g_HorPixel; /* x轴方向1000分 */
  1030. for (int i = 0; i < numTmp; i++)
  1031. {
  1032. if (vecTmp[i].isEyeData)
  1033. {
  1034. ValTmp = vecTmp[i].value;
  1035. num18 = (int)((float)i / num20);
  1036. /* 将数据添加到眼图矩阵中 */
  1037. eyeDataMatrix->addData(num18, ValTmp);
  1038. }
  1039. }
  1040. }
  1041. eyeDataMatrix->eyeStatisticalWeight();
  1042. eyeDataMatrix->eyeLessenTheBurden();
  1043. vec2DEyeData.clear();
  1044. auto eyeData = eyeDataMatrix->eyeZoomOut();
  1045. eyeDataMatrix->mutexEyeData.unlock();
  1046. eyeMapMatrix->mutexEyeData.lock();
  1047. eyeMapMatrix->copyDataMatrix(*eyeData);
  1048. eyeMapMatrix->mutexEyeData.unlock();
  1049. }
  1050. /* 设置零电压值和电压校准系数 */
  1051. void OneOscilloscopeData::setZeroVoltageAndCalibration(OscChannel chn, OscVoltageRange range)
  1052. {
  1053. if(chn == OscChannel::CH_A)
  1054. {
  1055. /* 电压幅值比 */
  1056. uint8_t altitudeByteA = 0;
  1057. m_zeroVoltageA = m_mapChAZeroVoltage.value(range);
  1058. altitudeByteA = m_mapChAVoltageAmplitudeRatio.value(range);
  1059. m_diffVoltageA = m_zeroVoltageA - 128;
  1060. if(range == OscVoltageRange::CR_100MV)
  1061. {
  1062. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1063. m_rangeRatioA = 0.1 / 255.0;
  1064. }
  1065. else if(range == OscVoltageRange::CR_250MV)
  1066. {
  1067. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1068. m_rangeRatioA = 0.25 / 255.0;
  1069. }
  1070. else if(range == OscVoltageRange::CR_500MV)
  1071. {
  1072. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1073. m_rangeRatioA = 0.5 / 255.0;
  1074. }
  1075. else if(range == OscVoltageRange::CR_1V)
  1076. {
  1077. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1078. m_rangeRatioA = 1.0 / 255.0;
  1079. }
  1080. else if(range == OscVoltageRange::CR_2V5)
  1081. {
  1082. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1083. m_rangeRatioA = 2.5 / 255.0;
  1084. }
  1085. else if(range == OscVoltageRange::CR_5V)
  1086. {
  1087. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1088. m_rangeRatioA = 5.0 / 255.0;
  1089. }
  1090. else if(range == OscVoltageRange::CR_8V)
  1091. {
  1092. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  1093. m_rangeRatioA = 8.0 / 255.0;
  1094. }
  1095. }
  1096. else if(chn == OscChannel::CH_B)
  1097. {
  1098. /* 电压幅值比 */
  1099. uint8_t altitudeByteB = 0;
  1100. m_zeroVoltageB = m_mapChBZeroVoltage.value(range);
  1101. altitudeByteB = m_mapChBVoltageAmplitudeRatio.value(range);
  1102. m_diffVoltageB = m_zeroVoltageB - 128;
  1103. if(range == OscVoltageRange::CR_100MV)
  1104. {
  1105. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1106. m_rangeRatioB = 0.1 / 255.0;
  1107. }
  1108. else if(range == OscVoltageRange::CR_250MV)
  1109. {
  1110. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1111. m_rangeRatioB = 0.25 / 255.0;
  1112. }
  1113. else if(range == OscVoltageRange::CR_500MV)
  1114. {
  1115. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1116. m_rangeRatioB = 0.5 / 255.0;
  1117. }
  1118. else if(range == OscVoltageRange::CR_1V)
  1119. {
  1120. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1121. m_rangeRatioB = 1.0 / 255.0;
  1122. }
  1123. else if(range == OscVoltageRange::CR_2V5)
  1124. {
  1125. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1126. m_rangeRatioB = 2.5 / 255.0;
  1127. }
  1128. else if(range == OscVoltageRange::CR_5V)
  1129. {
  1130. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1131. m_rangeRatioB = 5.0 / 255.0;
  1132. }
  1133. else if(range == OscVoltageRange::CR_8V)
  1134. {
  1135. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1136. m_rangeRatioB = 8.0 / 255.0;
  1137. }
  1138. }
  1139. }
  1140. /* 校准电压 */
  1141. double OneOscilloscopeData::calibrationVoltageA(uint8_t& data)
  1142. {
  1143. return m_voltageCalibrationA * m_rangeRatioA * (data - m_zeroVoltageA);
  1144. }
  1145. double OneOscilloscopeData::calibrationVoltageB(uint8_t& data)
  1146. {
  1147. return m_voltageCalibrationB * m_rangeRatioB * (data - m_zeroVoltageB);
  1148. }
  1149. /* 根据示波器编号获取示波器的数据矩阵指针 */
  1150. bool OneOscilloscopeData::getEyeDataMatrixPtr()
  1151. {
  1152. int chnA = m_oscNum * 2 - 1;
  1153. int chnB = m_oscNum * 2;
  1154. OscChnNum chnNumA = static_cast<OscChnNum>(chnA);
  1155. OscChnNum chnNumB = static_cast<OscChnNum>(chnB);
  1156. bool ret = true;
  1157. m_eyeDataMatrix_A = GOscDataInfo.findEyeDataMatrix(chnNumA);
  1158. if(m_eyeDataMatrix_A == nullptr)
  1159. {
  1160. SPDLOG_LOGGER_ERROR(m_logger, "示波器{} 通道A数据矩阵指针为空!", m_oscNum);
  1161. ret = false;
  1162. }
  1163. m_eyeDataMatrix_B = GOscDataInfo.findEyeDataMatrix(chnNumB);
  1164. if(m_eyeDataMatrix_B == nullptr)
  1165. {
  1166. SPDLOG_LOGGER_ERROR(m_logger, "示波器{} 通道B数据矩阵指针为空!", m_oscNum);
  1167. ret = false;
  1168. }
  1169. m_eyeMapMatrix_A = GOscDataInfo.findEyeMapMatrix(chnNumA);
  1170. if(m_eyeMapMatrix_A == nullptr)
  1171. {
  1172. SPDLOG_LOGGER_ERROR(m_logger, "示波器{} 通道A眼图矩阵指针为空!", m_oscNum);
  1173. ret = false;
  1174. }
  1175. m_eyeMapMatrix_B = GOscDataInfo.findEyeMapMatrix(chnNumB);
  1176. if(m_eyeMapMatrix_B == nullptr)
  1177. {
  1178. SPDLOG_LOGGER_ERROR(m_logger, "示波器{} 通道B眼图矩阵指针为空!", m_oscNum);
  1179. ret = false;
  1180. }
  1181. return ret;
  1182. }