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.

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