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.

359 lines
12 KiB

2 years ago
2 years ago
1 year ago
2 years 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
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year 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. #include "mainwindow.h"
  2. #include <QDateTime>
  3. #include <QMessageBox>
  4. #include <QtConcurrent>
  5. #include <QtCore/QVariant>
  6. #include <QtSerialPort/QSerialPort>
  7. #include <QtSerialPort/QSerialPortInfo>
  8. #include <QtWidgets/QLineEdit>
  9. #include "./ui_mainwindow.h"
  10. #include "iflytop_canbus/iflytop_canbus_master.hpp"
  11. #include "logger.hpp"
  12. #include "qt_serial_datachannel.hpp"
  13. #include "zexception.hpp"
  14. #include "zui/z_function_list_box.hpp"
  15. #include "zui/zq_vtab_page.hpp"
  16. //
  17. #include "zui/zui.hpp"
  18. using namespace std;
  19. using namespace iflytop;
  20. using namespace zcr;
  21. typedef enum {
  22. kone_lead_ecg,
  23. kthree_lead_ecg,
  24. } device_type_t;
  25. static MainWindow *m_mainWindow;
  26. static QTDataChannel G_QTDataChannel;
  27. static QTDataChannel G_WaveDataChannel;
  28. QT_REQUIRE_CONFIG(groupbox);
  29. #define TAG "MainWindow"
  30. static const char *fmt(const char *fmt, ...) {
  31. va_list args;
  32. va_start(args, fmt);
  33. static char buf[1024] = {0};
  34. vsnprintf(buf, sizeof(buf), fmt, args);
  35. va_end(args);
  36. return buf;
  37. }
  38. void MainWindow::log_output(QtMsgType type, const QMessageLogContext &context, const QString &msg) {}
  39. void MainWindow::doinui_slot(QFunction func) {
  40. if (func.get()) func.get()();
  41. }
  42. /***********************************************************************************************************************
  43. * PreviewShow *
  44. ***********************************************************************************************************************/
  45. void MainWindow::instructionPreviewShow(QString text) {
  46. QString info;
  47. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  48. info.append(" |");
  49. info.append(text);
  50. emit doinui_signal(QFunction([this, info]() { ui->instructionPreview->append(info); }));
  51. }
  52. void MainWindow::reportPreviewShow(QString text) {
  53. QString info;
  54. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  55. info.append(text);
  56. emit doinui_signal(QFunction([this, info]() {
  57. if (ui->reportPreview->document()->lineCount() > 1000) {
  58. ui->reportPreview->document()->clear();
  59. }
  60. ui->reportPreview->append(info);
  61. }));
  62. }
  63. void MainWindow::blockDataUploadPreviewShow(QString text) {
  64. QString info;
  65. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  66. info.append(text);
  67. emit doinui_signal(QFunction([this, info]() {
  68. if (ui->uploadDataPreview->document()->lineCount() > 1000) {
  69. ui->uploadDataPreview->document()->clear();
  70. }
  71. ui->uploadDataPreview->append(info);
  72. }));
  73. }
  74. void MainWindow::rawDataPreviewShow(QString text) {
  75. QString info;
  76. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
  77. info.append(text);
  78. emit doinui_signal(QFunction([this, info]() {
  79. if (ui->rawDataPreview->document()->lineCount() > 1000) {
  80. ui->rawDataPreview->document()->clear();
  81. }
  82. ui->rawDataPreview->append(info);
  83. }));
  84. }
  85. void MainWindow::instructionPreviewClear() {
  86. doinui_signal(QFunction([this]() { ui->instructionPreview->clear(); }));
  87. }
  88. #pragma pack(push, 1)
  89. typedef struct {
  90. uint16_t header;
  91. int16_t wave1;
  92. int16_t wave2;
  93. int16_t wave3;
  94. int16_t wave4;
  95. int16_t wave5;
  96. uint8_t check;
  97. uint16_t tail;
  98. } Wave_t;
  99. #pragma pack(pop)
  100. void MainWindow::displayWave(int16_t wave1, int16_t wave2, int16_t wave3) {
  101. // 1. 生成波形数据
  102. Wave_t wave;
  103. wave.header = 0xAAAA;
  104. wave.wave1 = wave1;
  105. wave.wave2 = wave2;
  106. wave.wave3 = wave3;
  107. wave.wave4 = 0;
  108. wave.wave5 = 0;
  109. wave.tail = 0x5555;
  110. wave.check = 0;
  111. uint8_t check = 0;
  112. for (size_t i = 2; i < sizeof(wave) - 2; i++) {
  113. check += ((uint8_t *)&wave)[i];
  114. }
  115. wave.check = check;
  116. // 2. 发送波形数据
  117. G_WaveDataChannel.send((uint8_t *)&wave, sizeof(wave));
  118. }
  119. /***********************************************************************************************************************
  120. * UI相关构造 *
  121. ***********************************************************************************************************************/
  122. void MainWindow::constructBaseUI() {
  123. /**
  124. * @brief UI
  125. */
  126. {
  127. const auto infos = QSerialPortInfo::availablePorts();
  128. for (const QSerialPortInfo &info : infos) {
  129. ui->serialPortCB->addItem(info.portName());
  130. }
  131. }
  132. ui->serialBaudrateCB->addItem("9600");
  133. ui->serialBaudrateCB->addItem("14400");
  134. ui->serialBaudrateCB->addItem("19200");
  135. ui->serialBaudrateCB->addItem("38400");
  136. ui->serialBaudrateCB->addItem("57600");
  137. ui->serialBaudrateCB->addItem("115200");
  138. ui->serialBaudrateCB->addItem("460800");
  139. ui->serialBaudrateCB->addItem("500000");
  140. ui->serialBaudrateCB->addItem("2000000");
  141. ui->serialBaudrateCB->setCurrentIndex(6);
  142. connect(ui->serialPortRefreshKey, &QPushButton::clicked, this, [this](bool check) {
  143. ui->serialPortCB->clear();
  144. const auto infos = QSerialPortInfo::availablePorts();
  145. for (const QSerialPortInfo &info : infos) {
  146. ui->serialPortCB->addItem(info.portName());
  147. }
  148. });
  149. connect(ui->serialOpenKey, &QPushButton::clicked, this, [=](bool check) {
  150. // 打开串口
  151. if (ui->serialOpenKey->text() == "打开") {
  152. G_QTDataChannel.setPortName(ui->serialPortCB->currentText().toStdString());
  153. G_QTDataChannel.setBaudRate(ui->serialBaudrateCB->currentText().toInt());
  154. G_QTDataChannel.setDataBits(QSerialPort::Data8);
  155. G_QTDataChannel.setParity(QSerialPort::NoParity);
  156. G_QTDataChannel.setFlowControl(QSerialPort::NoFlowControl);
  157. G_QTDataChannel.setStopBits(QSerialPort::OneStop);
  158. /**
  159. * @brief
  160. */
  161. if (!G_QTDataChannel.open()) {
  162. QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占??");
  163. return;
  164. }
  165. ui->serialOpenKey->setText("关闭");
  166. // 下拉菜单控件使能
  167. ui->serialBaudrateCB->setEnabled(false);
  168. ui->serialPortCB->setEnabled(false);
  169. ui->serialPortRefreshKey->setEnabled(false);
  170. IflytopCanbusMaster::ins()->updateChannelConfig();
  171. } else {
  172. G_QTDataChannel.close();
  173. ui->serialOpenKey->setText("打开");
  174. ui->serialBaudrateCB->setEnabled(true);
  175. ui->serialPortCB->setEnabled(true);
  176. ui->serialPortRefreshKey->setEnabled(true);
  177. }
  178. });
  179. /**
  180. * @brief UI
  181. */
  182. {
  183. const auto infos = QSerialPortInfo::availablePorts();
  184. for (const QSerialPortInfo &info : infos) {
  185. ui->waveSerialPortCB->addItem(info.portName());
  186. }
  187. }
  188. ui->waveSerialBaudrateCB->addItem("9600");
  189. ui->waveSerialBaudrateCB->addItem("14400");
  190. ui->waveSerialBaudrateCB->addItem("19200");
  191. ui->waveSerialBaudrateCB->addItem("38400");
  192. ui->waveSerialBaudrateCB->addItem("57600");
  193. ui->waveSerialBaudrateCB->addItem("115200");
  194. ui->waveSerialBaudrateCB->addItem("460800");
  195. ui->waveSerialBaudrateCB->addItem("500000");
  196. ui->waveSerialBaudrateCB->addItem("2000000");
  197. // ui->waveSerialBaudrateCB->addItems
  198. ui->waveSerialBaudrateCB->setCurrentIndex(6);
  199. connect(ui->waveSerialPortRefreshKey, &QPushButton::clicked, this, [this](bool check) {
  200. ui->waveSerialPortCB->clear();
  201. const auto infos = QSerialPortInfo::availablePorts();
  202. for (const QSerialPortInfo &info : infos) {
  203. ui->waveSerialPortCB->addItem(info.portName());
  204. }
  205. });
  206. connect(ui->waveSerialOpenKey, &QPushButton::clicked, this, [=](bool check) {
  207. // 打开串口
  208. if (ui->waveSerialOpenKey->text() == "打开") {
  209. G_WaveDataChannel.setPortName(ui->waveSerialPortCB->currentText().toStdString());
  210. G_WaveDataChannel.setBaudRate(ui->waveSerialBaudrateCB->currentText().toInt());
  211. G_WaveDataChannel.setDataBits(QSerialPort::Data8);
  212. G_WaveDataChannel.setParity(QSerialPort::NoParity);
  213. G_WaveDataChannel.setFlowControl(QSerialPort::NoFlowControl);
  214. G_WaveDataChannel.setStopBits(QSerialPort::OneStop);
  215. if (!G_WaveDataChannel.open()) {
  216. QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占??");
  217. return;
  218. }
  219. ui->waveSerialOpenKey->setText("关闭");
  220. // 下拉菜单控件使能
  221. ui->waveSerialBaudrateCB->setEnabled(false);
  222. ui->waveSerialPortCB->setEnabled(false);
  223. ui->waveSerialPortRefreshKey->setEnabled(false);
  224. } else {
  225. G_WaveDataChannel.close();
  226. ui->waveSerialOpenKey->setText("打开");
  227. ui->waveSerialBaudrateCB->setEnabled(true);
  228. ui->waveSerialPortCB->setEnabled(true);
  229. ui->waveSerialPortRefreshKey->setEnabled(true);
  230. }
  231. });
  232. }
  233. void MainWindow::displayInfo(bool suc, QString info) {}
  234. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
  235. /**
  236. * @brief QT初始化
  237. */
  238. ui->setupUi(this);
  239. m_mainWindow = this;
  240. qRegisterMetaType<int32_t>("int32_t");
  241. qRegisterMetaType<uint32_t>("uint32_t");
  242. qRegisterMetaType<float>("float");
  243. qRegisterMetaType<function<void()>>("function<void()>");
  244. qRegisterMetaType<QFunction>("QFunction");
  245. connect(this, SIGNAL(doinui_signal(QFunction)), this, SLOT(doinui_slot(QFunction)));
  246. ZQUI::ins()->initialize();
  247. ZQUI::ins()->setBlockDataUploadPreviewShow([this](QString text) { blockDataUploadPreviewShow(text); });
  248. ZQUI::ins()->setInstructionPreviewShow([this](QString text) { instructionPreviewShow(text); });
  249. ZQUI::ins()->setReportPreviewShow([this](QString text) { reportPreviewShow(text); });
  250. ZQUI::ins()->setRawDataPreviewShow([this](QString text) { rawDataPreviewShow(text); });
  251. ZQUI::ins()->setInstructionPreviewClear([this]() { instructionPreviewClear(); });
  252. /**
  253. * @brief
  254. */
  255. constructBaseUI();
  256. constructAppUI();
  257. /**
  258. * @brief
  259. */
  260. G_QTDataChannel.init();
  261. G_WaveDataChannel.init();
  262. IflytopCanbusMaster::ins()->initialize(&G_QTDataChannel);
  263. IflytopCanbusMaster::ins()->regOnRawData([this](raw_data_type_t type, uint8_t *hex, uint32_t hexlen) {
  264. if (type == kcmd_cmd) {
  265. ZQUI::ins()->rawDataPreviewShow("[CMD ] %s", zhex2str(hex, hexlen).c_str());
  266. } else if (type == kcmd_receipt) {
  267. ZQUI::ins()->rawDataPreviewShow("[RECEIPT] %s", zhex2str(hex, hexlen).c_str());
  268. } else if (type == kcmd_report) {
  269. ZQUI::ins()->rawDataPreviewShow("[REPORT ] %s", zhex2str(hex, hexlen).c_str());
  270. }
  271. });
  272. }
  273. MainWindow::~MainWindow() { delete ui; }
  274. void MainWindow::processException(const zexception &e) { //
  275. ZQUI::ins()->instructionPreviewShow("%s", e.what());
  276. }
  277. void MainWindow::constructAppUI() {
  278. {
  279. ZQVTabPage *tab = new ZQVTabPage(ui->buttonTabWidget, "模块操作");
  280. ZQFunctionListBox *box = new ZQFunctionListBox(tab, "模块基础操作", 4);
  281. box->regOnException([this](const zexception &e) { processException(e); });
  282. box->newFunc("扫描模块", {}, [this](int argn, const char **args) { //
  283. for (size_t i = 1; i < 255; i++) {
  284. try {
  285. IflytopCanbusMaster::ins()->ping(i);
  286. ZQUI::ins()->instructionPreviewShow("module :%d isOnline", i);
  287. } catch (const zexception &e) {
  288. if (e.ecode() != ke_overtime) {
  289. processException(e);
  290. break;
  291. }
  292. }
  293. }
  294. ZQUI::ins()->instructionPreviewShow("ScanModuleEnd");
  295. });
  296. tab->addSpacer();
  297. }
  298. {
  299. ZQVTabPage *tab = new ZQVTabPage(ui->buttonTabWidget, "寄存器操作");
  300. ZRegTableList *tableBox = new ZRegTableList(tab, "寄存器操作");
  301. tableBox->initializeRegOperation(
  302. [this](int32_t add, int32_t val) { //
  303. return true;
  304. },
  305. [this](int32_t add, int32_t *val) { //
  306. *val = add;
  307. return true;
  308. });
  309. // tableBox->add
  310. tableBox->addReg("123", 1, ZRegItem::krw | ZRegItem::kdec);
  311. tableBox->addReg("234", 2, ZRegItem::krw | ZRegItem::kdec);
  312. tableBox->addReg("345", 3, ZRegItem::krw | ZRegItem::kdec);
  313. tableBox->addSpacer();
  314. tab->addSpacer();
  315. }
  316. }