From 74050764eed15f236f768a6e7f55d5f1b37809c9 Mon Sep 17 00:00:00 2001 From: Sander Speetjens Date: Thu, 30 Jan 2025 15:39:16 +0100 Subject: [PATCH] Add can events --- Qt/CMakeLists.txt | 4 + Qt/can_transceive.cpp | 81 ++++ Qt/can_transceive.h | 31 ++ Qt/can_transceive.ui | 359 ++++++++++++++ Qt/simulator_base.cpp | 52 +- Qt/simulator_base.h | 2 + Qt/simulators/sim-can_debugger.cpp | 26 +- Qt/simulators/sim-can_debugger.h | 3 - Qt/simulators/sim-can_debugger.ui | 736 +++++++++++------------------ Qt/web_socket_wrapper.cpp | 21 +- Qt/web_socket_wrapper.h | 5 +- 11 files changed, 818 insertions(+), 502 deletions(-) create mode 100644 Qt/can_transceive.cpp create mode 100644 Qt/can_transceive.h create mode 100644 Qt/can_transceive.ui diff --git a/Qt/CMakeLists.txt b/Qt/CMakeLists.txt index b785bea..3b3a8c2 100644 --- a/Qt/CMakeLists.txt +++ b/Qt/CMakeLists.txt @@ -51,6 +51,10 @@ set(PROJECT_SOURCES better_radiobutton.cpp led.h led.cpp + + can_transceive.h + can_transceive.cpp + can_transceive.ui networkerror.h networkerror.cpp diff --git a/Qt/can_transceive.cpp b/Qt/can_transceive.cpp new file mode 100644 index 0000000..cf1af97 --- /dev/null +++ b/Qt/can_transceive.cpp @@ -0,0 +1,81 @@ +#include "can_transceive.h" +#include "ui_can_transceive.h" + +Can_Transceive::Can_Transceive(QWidget* parent) : QWidget(parent), ui(new Ui::Can_Transceive) { + ui->setupUi(this); + + can_send_hexspinboxes = { + ui->s_can_send_data0, + ui->s_can_send_data1, + ui->s_can_send_data2, + ui->s_can_send_data3, + ui->s_can_send_data4, + ui->s_can_send_data5, + ui->s_can_send_data6, + ui->s_can_send_data7, + }; + + enable_can_send_data(); + connect(ui->c_can_send_dlc, &QComboBox::currentIndexChanged, this, [=, this]{enable_can_send_data();}); + connect(ui->b_can_send_send, &QPushButton::clicked, this, [=, this]{emit send_can_message(ui->s_can_send_sid->value(), ui->c_can_send_dlc->currentIndex(), std::array({(uint8_t)(can_send_hexspinboxes[0]->value()), (uint8_t)(can_send_hexspinboxes[1]->value()),(uint8_t)(can_send_hexspinboxes[2]->value()),(uint8_t)(can_send_hexspinboxes[3]->value()),(uint8_t)(can_send_hexspinboxes[4]->value()),(uint8_t)(can_send_hexspinboxes[5]->value()),(uint8_t)(can_send_hexspinboxes[6]->value()),(uint8_t)(can_send_hexspinboxes[7]->value())}));}); + connect(ui->b_clear, &QPushButton::clicked, this, [=, this]{emit can_clear();}); +} + +Can_Transceive::~Can_Transceive() { + delete ui; +} + +void Can_Transceive::enable_can_send_data() +{ + uint8_t selected = atoi(ui->c_can_send_dlc->currentText().toLocal8Bit()); + for (size_t i = 0; i < can_send_hexspinboxes.size(); i++) + { + can_send_hexspinboxes[i]->setEnabled(i < selected); + if (i >= selected) + { + can_send_hexspinboxes[i]->setValue(0); + } + } +} + +void Can_Transceive::clear() +{ + ui->recvd_list->setRowCount(0); + ui->send_list->setRowCount(0); +} + +void Can_Transceive::add_send_item(uint32_t id, uint8_t dlc, std::array payload) +{ + size_t rc = ui->send_list->rowCount(); + ui->send_list->setRowCount(rc + 1); + + ui->send_list->setItem(rc, 0, new QTableWidgetItem(QString("%0").arg(id))); + ui->send_list->setItem(rc, 1, new QTableWidgetItem(QString("%0").arg(dlc))); + ui->send_list->setItem(rc, 2, new QTableWidgetItem(QString("%0").arg(payload[0]))); + ui->send_list->setItem(rc, 3, new QTableWidgetItem(QString("%0").arg(payload[1]))); + ui->send_list->setItem(rc, 4, new QTableWidgetItem(QString("%0").arg(payload[2]))); + ui->send_list->setItem(rc, 5, new QTableWidgetItem(QString("%0").arg(payload[3]))); + ui->send_list->setItem(rc, 6, new QTableWidgetItem(QString("%0").arg(payload[4]))); + ui->send_list->setItem(rc, 7, new QTableWidgetItem(QString("%0").arg(payload[5]))); + ui->send_list->setItem(rc, 8, new QTableWidgetItem(QString("%0").arg(payload[6]))); + ui->send_list->setItem(rc, 9, new QTableWidgetItem(QString("%0").arg(payload[7]))); + ui->send_list->resizeColumnsToContents(); +} + +void Can_Transceive::add_receive_item(uint32_t id, uint8_t dlc, std::array payload) +{ + size_t rc = ui->recvd_list->rowCount(); + ui->recvd_list->setRowCount(rc + 1); + + ui->recvd_list->setItem(rc, 0, new QTableWidgetItem(QString("%0").arg(id))); + ui->recvd_list->setItem(rc, 1, new QTableWidgetItem(QString("%0").arg(dlc))); + ui->recvd_list->setItem(rc, 2, new QTableWidgetItem(QString("%0").arg(payload[0]))); + ui->recvd_list->setItem(rc, 3, new QTableWidgetItem(QString("%0").arg(payload[1]))); + ui->recvd_list->setItem(rc, 4, new QTableWidgetItem(QString("%0").arg(payload[2]))); + ui->recvd_list->setItem(rc, 5, new QTableWidgetItem(QString("%0").arg(payload[3]))); + ui->recvd_list->setItem(rc, 6, new QTableWidgetItem(QString("%0").arg(payload[4]))); + ui->recvd_list->setItem(rc, 7, new QTableWidgetItem(QString("%0").arg(payload[5]))); + ui->recvd_list->setItem(rc, 8, new QTableWidgetItem(QString("%0").arg(payload[6]))); + ui->recvd_list->setItem(rc, 9, new QTableWidgetItem(QString("%0").arg(payload[7]))); + ui->recvd_list->resizeColumnsToContents(); +} diff --git a/Qt/can_transceive.h b/Qt/can_transceive.h new file mode 100644 index 0000000..f629242 --- /dev/null +++ b/Qt/can_transceive.h @@ -0,0 +1,31 @@ +#ifndef CAN_TRANSCEIVE_H +#define CAN_TRANSCEIVE_H + +#include +#include "hex_spinbox.h" + +namespace Ui { +class Can_Transceive; +} + +class Can_Transceive : public QWidget { + Q_OBJECT + + public: + explicit Can_Transceive(QWidget* parent = nullptr); + ~Can_Transceive(); + void enable_can_send_data(); + void clear(); + void add_send_item(uint32_t id, uint8_t dlc, std::array payload); + void add_receive_item(uint32_t id, uint8_t dlc, std::array payload); + + signals: + void send_can_message(uint32_t id, uint8_t dlc, std::array payload); + void can_clear(); + + private: + Ui::Can_Transceive* ui; + std::vector can_send_hexspinboxes; +}; + +#endif // CAN_TRANSCEIVE_H diff --git a/Qt/can_transceive.ui b/Qt/can_transceive.ui new file mode 100644 index 0000000..781026f --- /dev/null +++ b/Qt/can_transceive.ui @@ -0,0 +1,359 @@ + + + Can_Transceive + + + + 0 + 0 + 713 + 562 + + + + Form + + + + + + Received CAN messages + + + + + + + SID + + + + + DLC + + + + + Data 0 + + + + + Data 1 + + + + + Data 2 + + + + + Data 3 + + + + + Data 4 + + + + + Data 5 + + + + + Data 6 + + + + + Data 7 + + + + + + + + + + + Send CAN message + + + + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + + + + Send + + + + + + + 255 + + + + + + + 65535 + + + + + + + 255 + + + + + + + SID + + + + + + + DLC + + + + + + + Data 0 + + + + + + + Data 1 + + + + + + + Data 2 + + + + + + + Data 3 + + + + + + + Data 4 + + + + + + + Data 5 + + + + + + + Data 6 + + + + + + + Data 7 + + + + + + + 255 + + + + + + + 255 + + + + + + + 255 + + + + + + + 255 + + + + + + + 255 + + + + + + + 255 + + + + + + + + + + Send CAN messages + + + + + + + SID + + + + + DLC + + + + + Data 0 + + + + + Data 1 + + + + + Data 2 + + + + + Data 3 + + + + + Data 4 + + + + + Data 5 + + + + + Data 6 + + + + + Data 7 + + + + + + + + + + + clear buffers + + + + + + + + HexSpinBox + QSpinBox +
hex_spinbox.h
+
+
+ + +
diff --git a/Qt/simulator_base.cpp b/Qt/simulator_base.cpp index 094ff56..89664cd 100644 --- a/Qt/simulator_base.cpp +++ b/Qt/simulator_base.cpp @@ -1,4 +1,5 @@ #include "simulator_base.h" +#include "can_transceive.h" SimulatorBase::SimulatorBase(Web_socket_wrapper* web_socket, QWidget* parent) : QMainWindow{parent}, @@ -64,7 +65,7 @@ void SimulatorBase::on_event_cb(json& j) auto response = magic_enum::enum_cast(std::string(j.at("type"))).value_or(Web_socket_wrapper::Event::end); switch (response) { - case Web_socket_wrapper::Event::UI_changed: + case Web_socket_wrapper::Event::ui_changed: UI_item_parser(j); break; default: @@ -127,6 +128,11 @@ void SimulatorBase::UI_item_parser(json& input) process_ui_radiobutton(uiItem); continue; } + if (uiItem["type"] == "UI_can") + { + process_ui_can(uiItem); + continue; + } } } @@ -433,12 +439,42 @@ void SimulatorBase::process_ui_led(json& uiItem) } } +void SimulatorBase::process_ui_can(json& uiItem) +{ + QWidget* widget = id_to_ui(uiItem["id"]); + if (widget == nullptr) + { + QD << "id_to_ui returned null on " << QString::number((size_t)uiItem["id"]); + return; + } + + auto can_ui = qobject_cast(widget); + if (can_ui == nullptr) + { + QD << "widget is not of type led"; + return; + } + + can_ui->clear(); + for (auto& send_item : uiItem["can_send_messages"]) + { + can_ui->add_send_item(send_item["id"], send_item["dlc"], send_item["bytes"]); + } + + for (auto& recvd_item : uiItem["can_received_messages"]) + { + can_ui->add_receive_item(recvd_item["id"], recvd_item["dlc"], recvd_item["bytes"]); + } + +} + void SimulatorBase::setup_ui_item(QWidget* item, size_t index) { setup_button(item, index); setup_combobox(item, index); setup_dial(item, index); setup_slider(item, index); + setup_can_ui(item, index); } void SimulatorBase::setup_button(QWidget* item, size_t index) @@ -479,3 +515,17 @@ void SimulatorBase::setup_slider(QWidget* item, size_t index) m_web_socket->send_event(Web_socket_wrapper::Event::value_changed, index, slider->value());}); } + +void SimulatorBase::setup_can_ui(QWidget* item, size_t index) +{ + Can_Transceive* can = qobject_cast(item); + if (can == nullptr) + return; + + connect(can, &Can_Transceive::send_can_message, this, [=, this](uint32_t id, uint8_t dlc, std::array payload){ + m_web_socket->send_event(Web_socket_wrapper::Event::can_send, index, id, dlc, payload); + }); + connect(can, &Can_Transceive::can_clear, this, [=, this]{ + m_web_socket->send_event(Web_socket_wrapper::Event::can_clear, index); + }); +} diff --git a/Qt/simulator_base.h b/Qt/simulator_base.h index 37582b0..4ac5702 100644 --- a/Qt/simulator_base.h +++ b/Qt/simulator_base.h @@ -42,12 +42,14 @@ class SimulatorBase : public QMainWindow { virtual void process_ui_radiobutton(json& uiItem); virtual void process_ui_button(json& uiItem); virtual void process_ui_led(json& uiItem); + virtual void process_ui_can(json& uiItem); void setup_ui_item(QWidget* item, size_t index); void setup_button(QWidget* item, size_t index); void setup_combobox(QWidget* item, size_t index); void setup_dial(QWidget* item, size_t index); void setup_slider(QWidget* item, size_t index); + void setup_can_ui(QWidget* item, size_t index); void showEvent(QShowEvent* event); void closeEvent(QCloseEvent* event); diff --git a/Qt/simulators/sim-can_debugger.cpp b/Qt/simulators/sim-can_debugger.cpp index cc44761..9698bd8 100644 --- a/Qt/simulators/sim-can_debugger.cpp +++ b/Qt/simulators/sim-can_debugger.cpp @@ -6,32 +6,8 @@ Can_Debugger::Can_Debugger(Web_socket_wrapper* web_socket, QWidget *parent) : ui(new Ui::Can_Debugger) { ui->setupUi(this); this->setWindowTitle("CAN Debugger"); - can_send_hexspinboxes = { - ui->s_can_send_data0, - ui->s_can_send_data1, - ui->s_can_send_data2, - ui->s_can_send_data3, - ui->s_can_send_data4, - ui->s_can_send_data5, - ui->s_can_send_data6, - ui->s_can_send_data7, - }; - enable_can_send_data(); - connect(ui->c_can_send_dlc, &QComboBox::currentIndexChanged, this, [=]{enable_can_send_data();}); -} - -void Can_Debugger::enable_can_send_data() -{ - uint8_t selected = atoi(ui->c_can_send_dlc->currentText().toLocal8Bit()); - for (size_t i = 0; i < can_send_hexspinboxes.size(); i++) - { - can_send_hexspinboxes[i]->setEnabled(i < selected); - if (i >= selected) - { - can_send_hexspinboxes[i]->setValue(0); - } - } + this->push_ui_item(ui->can_transceive); } Can_Debugger::~Can_Debugger() { diff --git a/Qt/simulators/sim-can_debugger.h b/Qt/simulators/sim-can_debugger.h index 739ab44..71c91e8 100644 --- a/Qt/simulators/sim-can_debugger.h +++ b/Qt/simulators/sim-can_debugger.h @@ -3,7 +3,6 @@ #include #include "simulator_base.h" -#include "hex_spinbox.h" namespace Ui { class Can_Debugger; @@ -15,11 +14,9 @@ class Can_Debugger : public SimulatorBase { public: explicit Can_Debugger(Web_socket_wrapper* web_socket, QWidget *parent = nullptr); ~Can_Debugger(); - void enable_can_send_data(); private: Ui::Can_Debugger* ui; - std::vector can_send_hexspinboxes; }; #endif // SIM_CAN_DEBUGGER_H diff --git a/Qt/simulators/sim-can_debugger.ui b/Qt/simulators/sim-can_debugger.ui index f7c4e8f..9444e1b 100644 --- a/Qt/simulators/sim-can_debugger.ui +++ b/Qt/simulators/sim-can_debugger.ui @@ -14,481 +14,274 @@ MainWindow - - - - 450 - 10 - 641 - 121 - - - - Send CAN message - - - - - - - 0 + + + + + + + Global - - - - 1 + + + + + Get SID + + + + + + + + + + Output - - - - 2 + + + + + Reset 0 + + + + + + + Reset all + + + + + + + Set 0 + + + + + + + Cycle single + + + + + + + Cycle multi + + + + + + + Set all + + + + + + + Req Data 1 + + + + + + + + + + Input - - - - 3 + + + + + Enable T M + + + + + + + Disable T M + + + + + + + Req Data 1 + + + + + + + + + + Relais - - - - 4 + + + + + Set 0 + + + + + + + Reset 0 + + + + + + + Set all + + + + + + + Reset all + + + + + + + Req Data 1 + + + + + + + + + + ADC - - - - 5 + + + + + Request Data 2 single + + + + + + + Request Data 2 all + + + + + + + + + + DAC - - - - 6 + + + + + Set channel 1 op 20% + + + + + + + Reset channels to 0% + + + + + + + Voltage +10% + + + + + + + Voltage -10% + + + + + + + Set Channel + + + + + + + + + + HVac am80 cutom kaart robbe - - - - 7 - - - - - 8 - - - - - - - - Send - - - - - - - 255 - - - - - - - 65535 - - - - - - - 255 - - - - - - - SID - - - - - - - DLC - - - - - - - Data0 - - - - - - - Data1 - - - - - - - Data2 - - - - - - - Data3 - - - - - - - Data4 - - - - - - - Data5 - - - - - - - Data6 - - - - - - - Data7 - - - - - - - 255 - - - - - - - 255 - - - - - - - 255 - - - - - - - 255 - - - - - - - 255 - - - - - - - 255 - - - - - - - - - 20 - 0 - 413 - 951 - - - - - - - Global - - - - - - Get SID - - - - - - - - - - Output - - - - - - Reset 0 - - - - - - - Reset all - - - - - - - Set 0 - - - - - - - Cycle single - - - - - - - Cycle multi - - - - - - - Set all - - - - - - - Req Data 1 - - - - - - - - - - Input - - - - - - Enable T M - - - - - - - Disable T M - - - - - - - Req Data 1 - - - - - - - - - - Relais - - - - - - Set 0 - - - - - - - Reset 0 - - - - - - - Set all - - - - - - - Reset all - - - - - - - Req Data 1 - - - - - - - - - - ADC - - - - - - Request Data 2 single - - - - - - - Request Data 2 all - - - - - - - - - - DAC - - - - - - Set channel 1 op 20% - - - - - - - Reset channels to 0% - - - - - - - Voltage +10% - - - - - - - Voltage -10% - - - - - - - Set Channel - - - - - - - - - - HVac am80 cutom kaart robbe - - - - - - Single weerstand & Enable - - - - - - - Single stroom & Enable - - - - - - - Single weerstand & Disable - - - - - - - Single stroom & Disable - - - - - - - Enables set values - - - - - - - - + + + + + Single weerstand & Enable + + + + + + + Single stroom & Enable + + + + + + + Single weerstand & Disable + + + + + + + Single stroom & Disable + + + + + + + Enables set values + + + + + + + + + + + + @@ -504,9 +297,10 @@ - HexSpinBox - QSpinBox -
hex_spinbox.h
+ Can_Transceive + QWidget +
can_transceive.h
+ 1
diff --git a/Qt/web_socket_wrapper.cpp b/Qt/web_socket_wrapper.cpp index d34fa9c..a97e532 100644 --- a/Qt/web_socket_wrapper.cpp +++ b/Qt/web_socket_wrapper.cpp @@ -73,10 +73,11 @@ void Web_socket_wrapper::send_event(Event event, size_t id) switch (event) { case Event::clicked: + case Event::can_clear: j["event"]["type"] = magic_enum::enum_name(event).data(); j["event"]["id"] = id; m_web_socket->sendTextMessage(QString(j.dump().data())); - break; + break; default: break; } @@ -120,6 +121,24 @@ void Web_socket_wrapper::send_event(Event event, size_t id, QString val) } } +void Web_socket_wrapper::send_event(Event event, size_t id, uint32_t sid, uint8_t dlc, std::array payload) +{ + json j; + switch (event) + { + case Event::can_send: + j["event"]["type"] = magic_enum::enum_name(event).data(); + j["event"]["id"] = id; + j["event"]["sid"] = sid; + j["event"]["dlc"] = dlc; + j["event"]["payload"] = payload; + m_web_socket->sendTextMessage(QString(j.dump().data())); + break; + default: + break; + } +} + void Web_socket_wrapper::close() { if (m_connected) diff --git a/Qt/web_socket_wrapper.h b/Qt/web_socket_wrapper.h index c2a0c66..b7f86b4 100644 --- a/Qt/web_socket_wrapper.h +++ b/Qt/web_socket_wrapper.h @@ -27,7 +27,9 @@ class Web_socket_wrapper : public QObject value_changed, text_changed, selected, - UI_changed, + can_send, + can_clear, + ui_changed, end, begin = 0 }; @@ -39,6 +41,7 @@ class Web_socket_wrapper : public QObject void send_event(Event event, size_t id); void send_event(Event event, size_t id, double val); void send_event(Event event, size_t id, QString val); + void send_event(Event event, size_t id, uint32_t sid, uint8_t dlc, std::array payload); void close(); Q_SIGNALS: