diff --git a/canframemodel.cpp b/canframemodel.cpp index 496a165..42ca0a5 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -145,6 +145,15 @@ void CANFrameModel::sendRefresh(int pos) endInsertRows(); } +//issue a refresh for the last num entries in the model. +//used by the serial worker to do batch updates so it doesn't +//have to send thousands of messages per second +void CANFrameModel::sendBulkRefresh(int num) +{ + //qDebug() << "Bulk refresh of " << num; + beginInsertRows(QModelIndex(), frames.count() - num, frames.count() - 1); + endInsertRows(); +} void CANFrameModel::clearFrames() { diff --git a/canframemodel.h b/canframemodel.h index 21c6d68..af2499d 100644 --- a/canframemodel.h +++ b/canframemodel.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "can_structs.h" #include "dbchandler.h" @@ -23,6 +24,7 @@ public: void addFrame(CANFrame &, bool); void sendRefresh(); void sendRefresh(int); + void sendBulkRefresh(int); void clearFrames(); void setDBCHandler(DBCHandler *); void setInterpetMode(bool); diff --git a/mainwindow.cpp b/mainwindow.cpp index 515aca6..2501026 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -75,11 +75,11 @@ MainWindow::MainWindow(QWidget *parent) : ui->cbSpeed2->addItem(tr("1000000")); ui->cbSpeed2->addItem(tr("33333")); - SerialWorker *worker = new SerialWorker(); + SerialWorker *worker = new SerialWorker(model); worker->moveToThread(&serialWorkerThread); connect(&serialWorkerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &MainWindow::sendSerialPort, worker, &SerialWorker::setSerialPort, Qt::QueuedConnection); - connect(worker, &SerialWorker::receivedFrame, this, &MainWindow::gotFrame, Qt::QueuedConnection); + connect(worker, &SerialWorker::receivedFrames, this, &MainWindow::gotFrames, Qt::QueuedConnection); connect(this, &MainWindow::updateBaudRates, worker, &SerialWorker::updateBaudRates, Qt::QueuedConnection); connect(this, &MainWindow::sendCANFrame, worker, &SerialWorker::sendFrame, Qt::QueuedConnection); connect(worker, &SerialWorker::connectionSuccess, this, &MainWindow::connectionSucceeded, Qt::QueuedConnection); @@ -145,11 +145,12 @@ void MainWindow::updateBaudLabel(int baud0, int baud1) lbStatusBauds.setText(labelText); } -void MainWindow::gotFrame(CANFrame *frame) +//most of the work is handled elsewhere. Need only to update the # of frames +//and maybe auto scroll +void MainWindow::gotFrames() { - //qDebug() << "got frame from serial side. ID was " << frame->ID; - addFrameToDisplay(*frame, true); ui->lbNumFrames->setText(QString::number(model->rowCount())); + if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom(); } void MainWindow::addFrameToDisplay(CANFrame &frame, bool autoRefresh = false) diff --git a/mainwindow.h b/mainwindow.h index caffb26..88fc1f2 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -13,7 +13,7 @@ #include "framesenderwindow.h" #include "dbchandler.h" -#define VERSION 100 +#define VERSION 102 namespace Ui { class MainWindow; @@ -46,7 +46,7 @@ private slots: void connectionSucceeded(int, int); public slots: - void gotFrame(CANFrame *frame); + void gotFrames(); signals: diff --git a/serialworker.cpp b/serialworker.cpp index b4c680e..a356d23 100644 --- a/serialworker.cpp +++ b/serialworker.cpp @@ -4,12 +4,19 @@ #include #include -SerialWorker::SerialWorker(QObject *parent) : QObject(parent) +SerialWorker::SerialWorker(CANFrameModel *model, QObject *parent) : QObject(parent) { serial = NULL; rx_state = IDLE; rx_step = 0; buildFrame = new CANFrame; + canModel = model; + ticker.setInterval(250); //tick four times per second + ticker.setSingleShot(false); //keep ticking + ticker.start(); + gotFrames = 0; + + connect(&ticker, SIGNAL(timeout()), this, SLOT(handleTick())); } SerialWorker::~SerialWorker() @@ -25,6 +32,7 @@ SerialWorker::~SerialWorker() serial->disconnect(); //disconnect all signals delete serial; } + ticker.stop(); } void SerialWorker::setSerialPort(QSerialPortInfo *port) @@ -226,8 +234,10 @@ void SerialWorker::procRXChar(unsigned char c) rx_state = IDLE; rx_step = 0; //qDebug() << "emit from serial handler to main form id: " << buildFrame->ID; - emit receivedFrame(buildFrame); - buildFrame = new CANFrame; + //emit receivedFrame(buildFrame); + canModel->addFrame(*buildFrame, false); + gotFrames++; + //buildFrame = new CANFrame; } break; } @@ -322,3 +332,13 @@ void SerialWorker::procRXChar(unsigned char c) break; } } + +void SerialWorker::handleTick() +{ + if (gotFrames > 0) + { + emit receivedFrames(); //notify interested parties that there are new frames + canModel->sendBulkRefresh(gotFrames); + gotFrames = 0; + } +} diff --git a/serialworker.h b/serialworker.h index 607f995..c8a43a7 100644 --- a/serialworker.h +++ b/serialworker.h @@ -4,7 +4,9 @@ #include #include #include +#include #include "can_structs.h" +#include "canframemodel.h" enum STATE //keep this enum synchronized with the Arduino firmware project { @@ -25,12 +27,12 @@ class SerialWorker : public QObject Q_OBJECT public: - SerialWorker(QObject *parent = 0); + SerialWorker(CANFrameModel *model, QObject *parent = 0); ~SerialWorker(); signals: //we emit signals void error(const QString &); - void receivedFrame(CANFrame *); + void receivedFrames(); //since the last tick we got at least one more frame void connectionSuccess(int, int); void connectionFailure(); void deviceInfo(int, int); @@ -38,6 +40,7 @@ signals: //we emit signals private slots: //we receive things in slots void readSerialData(); void connectionTimeout(); + void handleTick(); public slots: void setSerialPort(QSerialPortInfo*); @@ -49,6 +52,9 @@ private: bool quit; bool connected; QSerialPort *serial; + CANFrameModel *canModel; + QTimer ticker; + int gotFrames; STATE rx_state; int rx_step; CANFrame *buildFrame;