You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

761 lines
29 KiB

2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "mainwindow.h"
  2. #include <QDateTime>
  3. #include <QMessageBox>
  4. #include <QtConcurrent>
  5. #include <QtSerialPort/QSerialPort>
  6. #include <QtSerialPort/QSerialPortInfo>
  7. #include "./ui_mainwindow.h"
  8. #include "ads129x/ads129x_type.h"
  9. #include "algo/iflytop_simple_filter.h"
  10. #include "electrocardiograph_tester.hpp"
  11. #include "filter_algo_mgr.hpp"
  12. #include "logger.hpp"
  13. #include "qt_serial_datachannel.hpp"
  14. #include "widgetplot2d.h"
  15. #include "zexception.hpp"
  16. WidgetPlot2D *wp2d;
  17. using namespace std;
  18. using namespace iflytop;
  19. typedef enum {
  20. kone_lead_ecg,
  21. kthree_lead_ecg,
  22. kone_lead_ecg_v2,
  23. } device_type_t;
  24. static MainWindow *m_mainWindow;
  25. static QTDataChannel G_QTDataChannel;
  26. static device_type_t m_devicetype;
  27. static const uint32_t str2int(QString str) {
  28. // 如果0x开头,按16进制转换
  29. // 如果0b开头,按2进制转换
  30. // 否则按10进制转换
  31. // 去除掉str中_
  32. str.remove("_");
  33. if (str.startsWith("0x")) {
  34. return str.toUInt(nullptr, 16);
  35. } else if (str.startsWith("0b")) {
  36. // remove 0b
  37. str.remove(0, 2);
  38. return str.toUInt(nullptr, 2);
  39. } else {
  40. return str.toUInt(nullptr, 10);
  41. }
  42. }
  43. #define TAG "MainWindow"
  44. static const char *fmt(const char *fmt, ...) {
  45. va_list args;
  46. va_start(args, fmt);
  47. static char buf[1024] = {0};
  48. vsnprintf(buf, sizeof(buf), fmt, args);
  49. va_end(args);
  50. return buf;
  51. }
  52. void MainWindow::log_output(QtMsgType type, const QMessageLogContext &context, const QString &msg) {}
  53. void MainWindow::doinui_slot(QFunction func) {
  54. if (func.get()) func.get()();
  55. }
  56. void MainWindow::ishow(const char *fmt, ...) {
  57. va_list args;
  58. va_start(args, fmt);
  59. char buf[1024] = {0};
  60. vsnprintf(buf, sizeof(buf), fmt, args);
  61. va_end(args);
  62. QString text(buf);
  63. QString info;
  64. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  65. info.append(" |");
  66. info.append(text);
  67. emit doinui_signal(QFunction([this, info]() { ui->instructionPreview->append(info); }));
  68. }
  69. void MainWindow::instructionPreviewClear() { ui->instructionPreview->document()->clear(); }
  70. void MainWindow::reportPreviewShow(const char *fmt, ...) {
  71. va_list args;
  72. va_start(args, fmt);
  73. char buf[1024] = {0};
  74. vsnprintf(buf, sizeof(buf), fmt, args);
  75. va_end(args);
  76. QString text(buf);
  77. QString info;
  78. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  79. info.append(text);
  80. emit doinui_signal(QFunction([this, info]() {
  81. if (ui->reportPreview->document()->lineCount() > 1000) {
  82. ui->reportPreview->document()->clear();
  83. }
  84. ui->reportPreview->append(info);
  85. }));
  86. }
  87. void MainWindow::blockDataUploadPreviewShow(const char *fmt, ...) {
  88. va_list args;
  89. va_start(args, fmt);
  90. char buf[1024] = {0};
  91. vsnprintf(buf, sizeof(buf), fmt, args);
  92. va_end(args);
  93. QString text(buf);
  94. QString info;
  95. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  96. info.append(text);
  97. emit doinui_signal(QFunction([this, info]() {
  98. if (ui->uploadDataPreview->document()->lineCount() > 1000) {
  99. ui->uploadDataPreview->document()->clear();
  100. }
  101. ui->uploadDataPreview->append(info);
  102. }));
  103. }
  104. void MainWindow::rawDataPreviewShow(const char *fmt, ...) {
  105. va_list args;
  106. va_start(args, fmt);
  107. char buf[1024] = {0};
  108. vsnprintf(buf, sizeof(buf), fmt, args);
  109. va_end(args);
  110. QString text(buf);
  111. QString info;
  112. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
  113. info.append(text);
  114. emit doinui_signal(QFunction([this, info]() {
  115. if (ui->rawDataPreview->document()->lineCount() > 1000) {
  116. ui->rawDataPreview->document()->clear();
  117. }
  118. ui->rawDataPreview->append(info);
  119. }));
  120. }
  121. // uploadDataPreview
  122. #pragma pack(push, 1)
  123. typedef struct {
  124. uint16_t header;
  125. int16_t wave1;
  126. int16_t wave2;
  127. int16_t wave3;
  128. int16_t wave4;
  129. int16_t wave5;
  130. uint8_t check;
  131. uint16_t tail;
  132. } Wave_t;
  133. #pragma pack(pop)
  134. void MainWindow::displayInfo(bool suc, QString info) {}
  135. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
  136. /*******************************************************************************
  137. * QT初始化 *
  138. *******************************************************************************/
  139. ui->setupUi(this);
  140. m_mainWindow = this;
  141. qRegisterMetaType<int32_t>("int32_t");
  142. qRegisterMetaType<uint32_t>("uint32_t");
  143. qRegisterMetaType<float>("float");
  144. qRegisterMetaType<function<void()>>("function<void()>");
  145. qRegisterMetaType<QFunction>("QFunction");
  146. connect(this, SIGNAL(doinui_signal(QFunction)), this, SLOT(doinui_slot(QFunction)));
  147. // qInstallMessageHandler(log_output);
  148. wp2d = new WidgetPlot2D();
  149. wp2d->initGraphName(QStringList() << "心电");
  150. /*******************************************************************************
  151. * *
  152. *******************************************************************************/
  153. constructUI();
  154. ui->TestCmd_writeSubICRegMask_p0->setPlaceholderText("寄存器地址");
  155. ui->TestCmd_writeSubICRegMask_p1->setPlaceholderText("偏移");
  156. ui->TestCmd_writeSubICRegMask_p2->setPlaceholderText("位数");
  157. ui->TestCmd_writeSubICRegMask_p3->setPlaceholderText("");
  158. ui->TestCmd_writeSubICReg_p0->setPlaceholderText("寄存器地址");
  159. ui->TestCmd_writeSubICReg_p1->setPlaceholderText("");
  160. /*******************************************************************************
  161. * *
  162. *******************************************************************************/
  163. G_QTDataChannel.init();
  164. ElectrocardiographTester::ins()->initialize(&G_QTDataChannel);
  165. }
  166. MainWindow::~MainWindow() { delete ui; }
  167. /*******************************************************************************
  168. * UI相关构造 *
  169. *******************************************************************************/
  170. void MainWindow::constructUI() {
  171. /*******************************************************************************
  172. * UI *
  173. *******************************************************************************/
  174. {
  175. const auto infos = QSerialPortInfo::availablePorts();
  176. for (const QSerialPortInfo &info : infos) {
  177. ui->serialPortCB->addItem(info.portName());
  178. }
  179. }
  180. ui->serialBaudrateCB->addItem("9600");
  181. ui->serialBaudrateCB->addItem("14400");
  182. ui->serialBaudrateCB->addItem("19200");
  183. ui->serialBaudrateCB->addItem("38400");
  184. ui->serialBaudrateCB->addItem("57600");
  185. ui->serialBaudrateCB->addItem("115200");
  186. ui->serialBaudrateCB->addItem("460800");
  187. ui->serialBaudrateCB->addItem("500000");
  188. ui->serialBaudrateCB->setCurrentIndex(6);
  189. connect(ui->serialPortRefreshKey, &QPushButton::clicked, this, [this](bool check) {
  190. ui->serialPortCB->clear();
  191. const auto infos = QSerialPortInfo::availablePorts();
  192. for (const QSerialPortInfo &info : infos) {
  193. ui->serialPortCB->addItem(info.portName());
  194. }
  195. });
  196. connect(ui->serialOpenKey, &QPushButton::clicked, this, [=](bool check) {
  197. // 打开串口
  198. if (ui->serialOpenKey->text() == "打开") {
  199. G_QTDataChannel.setPortName(ui->serialPortCB->currentText().toStdString());
  200. G_QTDataChannel.setBaudRate(ui->serialBaudrateCB->currentText().toInt());
  201. G_QTDataChannel.setDataBits(QSerialPort::Data8);
  202. G_QTDataChannel.setParity(QSerialPort::NoParity);
  203. G_QTDataChannel.setFlowControl(QSerialPort::NoFlowControl);
  204. G_QTDataChannel.setStopBits(QSerialPort::OneStop);
  205. if (!G_QTDataChannel.open()) {
  206. QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占??");
  207. return;
  208. }
  209. ui->serialOpenKey->setText("关闭");
  210. // 下拉菜单控件使能
  211. ui->serialBaudrateCB->setEnabled(false);
  212. ui->serialPortCB->setEnabled(false);
  213. ui->serialPortRefreshKey->setEnabled(false);
  214. } else {
  215. G_QTDataChannel.close();
  216. ui->serialOpenKey->setText("打开");
  217. ui->serialBaudrateCB->setEnabled(true);
  218. ui->serialPortCB->setEnabled(true);
  219. ui->serialPortRefreshKey->setEnabled(true);
  220. }
  221. });
  222. /*******************************************************************************
  223. * UI *
  224. *******************************************************************************/
  225. {
  226. ui->deviceType->addItem("单导联一代(M1001)");
  227. ui->deviceType->addItem("三导联一代(M1002)");
  228. ui->deviceType->addItem("单导联二代(M1003)");
  229. ui->deviceType->setCurrentIndex(0);
  230. connect(ui->deviceType, &QComboBox::currentTextChanged, this, [this](const QString &text) {
  231. if (text == "单导联一代(M1001)") {
  232. m_devicetype = kone_lead_ecg;
  233. } else if (text == "三导联一代(M1002)") {
  234. m_devicetype = kthree_lead_ecg;
  235. } else if (text == "单导联二代(M1003)") {
  236. m_devicetype = kone_lead_ecg_v2;
  237. }
  238. });
  239. }
  240. // 事件填充
  241. ElectrocardiographTester::ins()->regReportCB([this](bool checkok, ify_hrs_packet_t *report_packet, size_t len) {
  242. int reportType = report_packet->cmd;
  243. switch (reportType) {
  244. case ify_hrs_report_heartrate_data: {
  245. heartrate_report_packet_t *heartrate_report = (heartrate_report_packet_t *)report_packet;
  246. if (m_devicetype == kone_lead_ecg) {
  247. static uint32_t lastpacket_index = 0;
  248. static uint32_t lostpacket = 0;
  249. if ((lastpacket_index + 5) != (heartrate_report->sample_data_index)) {
  250. lostpacket++;
  251. }
  252. lastpacket_index = heartrate_report->sample_data_index;
  253. reportPreviewShow("[preview data ] lost:%d index %d", lostpacket, heartrate_report->sample_data_index);
  254. if (checkok) {
  255. uint16_t data0 = (uint16_t)(heartrate_report->data[0]) + ((uint16_t)heartrate_report->data[1] << 8);
  256. uint16_t data1 = (uint16_t)(heartrate_report->data[2]) + ((uint16_t)heartrate_report->data[3] << 8);
  257. uint16_t data2 = (uint16_t)(heartrate_report->data[4]) + ((uint16_t)heartrate_report->data[5] << 8);
  258. uint16_t data3 = (uint16_t)(heartrate_report->data[6]) + ((uint16_t)heartrate_report->data[7] << 8);
  259. uint16_t data4 = (uint16_t)(heartrate_report->data[8]) + ((uint16_t)heartrate_report->data[9] << 8);
  260. emit doinui_signal(QFunction([this, data0, data1, data2, data3, data4]() { //
  261. wp2d->addData("心电", data0, 0);
  262. wp2d->addData("心电", data1, 2);
  263. wp2d->addData("心电", data2, 4);
  264. wp2d->addData("心电", data3, 6);
  265. wp2d->addData("心电", data4, 8);
  266. // wp2d->addData("心电", data2);
  267. // wp2d->addData("心电", data3);
  268. // wp2d->addData("心电", data4);
  269. }));
  270. }
  271. } else if (m_devicetype == kthree_lead_ecg) {
  272. } else if (m_devicetype == kone_lead_ecg_v2) {
  273. if (checkok) {
  274. uint32_t packetlen = len - sizeof(heartrate_report_packet_t);
  275. static uint32_t lastpacket_index = 0;
  276. static uint32_t lostpacket = 0;
  277. if ((lastpacket_index + 50) != (heartrate_report->sample_data_index)) {
  278. lostpacket++;
  279. }
  280. lastpacket_index = heartrate_report->sample_data_index;
  281. uint32_t timestamp = *(uint32_t *)(&heartrate_report->data[50 * 4]);
  282. reportPreviewShow("[preview data ] timestamp:%10d lost:%d index %d packetlen %d", timestamp, lostpacket, heartrate_report->sample_data_index, packetlen);
  283. int32_t *frame = (int32_t *)heartrate_report->data;
  284. for (int i = 0; i < 50; i++) {
  285. int32_t data = frame[i];
  286. int32_t frameIndex = heartrate_report->sample_data_index + i;
  287. data = FilterAlgoMgr::ins()->processData("心电", data);
  288. emit doinui_signal(QFunction([this, data, i]() { wp2d->addData("心电", data, i * 2); }));
  289. }
  290. }
  291. }
  292. break;
  293. }
  294. case ify_hrs_report_battery_level: {
  295. reportPreviewShow("[battery_level ]");
  296. break;
  297. }
  298. case ify_hrs_report_low_battey_level: {
  299. reportPreviewShow("[low_battey ]");
  300. break;
  301. }
  302. case ify_hrs_report_sample_finish_end: {
  303. reportPreviewShow("[sample_finish ]");
  304. break;
  305. }
  306. case ify_hrs_report_sensor_drop_detect: {
  307. sensor_drop_event_report_packet_t *sensor_drop_report = (sensor_drop_event_report_packet_t *)report_packet->data;
  308. reportPreviewShow("[sensor_drop ] %s %s", zhex2binary(sensor_drop_report->drop_state0).c_str(), zhex2binary(sensor_drop_report->drop_state1).c_str());
  309. break;
  310. }
  311. case ify_hrs_report_record_upload_end: {
  312. uint32_t checksum = *(uint32_t *)report_packet->data;
  313. reportPreviewShow("[upload end ] checksum: 0x%08x", checksum);
  314. break;
  315. }
  316. default:
  317. break;
  318. }
  319. });
  320. ElectrocardiographTester::ins()->regCh4CheckSumPacketReport([this](uint32_t rxcnt, uint32_t report_packet_checksum) { //
  321. blockDataUploadPreviewShow("RXCNT %d CHECKSUM 0x%08x", rxcnt, report_packet_checksum);
  322. });
  323. ElectrocardiographTester::ins()->regRawDataCB([this](raw_data_type_t type, uint8_t *hex, uint32_t hexlen) {
  324. if (type == kcmd_cmd) {
  325. rawDataPreviewShow("[CMD ] %s", zhex2str(hex, hexlen).c_str());
  326. } else if (type == kcmd_receipt) {
  327. rawDataPreviewShow("[RECEIPT] %s", zhex2str(hex, hexlen).c_str());
  328. } else if (type == kcmd_report) {
  329. rawDataPreviewShow("[REPORT ] %s", zhex2str(hex, hexlen).c_str());
  330. } else if (type == kcmd_ch4_data) {
  331. // rawDataPreviewShow("[CH4 ] %s", zhex2str(hex, hexlen).c_str());
  332. }
  333. });
  334. }
  335. void MainWindow::processException(zexception &e) { ishow("%s:%s", e.what(), ify_hrs_error_code_to_string((ify_hrs_error_code_t)e.ecode())); }
  336. void MainWindow::on_readDeviceVersion_clicked() {
  337. instructionPreviewClear();
  338. try {
  339. device_version_info_receipt_t version;
  340. ElectrocardiographTester::ins()->readDeviceVersion(&version);
  341. ishow("-------------- version ----------------");
  342. ishow(" blestack_version: %d", version.blestack_version);
  343. ishow(" bootloader_version: %d", version.bootloader_version);
  344. ishow(" firmware_version: %d", version.firmware_version);
  345. ishow(" hardware_version: %d", version.hardware_version);
  346. } catch (zexception &exception) {
  347. processException(exception);
  348. }
  349. }
  350. void MainWindow::on_readDeviceState_clicked() {
  351. instructionPreviewClear();
  352. try {
  353. device_state_receipt_t state;
  354. ElectrocardiographTester::ins()->readDeviceState(&state);
  355. ishow("-------------- state ----------------");
  356. ishow(" drop_state0: %s", zhex2binary(state.drop_state0).c_str());
  357. ishow(" drop_state1: %s", zhex2binary(state.drop_state1).c_str());
  358. ishow(" sampling_state: %d", state.device_state0.sampling_state);
  359. ishow(" report_state: %d", state.device_state0.report_state);
  360. ishow(" low_battery: %d", state.device_state0.low_battery);
  361. ishow(" full_storge: %d", state.device_state0.full_storge);
  362. ishow(" holder: %d", state.device_state0.holder);
  363. ishow(" powerlevel: %d", state.powerlevel);
  364. ishow(" storage_item_num: %d", state.storage_item_num);
  365. } catch (zexception &exception) {
  366. processException(exception);
  367. }
  368. }
  369. void MainWindow::on_readTime_clicked() {
  370. instructionPreviewClear();
  371. try {
  372. read_time_receipt_t time;
  373. ElectrocardiographTester::ins()->readTime(&time);
  374. ishow("-------------- time ----------------");
  375. ishow(" %d/%d/%d %d:%d:%d", time.year + 2000, time.month, time.day, time.hour, time.minute, time.second);
  376. } catch (zexception &exception) {
  377. processException(exception);
  378. }
  379. }
  380. void MainWindow::on_syncTime_clicked() {
  381. instructionPreviewClear();
  382. try {
  383. // 获取系统时间
  384. QDateTime now = QDateTime::currentDateTime();
  385. ElectrocardiographTester::ins()->syncTime(now.date().year() - 2000, now.date().month(), now.date().day(), now.time().hour(), now.time().minute(), now.time().second());
  386. ishow("sync time success!");
  387. } catch (zexception &exception) {
  388. processException(exception);
  389. }
  390. }
  391. std::string zhex2time(const uint8_t *hex, size_t len) {
  392. std::string str;
  393. if (len < 6) return str;
  394. str.append(fmt("%d/%d/%d %2d:%2d:%2d", hex[0] + 2000, hex[1], hex[2], hex[3], hex[4], hex[5]));
  395. return str;
  396. }
  397. void MainWindow::on_readAllRecords_clicked() {
  398. // 读取当前有多少条记录
  399. instructionPreviewClear();
  400. try {
  401. device_state_receipt_t state;
  402. ElectrocardiographTester::ins()->readDeviceState(&state);
  403. ishow("index recordid frameNum dataSize sensorNum captRate captPrec compAlgo checksum");
  404. for (int32_t i = 0; i < state.storage_item_num; i++) {
  405. read_record_info_receipt_t record;
  406. ElectrocardiographTester::ins()->readRecordsInfo(i, &record);
  407. ishow("%d %s %8d %8d %8d %8d %8d %8d 0x%08x", i, zhex2time(record.record_id, 6).c_str(), record.frameNum, record.dataSize, record.sensorNum, record.captureRate, record.capturePrecision, record.compressAlgorithm, record.checksum);
  408. }
  409. } catch (zexception &exception) {
  410. processException(exception);
  411. }
  412. }
  413. void MainWindow::on_startUploadRecord_clicked() {
  414. instructionPreviewClear();
  415. int reportIndex = ui->startUploadRecord_p0->toPlainText().toInt();
  416. try {
  417. read_record_info_receipt_t record;
  418. ElectrocardiographTester::ins()->readRecordsInfo(reportIndex, &record);
  419. ElectrocardiographTester::ins()->startUploadRecord(record.record_id);
  420. ishow("start upload record [%s] success", zhex2time(record.record_id, 6).c_str());
  421. } catch (zexception &exception) {
  422. processException(exception);
  423. }
  424. }
  425. void MainWindow::on_readSensorInfo_clicked() {
  426. instructionPreviewClear();
  427. try {
  428. sensor_info_receipt_t sensor;
  429. ElectrocardiographTester::ins()->readSensorInfo(&sensor);
  430. ishow("-------------- sensor ----------------");
  431. ishow(" sensor_num: %d", sensor.sensor_num);
  432. ishow(" sensor_precision: %d", sensor.sensor_precision);
  433. ishow(" sensor_sample_rate:%d", sensor.sensor_sample_rate);
  434. ishow(" sensor0_pos: %d", sensor.sensor0_pos);
  435. ishow(" sensor1_pos: %d", sensor.sensor1_pos);
  436. ishow(" sensor2_pos: %d", sensor.sensor2_pos);
  437. } catch (zexception &exception) {
  438. processException(exception);
  439. }
  440. }
  441. void MainWindow::on_readSN_clicked() {
  442. instructionPreviewClear();
  443. try {
  444. string sn;
  445. ElectrocardiographTester::ins()->readSn(sn);
  446. ishow("-------------- sn ----------------");
  447. ishow(" sn: %s", sn.c_str());
  448. } catch (zexception &exception) {
  449. processException(exception);
  450. }
  451. }
  452. void MainWindow::on_stopUploadRecord_clicked() {
  453. instructionPreviewClear();
  454. try {
  455. ElectrocardiographTester::ins()->stopUploadRecord();
  456. ishow("stop upload record success");
  457. } catch (zexception &exception) {
  458. processException(exception);
  459. }
  460. }
  461. void MainWindow::on_delRecord_clicked() {
  462. instructionPreviewClear();
  463. int reportIndex = ui->delRecord_p0->toPlainText().toInt();
  464. try {
  465. read_record_info_receipt_t record;
  466. ElectrocardiographTester::ins()->readRecordsInfo(reportIndex, &record);
  467. ElectrocardiographTester::ins()->delRecord(record.record_id);
  468. ishow("delete record [%s] success", zhex2time(record.record_id, 6).c_str());
  469. } catch (zexception &exception) {
  470. processException(exception);
  471. }
  472. }
  473. #if 0
  474. void MainWindow::on_startCapture_clicked() {
  475. instructionPreviewClear();
  476. try {
  477. ElectrocardiographTester::ins()->startCapture();
  478. ishow("start capture success");
  479. } catch (zexception &exception) {
  480. processException(exception);
  481. }
  482. }
  483. void MainWindow::on_stopCapture_clicked() {
  484. instructionPreviewClear();
  485. try {
  486. ElectrocardiographTester::ins()->stopCapture();
  487. ishow("stop capture success");
  488. } catch (zexception &exception) {
  489. processException(exception);
  490. }
  491. }
  492. #endif
  493. void MainWindow::on_startRealtimeReport_clicked() {
  494. instructionPreviewClear();
  495. try {
  496. ElectrocardiographTester::ins()->startRealtimeReport();
  497. ishow("start realtime report success");
  498. wp2d->show();
  499. } catch (zexception &exception) {
  500. processException(exception);
  501. }
  502. }
  503. void MainWindow::on_stopRealtimeReport_clicked() {
  504. instructionPreviewClear();
  505. try {
  506. ElectrocardiographTester::ins()->stopRealtimeReport();
  507. ishow("stop realtime report success");
  508. wp2d->hide();
  509. } catch (zexception &exception) {
  510. processException(exception);
  511. }
  512. }
  513. void MainWindow::on_clearPreview_clicked() {
  514. ui->reportPreview->document()->clear();
  515. ui->uploadDataPreview->document()->clear();
  516. ui->rawDataPreview->document()->clear();
  517. ui->instructionPreview->document()->clear();
  518. }
  519. void MainWindow::on_TestCmd_readSubIcRegs_clicked() {
  520. instructionPreviewClear();
  521. try {
  522. uint8_t data[12];
  523. data[ADS129X_REG_ID] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_ID);
  524. data[ADS129X_REG_CONFIG1] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CONFIG1);
  525. data[ADS129X_REG_CONFIG2] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CONFIG2);
  526. data[ADS129X_REG_LOFF] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_LOFF);
  527. data[ADS129X_REG_CH1SET] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CH1SET);
  528. data[ADS129X_REG_CH2SET] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CH2SET);
  529. data[ADS129X_REG_RLDSENS] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_RLDSENS);
  530. data[ADS129X_REG_LOFFSENS] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_LOFFSENS);
  531. data[ADS129X_REG_LOFFSTAT] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_LOFFSTAT);
  532. data[ADS129X_REG_RESP1] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_RESP1);
  533. data[ADS129X_REG_RESP2] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_RESP2);
  534. data[ADS129X_REG_GPIO] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_GPIO);
  535. ishow("reg %10s %02d: 0x%02x", "ID", ADS129X_REG_ID, data[ADS129X_REG_ID]);
  536. ishow("reg %10s %02d: 0x%02x", "CONFIG1", ADS129X_REG_CONFIG1, data[ADS129X_REG_CONFIG1]);
  537. ishow("reg %10s %02d: 0x%02x", "CONFIG2", ADS129X_REG_CONFIG2, data[ADS129X_REG_CONFIG2]);
  538. ishow("reg %10s %02d: 0x%02x", "LOFF", ADS129X_REG_LOFF, data[ADS129X_REG_LOFF]);
  539. ishow("reg %10s %02d: 0x%02x", "CH1SET", ADS129X_REG_CH1SET, data[ADS129X_REG_CH1SET]);
  540. ishow("reg %10s %02d: 0x%02x", "CH2SET", ADS129X_REG_CH2SET, data[ADS129X_REG_CH2SET]);
  541. ishow("reg %10s %02d: 0x%02x", "RLDSENS", ADS129X_REG_RLDSENS, data[ADS129X_REG_RLDSENS]);
  542. ishow("reg %10s %02d: 0x%02x", "LOFFSENS", ADS129X_REG_LOFFSENS, data[ADS129X_REG_LOFFSENS]);
  543. ishow("reg %10s %02d: 0x%02x %s", "LOFFSTAT", ADS129X_REG_LOFFSTAT, data[ADS129X_REG_LOFFSTAT], zhex2binary(data[ADS129X_REG_LOFFSTAT]).c_str());
  544. ishow("reg %10s %02d: 0x%02x", "RESP1", ADS129X_REG_RESP1, data[ADS129X_REG_RESP1]);
  545. ishow("reg %10s %02d: 0x%02x", "RESP2", ADS129X_REG_RESP2, data[ADS129X_REG_RESP2]);
  546. ishow("reg %10s %02d: 0x%02x", "GPIO", ADS129X_REG_GPIO, data[ADS129X_REG_GPIO]);
  547. ishow("regs: %s", zhex2str(data, 12).c_str());
  548. } catch (zexception &exception) {
  549. processException(exception);
  550. }
  551. }
  552. void MainWindow::on_TestCmd_writeSubICReg_clicked() {
  553. uint32_t add = str2int(ui->TestCmd_writeSubICReg_p0->toPlainText());
  554. uint32_t val = str2int(ui->TestCmd_writeSubICReg_p1->toPlainText());
  555. instructionPreviewClear();
  556. try {
  557. ElectrocardiographTester::ins()->testCmdWriteReg(add, val);
  558. ishow("write reg %d: 0x%02x success", add, val);
  559. } catch (zexception &exception) {
  560. processException(exception);
  561. }
  562. }
  563. void MainWindow::on_TestCmd_writeSubICRegMask_clicked() {
  564. uint8_t add = ui->TestCmd_writeSubICRegMask_p0->toPlainText().toInt();
  565. uint8_t off = ui->TestCmd_writeSubICRegMask_p1->toPlainText().toInt();
  566. uint8_t bitnum = ui->TestCmd_writeSubICRegMask_p2->toPlainText().toInt();
  567. uint8_t val = ui->TestCmd_writeSubICRegMask_p3->toPlainText().toInt();
  568. instructionPreviewClear();
  569. try {
  570. uint8_t regval = ElectrocardiographTester::ins()->testCmdReadReg(add);
  571. uint8_t oldval = regval;
  572. uint8_t mask = (1 << bitnum) - 1;
  573. mask = mask << off;
  574. regval = regval & (~mask);
  575. regval = regval | (val << off);
  576. ElectrocardiographTester::ins()->testCmdWriteReg(add, regval);
  577. ishow("write reg %d: 0x%02x -> 0x%02x success", add, oldval, regval);
  578. } catch (const std::exception &e) {
  579. std::cerr << e.what() << '\n';
  580. }
  581. }
  582. void MainWindow::on_TestCmd_startCapture_clicked() {
  583. instructionPreviewClear();
  584. try {
  585. ElectrocardiographTester::ins()->testCmdStartCapture();
  586. ishow("call start capture success");
  587. wp2d->show();
  588. } catch (zexception &exception) {
  589. processException(exception);
  590. }
  591. }
  592. void MainWindow::on_TestCmd_stopCapture_clicked() {
  593. instructionPreviewClear();
  594. try {
  595. ElectrocardiographTester::ins()->testCmdStopCapture();
  596. ishow("call stop capture success");
  597. } catch (zexception &exception) {
  598. processException(exception);
  599. }
  600. }
  601. void MainWindow::on_TestCmd_changeECGSrcToSquareWave_clicked() {
  602. instructionPreviewClear();
  603. try {
  604. uint8_t cfg2 = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CONFIG2);
  605. uint8_t ch1set = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CH1SET);
  606. cfg2 = ADS129X_SET_BITS(cfg2, ADS129X_INT_TEST, ADS129X_INT_TEST_ON);
  607. cfg2 = ADS129X_SET_BITS(cfg2, ADS129X_INT_FREQ, ADS129X_INT_FREQ_AC);
  608. ch1set = ADS129X_SET_BITS(ch1set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST);
  609. ElectrocardiographTester::ins()->testCmdWriteReg(ADS129X_REG_CONFIG2, cfg2);
  610. ElectrocardiographTester::ins()->testCmdWriteReg(ADS129X_REG_CH1SET, ch1set);
  611. ishow("call change ECG src to square wave success");
  612. } catch (zexception &exception) {
  613. processException(exception);
  614. }
  615. }
  616. void MainWindow::on_resetDevice_clicked() {
  617. instructionPreviewClear();
  618. try {
  619. ElectrocardiographTester::ins()->reset();
  620. } catch (zexception &exception) {
  621. // processException(exception);
  622. }
  623. ishow("call reset device success");
  624. }
  625. void MainWindow::on_FilterUpdateParameter_clicked() {
  626. instructionPreviewClear();
  627. FilterAlgoMgr::ins()->FilterCommon_setSampleTimeMs(ui->FilterCommon_SampleTimeMs->text().toFloat());
  628. FilterAlgoMgr::ins()->LPFilter_setEnable(ui->LPFilter_Enable->isChecked());
  629. FilterAlgoMgr::ins()->LPFilter_setCutoffFreqHz(ui->LPFilter_CutoffFreqHz->text().toFloat());
  630. FilterAlgoMgr::ins()->LPFilter_setOrder(ui->LPFilter_Order->text().toInt());
  631. FilterAlgoMgr::ins()->HPFilter_setEnable(ui->HPFilter_Enable->isChecked());
  632. FilterAlgoMgr::ins()->HPFilter_setCutoffFreqHz(ui->HPFilter_CutoffFreqHz->text().toFloat());
  633. FilterAlgoMgr::ins()->HPFilter_setOrder(ui->HPFilter_Order->text().toInt());
  634. FilterAlgoMgr::ins()->NOTCHFilter_setEnable(ui->NOTCHFilter_Enable->isChecked());
  635. FilterAlgoMgr::ins()->NOTCHFilter_setCenterFreqHz(ui->NOTCHFilter_CenterFreqHz->text().toFloat());
  636. FilterAlgoMgr::ins()->NOTCHFilter_setNotchWidthHz(ui->NOTCHFilter_NotchWidthHz->text().toFloat());
  637. FilterAlgoMgr::ins()->NOTCHFilter_setOrder(ui->NOTCHFilter_Order->text().toInt());
  638. FilterAlgoMgr::ins()->updateParameter();
  639. on_buttonTabWidget_currentChanged(0);
  640. ishow("Filter Update Parameter success");
  641. }
  642. void MainWindow::on_buttonTabWidget_currentChanged(int index) {
  643. ui->FilterCommon_SampleTimeMs->setText(QString::number(FilterAlgoMgr::ins()->FilterCommon_getSampleTimeMs()));
  644. ui->LPFilter_Enable->setChecked(FilterAlgoMgr::ins()->LPFilter_getEnable());
  645. ui->LPFilter_CutoffFreqHz->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getCutoffFreqHz()));
  646. ui->LPFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getOrder()));
  647. ui->HPFilter_Enable->setChecked(FilterAlgoMgr::ins()->HPFilter_getEnable());
  648. ui->HPFilter_CutoffFreqHz->setText(QString::number(FilterAlgoMgr::ins()->HPFilter_getCutoffFreqHz()));
  649. ui->HPFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->HPFilter_getOrder()));
  650. ui->NOTCHFilter_Enable->setChecked(FilterAlgoMgr::ins()->NOTCHFilter_getEnable());
  651. ui->NOTCHFilter_CenterFreqHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getCenterFreqHz()));
  652. ui->NOTCHFilter_NotchWidthHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getNotchWidthHz()));
  653. ui->NOTCHFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getOrder()));
  654. }
  655. void MainWindow::on_TestCmd_writeSubICAllReg_clicked() {
  656. // 0x52,0x02,0xe0,0xF1,0x00,0x80,0x00,0x03,0x12,0x02,0x07,0x0c
  657. instructionPreviewClear();
  658. QString regs = ui->TestCmd_writeSubICAllReg_p0->toPlainText();
  659. QStringList reglist = regs.split(",");
  660. if (reglist.size() != 12) {
  661. ishow("reg size error %d != 12", reglist.size());
  662. return;
  663. }
  664. try {
  665. uint8_t data[12];
  666. for (int i = 0; i < 12; i++) {
  667. data[i] = str2int(reglist[i]);
  668. }
  669. for (size_t i = 0; i < 12; i++) {
  670. ElectrocardiographTester::ins()->testCmdWriteReg(i, data[i]);
  671. ishow("write reg %d: 0x%02x success", i, data[i]);
  672. }
  673. ishow("write all reg success");
  674. } catch (zexception &exception) {
  675. processException(exception);
  676. }
  677. }