diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,6 +59,7 @@ qt5_wrap_ui(UI_FILES
snapshotview.ui
commandpanel.ui
commandwidget.ui
+ dataformatpanel.ui
)
if (WIN32)
@@ -85,6 +86,7 @@ add_executable(${PROGRAM_NAME} WIN32
commandpanel.cpp
commandwidget.cpp
commandedit.cpp
+ dataformatpanel.cpp
${UI_FILES}
${RES_FILES}
misc/windows_icon.rc
diff --git a/dataformatpanel.cpp b/dataformatpanel.cpp
new file mode 100644
--- /dev/null
+++ b/dataformatpanel.cpp
@@ -0,0 +1,327 @@
+/*
+ Copyright © 2015 Hasan Yavuz Özderya
+
+ This file is part of serialplot.
+
+ serialplot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ serialplot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with serialplot. If not, see .
+*/
+
+#include "dataformatpanel.h"
+#include "ui_dataformatpanel.h"
+
+#include
+
+#include "utils.h"
+#include "floatswap.h"
+
+DataFormatPanel::DataFormatPanel(QSerialPort* port,
+ QList* channelBuffers,
+ QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::DataFormatPanel)
+{
+ ui->setupUi(this);
+
+ serialPort = port;
+ _channelBuffers = channelBuffers;
+ paused = false;
+
+ // setup number format buttons
+ numberFormatButtons.addButton(ui->rbUint8, NumberFormat_uint8);
+ numberFormatButtons.addButton(ui->rbUint16, NumberFormat_uint16);
+ numberFormatButtons.addButton(ui->rbUint32, NumberFormat_uint32);
+ numberFormatButtons.addButton(ui->rbInt8, NumberFormat_int8);
+ numberFormatButtons.addButton(ui->rbInt16, NumberFormat_int16);
+ numberFormatButtons.addButton(ui->rbInt32, NumberFormat_int32);
+ numberFormatButtons.addButton(ui->rbFloat, NumberFormat_float);
+ numberFormatButtons.addButton(ui->rbASCII, NumberFormat_ASCII);
+
+ QObject::connect(
+ &numberFormatButtons, SIGNAL(buttonToggled(int, bool)),
+ this, SLOT(onNumberFormatButtonToggled(int, bool)));
+
+ // init number format
+ selectNumberFormat((NumberFormat) numberFormatButtons.checkedId());
+
+ // setup number of channels spinbox
+ QObject::connect(ui->spNumOfChannels,
+ SELECT::OVERLOAD_OF(&QSpinBox::valueChanged),
+ this, &DataFormatPanel::onNumOfChannelsSP);
+
+ _numOfChannels = ui->spNumOfChannels->value();
+
+ // Init sps (sample per second) counter
+ sampleCount = 0;
+ QObject::connect(&spsTimer, &QTimer::timeout,
+ this, &DataFormatPanel::spsTimerTimeout);
+ spsTimer.start(SPS_UPDATE_TIMEOUT * 1000);
+
+ // Init demo mode
+ demoCount = 0;
+ demoTimer.setInterval(100);
+ QObject::connect(&demoTimer, &QTimer::timeout,
+ this, &DataFormatPanel::demoTimerTimeout);
+}
+
+DataFormatPanel::~DataFormatPanel()
+{
+ delete ui;
+}
+
+void DataFormatPanel::onNumberFormatButtonToggled(int numberFormatId,
+ bool checked)
+{
+ if (checked) selectNumberFormat((NumberFormat) numberFormatId);
+}
+
+void DataFormatPanel::selectNumberFormat(NumberFormat numberFormatId)
+{
+ numberFormat = numberFormatId;
+
+ switch(numberFormat)
+ {
+ case NumberFormat_uint8:
+ sampleSize = 1;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_int8:
+ sampleSize = 1;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_uint16:
+ sampleSize = 2;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_int16:
+ sampleSize = 2;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_uint32:
+ sampleSize = 4;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_int32:
+ sampleSize = 4;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_float:
+ sampleSize = 4;
+ readSample = &DataFormatPanel::readSampleAs;
+ break;
+ case NumberFormat_ASCII:
+ sampleSize = 0; // these two members should not be used
+ readSample = NULL; // in this mode
+ break;
+ }
+
+ if (numberFormat == NumberFormat_ASCII)
+ {
+ QObject::disconnect(serialPort, &QSerialPort::readyRead, 0, 0);
+ QObject::connect(this->serialPort, &QSerialPort::readyRead,
+ this, &DataFormatPanel::onDataReadyASCII);
+ }
+ else
+ {
+ QObject::disconnect(serialPort, &QSerialPort::readyRead, 0, 0);
+ QObject::connect(serialPort, &QSerialPort::readyRead,
+ this, &DataFormatPanel::onDataReady);
+ }
+
+ emit skipByteEnabledChanged(skipByteEnabled());
+}
+
+bool DataFormatPanel::skipByteEnabled()
+{
+ return numberFormat != NumberFormat_ASCII;
+}
+
+unsigned DataFormatPanel::numOfChannels()
+{
+ return _numOfChannels;
+}
+
+void DataFormatPanel::onNumOfChannelsSP(int value)
+{
+ _numOfChannels = value;
+ emit numOfChannelsChanged(value);
+}
+
+void DataFormatPanel::requestSkipByte()
+{
+ skipByteRequested = true;
+}
+
+void DataFormatPanel::pause(bool enabled)
+{
+ paused = enabled;
+}
+
+void DataFormatPanel::enableDemo(bool enabled)
+{
+ if (enabled)
+ {
+ demoTimer.start();
+ }
+ else
+ {
+ demoTimer.stop();
+ }
+}
+
+void DataFormatPanel::spsTimerTimeout()
+{
+ unsigned currentSps = _samplesPerSecond;
+ _samplesPerSecond = sampleCount/SPS_UPDATE_TIMEOUT;
+ if (currentSps != _samplesPerSecond)
+ {
+ emit samplesPerSecondChanged(_samplesPerSecond);
+ }
+ sampleCount = 0;
+}
+
+
+void DataFormatPanel::demoTimerTimeout()
+{
+ const double period = 100;
+ demoCount++;
+ if (demoCount >= 100) demoCount = 0;
+
+ if (!paused)
+ {
+ for (unsigned ci = 0; ci < _numOfChannels; ci++)
+ {
+ // we are calculating the fourier components of square wave
+ double value = 4*sin(2*M_PI*double((ci+1)*demoCount)/period)/((2*(ci+1))*M_PI);
+ addChannelData(ci, &value, 1);
+ }
+ emit dataAdded();
+ }
+}
+
+void DataFormatPanel::onDataReady()
+{
+ // TODO: discard data in the size of packageSize
+ if (paused)
+ {
+ serialPort->clear(QSerialPort::Input);
+ return;
+ }
+
+ // a package is a set of channel data like {CHAN0_SAMPLE, CHAN1_SAMPLE...}
+ int packageSize = sampleSize * _numOfChannels;
+ int bytesAvailable = serialPort->bytesAvailable();
+
+ if (bytesAvailable > 0 && skipByteRequested)
+ {
+ serialPort->read(1);
+ skipByteRequested = false;
+ bytesAvailable--;
+ }
+
+ if (bytesAvailable < packageSize) return;
+
+ int numOfPackagesToRead =
+ (bytesAvailable - (bytesAvailable % packageSize)) / packageSize;
+ double* channelSamples = new double[numOfPackagesToRead*_numOfChannels];
+
+ // TODO: use `for`, it is for this
+ int i = 0;
+ while(i < numOfPackagesToRead)
+ {
+ for (unsigned int ci = 0; ci < _numOfChannels; ci++)
+ {
+ // channelSamples[ci].replace(i, (this->*readSample)());
+ channelSamples[ci*numOfPackagesToRead+i] = (this->*readSample)();
+ }
+ i++;
+ }
+
+ for (unsigned int ci = 0; ci < _numOfChannels; ci++)
+ {
+ addChannelData(ci,
+ channelSamples + ci*numOfPackagesToRead,
+ numOfPackagesToRead);
+ }
+ emit dataAdded();
+
+ delete channelSamples;
+}
+
+void DataFormatPanel::onDataReadyASCII()
+{
+ while(serialPort->canReadLine())
+ {
+ QByteArray line = serialPort->readLine();
+
+ // discard data if paused
+ if (paused)
+ {
+ return;
+ }
+
+ line = line.trimmed();
+ auto separatedValues = line.split(',');
+
+ int numReadChannels; // effective number of channels to read
+ if (separatedValues.length() >= int(_numOfChannels))
+ {
+ numReadChannels = _numOfChannels;
+ }
+ else // there is missing channel data
+ {
+ numReadChannels = separatedValues.length();
+ qWarning() << "Incoming data is missing data for some channels!";
+ }
+
+ // parse read line
+ for (int ci = 0; ci < numReadChannels; ci++)
+ {
+ bool ok;
+ double channelSample = separatedValues[ci].toDouble(&ok);
+ if (ok)
+ {
+ addChannelData(ci, &channelSample, 1);
+ }
+ else
+ {
+ qWarning() << "Data parsing error for channel: " << ci;
+ }
+ }
+ emit dataAdded();
+ }
+}
+
+template double DataFormatPanel::readSampleAs()
+{
+ T data;
+ serialPort->read((char*) &data, sizeof(data));
+
+ if (ui->rbLittleE->isChecked())
+ {
+ data = qFromLittleEndian(data);
+ }
+ else
+ {
+ data = qFromBigEndian(data);
+ }
+
+ return double(data);
+}
+
+void DataFormatPanel::addChannelData(unsigned int channel,
+ double* data, unsigned size)
+{
+ (*_channelBuffers)[channel]->addSamples(data, size);
+ sampleCount += size;
+}
diff --git a/dataformatpanel.h b/dataformatpanel.h
new file mode 100644
--- /dev/null
+++ b/dataformatpanel.h
@@ -0,0 +1,117 @@
+/*
+ Copyright © 2015 Hasan Yavuz Özderya
+
+ This file is part of serialplot.
+
+ serialplot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ serialplot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with serialplot. If not, see .
+*/
+
+#ifndef DATAFORMATPANEL_H
+#define DATAFORMATPANEL_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "framebuffer.h"
+
+namespace Ui {
+class DataFormatPanel;
+}
+
+class DataFormatPanel : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit DataFormatPanel(QSerialPort* port,
+ QList* channelBuffers,
+ QWidget *parent = 0);
+ ~DataFormatPanel();
+
+ unsigned numOfChannels();
+ unsigned samplesPerSecond();
+ bool skipByteEnabled(void); // true for binary formats
+
+public slots:
+ // during next read operation reader will skip 1 byte,
+ // requests are not accumulated
+ void requestSkipByte();
+ void pause(bool);
+ void enableDemo(bool); // demo shouldn't be enabled when port is open
+
+signals:
+ void numOfChannelsChanged(unsigned);
+ void samplesPerSecondChanged(unsigned);
+ void skipByteEnabledChanged(bool);
+ void dataAdded();
+
+private:
+ enum NumberFormat
+ {
+ NumberFormat_uint8,
+ NumberFormat_uint16,
+ NumberFormat_uint32,
+ NumberFormat_int8,
+ NumberFormat_int16,
+ NumberFormat_int32,
+ NumberFormat_float,
+ NumberFormat_ASCII
+ };
+
+ Ui::DataFormatPanel *ui;
+ QButtonGroup numberFormatButtons;
+
+ QSerialPort* serialPort;
+ QList* _channelBuffers;
+
+ unsigned int _numOfChannels;
+ NumberFormat numberFormat;
+ unsigned int sampleSize; // number of bytes in the selected number format
+ bool skipByteRequested;
+ bool paused;
+
+ const int SPS_UPDATE_TIMEOUT = 1; // second
+ unsigned _samplesPerSecond;
+ unsigned int sampleCount;
+ QTimer spsTimer;
+
+ // demo
+ QTimer demoTimer;
+ int demoCount;
+
+ void selectNumberFormat(NumberFormat numberFormatId);
+
+ // points to the readSampleAs function for currently selected number format
+ double (DataFormatPanel::*readSample)();
+
+ // note that serialPort should already have enough bytes present
+ template double readSampleAs();
+
+ // `data` contains i th channels data
+ void addChannelData(unsigned int channel, double* data, unsigned size);
+
+private slots:
+ void onDataReady(); // used with binary number formats
+ void onDataReadyASCII(); // used with ASCII number format
+ void onNumberFormatButtonToggled(int numberFormatId, bool checked);
+ void onNumOfChannelsSP(int value);
+ void spsTimerTimeout();
+ void demoTimerTimeout();
+};
+
+#endif // DATAFORMATPANEL_H
diff --git a/dataformatpanel.ui b/dataformatpanel.ui
new file mode 100644
--- /dev/null
+++ b/dataformatpanel.ui
@@ -0,0 +1,244 @@
+
+
+ DataFormatPanel
+
+
+
+ 0
+ 0
+ 607
+ 181
+
+
+
+ Data Format
+
+
+ -
+
+
-
+
+
+ Number Of Channels:
+
+
+
+ -
+
+
+
+ 60
+ 0
+
+
+
+ false
+
+
+ 1
+
+
+ 32
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Number Format:
+
+
+
-
+
+
+ unsigned 4 bytes integer
+
+
+ uint32
+
+
+
+ -
+
+
+ signed 1 byte integer
+
+
+ int8
+
+
+
+ -
+
+
+ unsigned 1 byte integer
+
+
+ uint8
+
+
+ true
+
+
+
+ -
+
+
+ Comma Separated Values
+
+
+ ASCII(CSV)
+
+
+
+ -
+
+
+ signed 2 bytes integer
+
+
+ int16
+
+
+
+ -
+
+
+ signed 4 bytes integer
+
+
+ int32
+
+
+
+ -
+
+
+ 4 bytes floating point number
+
+
+ float
+
+
+
+ -
+
+
+ unsigned 2 bytes integer
+
+
+ uint16
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 1
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Byte Order:
+
+
+
-
+
+
+ least significant byte first
+
+
+ Little Endian
+
+
+ true
+
+
+
+ -
+
+
+ most significant byte first
+
+
+ Big Endian
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 1
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::MinimumExpanding
+
+
+
+ 37
+ 20
+
+
+
+
+
+
+
+
+
diff --git a/mainwindow.cpp b/mainwindow.cpp
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -25,7 +25,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -35,7 +34,6 @@
#include "utils.h"
#include "version.h"
-#include "floatswap.h"
#if defined(Q_OS_WIN) && defined(QT_STATIC)
#include
@@ -56,10 +54,12 @@ MainWindow::MainWindow(QWidget *parent)
aboutDialog(this),
portControl(&serialPort),
commandPanel(&serialPort),
+ dataFormatPanel(&serialPort, &channelBuffers),
snapshotMan(this, &channelBuffers)
{
ui->setupUi(this);
ui->tabWidget->insertTab(0, &portControl, "Port");
+ ui->tabWidget->insertTab(1, &dataFormatPanel, "Data Format");
ui->tabWidget->insertTab(3, &commandPanel, "Commands");
ui->tabWidget->setCurrentIndex(0);
addToolBar(portControl.toolBar());
@@ -94,7 +94,7 @@ MainWindow::MainWindow(QWidget *parent)
this, &MainWindow::onPortToggled);
QObject::connect(&portControl, &PortControl::skipByteRequested,
- this, &MainWindow::skipByte);
+ &dataFormatPanel, &DataFormatPanel::requestSkipByte);
QObject::connect(ui->spNumOfSamples, SELECT::OVERLOAD_OF(&QSpinBox::valueChanged),
this, &MainWindow::onNumOfSamplesChanged);
@@ -114,24 +114,6 @@ MainWindow::MainWindow(QWidget *parent)
QObject::connect(snapshotMan.takeSnapshotAction(), &QAction::triggered,
ui->plot, &Plot::flashSnapshotOverlay);
- // setup number of channels spinbox
- QObject::connect(ui->spNumOfChannels,
- SELECT::OVERLOAD_OF(&QSpinBox::valueChanged),
- this, &MainWindow::onNumOfChannelsChanged);
-
- // setup number format buttons
- numberFormatButtons.addButton(ui->rbUint8, NumberFormat_uint8);
- numberFormatButtons.addButton(ui->rbUint16, NumberFormat_uint16);
- numberFormatButtons.addButton(ui->rbUint32, NumberFormat_uint32);
- numberFormatButtons.addButton(ui->rbInt8, NumberFormat_int8);
- numberFormatButtons.addButton(ui->rbInt16, NumberFormat_int16);
- numberFormatButtons.addButton(ui->rbInt32, NumberFormat_int32);
- numberFormatButtons.addButton(ui->rbFloat, NumberFormat_float);
- numberFormatButtons.addButton(ui->rbASCII, NumberFormat_ASCII);
-
- QObject::connect(&numberFormatButtons, SIGNAL(buttonToggled(int, bool)),
- this, SLOT(onNumberFormatButtonToggled(int, bool)));
-
// init port signals
QObject::connect(&(this->serialPort), SIGNAL(error(QSerialPort::SerialPortError)),
this, SLOT(onPortError(QSerialPort::SerialPortError)));
@@ -143,10 +125,21 @@ MainWindow::MainWindow(QWidget *parent)
ui->spYmax->setRange((-1) * std::numeric_limits::max(),
std::numeric_limits::max());
- // init data arrays and plot
+ // init data format and reader
+ QObject::connect(&dataFormatPanel, &DataFormatPanel::dataAdded,
+ ui->plot, &QwtPlot::replot);
+
+ QObject::connect(ui->actionPause, &QAction::triggered,
+ &dataFormatPanel, &DataFormatPanel::pause);
+ // init data arrays and plot
numOfSamples = ui->spNumOfSamples->value();
- numOfChannels = ui->spNumOfChannels->value();
+ unsigned numOfChannels = dataFormatPanel.numOfChannels();
+
+ QObject::connect(&dataFormatPanel,
+ &DataFormatPanel::numOfChannelsChanged,
+ this,
+ &MainWindow::onNumOfChannelsChanged);
// init channel data and curve list
for (unsigned int i = 0; i < numOfChannels; i++)
@@ -187,30 +180,15 @@ MainWindow::MainWindow(QWidget *parent)
QObject::connect(ui->cbRangePresets, SIGNAL(activated(int)),
this, SLOT(onRangeSelected()));
- // init number format
- if (numberFormatButtons.checkedId() >= 0)
- {
- selectNumberFormat((NumberFormat) numberFormatButtons.checkedId());
- }
- else
- {
- selectNumberFormat(NumberFormat_uint8);
- }
-
// Init sps (sample per second) counter
- sampleCount = 0;
spsLabel.setText("0sps");
spsLabel.setToolTip("samples per second (total of all channels)");
ui->statusBar->addPermanentWidget(&spsLabel);
- spsTimer.start(SPS_UPDATE_TIMEOUT * 1000);
- QObject::connect(&spsTimer, &QTimer::timeout,
- this, &MainWindow::spsTimerTimeout);
+ QObject::connect(&dataFormatPanel,
+ &DataFormatPanel::samplesPerSecondChanged,
+ this, &MainWindow::onSpsChanged);
- // Init demo mode
- demoCount = 0;
- demoTimer.setInterval(100);
- QObject::connect(&demoTimer, &QTimer::timeout,
- this, &MainWindow::demoTimerTimeout);
+ // init demo
QObject::connect(ui->actionDemoMode, &QAction::toggled,
this, &MainWindow::enableDemo);
@@ -224,7 +202,6 @@ MainWindow::MainWindow(QWidget *parent)
demoIndicator.hide();
demoIndicator.attach(ui->plot);
}
-
}
MainWindow::~MainWindow()
@@ -265,97 +242,6 @@ void MainWindow::onPortToggled(bool open
ui->actionDemoMode->setEnabled(!open);
}
-void MainWindow::onDataReady()
-{
- if (ui->actionPause->isChecked())
- {
- serialPort.clear(QSerialPort::Input);
- return;
- }
-
- // a package is a set of channel data like {CHAN0_SAMPLE, CHAN1_SAMPLE...}
- int packageSize = sampleSize * numOfChannels;
- int bytesAvailable = serialPort.bytesAvailable();
-
- if (bytesAvailable > 0 && skipByteRequested)
- {
- serialPort.read(1);
- skipByteRequested = false;
- bytesAvailable--;
- }
-
- if (bytesAvailable < packageSize) return;
-
- int numOfPackagesToRead =
- (bytesAvailable - (bytesAvailable % packageSize)) / packageSize;
- double* channelSamples = new double[numOfPackagesToRead*numOfChannels];
-
- int i = 0;
- while(i < numOfPackagesToRead)
- {
- for (unsigned int ci = 0; ci < numOfChannels; ci++)
- {
- // channelSamples[ci].replace(i, (this->*readSample)());
- channelSamples[ci*numOfPackagesToRead+i] = (this->*readSample)();
- }
- i++;
- }
-
- for (unsigned int ci = 0; ci < numOfChannels; ci++)
- {
- addChannelData(ci,
- channelSamples + ci*numOfPackagesToRead,
- numOfPackagesToRead);
- }
- ui->plot->replot();
-
- delete channelSamples;
-}
-
-void MainWindow::onDataReadyASCII()
-{
- while(serialPort.canReadLine())
- {
- QByteArray line = serialPort.readLine();
-
- // discard data if paused
- if (ui->actionPause->isChecked())
- {
- return;
- }
-
- line = line.trimmed();
- auto separatedValues = line.split(',');
-
- int numReadChannels; // effective number of channels to read
- if (separatedValues.length() >= int(numOfChannels))
- {
- numReadChannels = numOfChannels;
- }
- else // there is missing channel data
- {
- numReadChannels = separatedValues.length();
- qWarning() << "Incoming data is missing data for some channels!";
- }
-
- // parse read line
- for (int ci = 0; ci < numReadChannels; ci++)
- {
- bool ok;
- double channelSample = separatedValues[ci].toDouble(&ok);
- if (ok)
- {
- addChannelData(ci, &channelSample, 1);
- }
- else
- {
- qWarning() << "Data parsing error for channel: " << ci;
- }
- }
- ui->plot->replot();
- }
-}
-
void MainWindow::onPortError(QSerialPort::SerialPortError error)
{
switch(error)
@@ -414,20 +300,9 @@ required privileges or device is already
}
}
-void MainWindow::skipByte()
-{
- skipByteRequested = true;
-}
-
-void MainWindow::addChannelData(unsigned int channel, double* data, unsigned size)
-{
- channelBuffers[channel]->addSamples(data, size);
- sampleCount += size;
-}
-
void MainWindow::clearPlot()
{
- for (unsigned int ci = 0; ci < numOfChannels; ci++)
+ for (int ci = 0; ci < channelBuffers.size(); ci++)
{
channelBuffers[ci]->clear();
}
@@ -438,7 +313,7 @@ void MainWindow::onNumOfSamplesChanged(i
{
numOfSamples = value;
- for (unsigned int ci = 0; ci < numOfChannels; ci++)
+ for (int ci = 0; ci < channelBuffers.size(); ci++)
{
channelBuffers[ci]->resize(numOfSamples);
}
@@ -446,10 +321,10 @@ void MainWindow::onNumOfSamplesChanged(i
ui->plot->replot();
}
-void MainWindow::onNumOfChannelsChanged(int value)
+void MainWindow::onNumOfChannelsChanged(unsigned value)
{
- unsigned int oldNum = this->numOfChannels;
- this->numOfChannels = value;
+ unsigned int oldNum = channelBuffers.size();
+ unsigned numOfChannels = value;
if (numOfChannels > oldNum)
{
@@ -509,82 +384,9 @@ void MainWindow::onRangeSelected()
ui->cbAutoScale->setChecked(false);
}
-void MainWindow::onNumberFormatButtonToggled(int numberFormatId, bool checked)
-{
- if (checked) selectNumberFormat((NumberFormat) numberFormatId);
-}
-
-void MainWindow::selectNumberFormat(NumberFormat numberFormatId)
+void MainWindow::onSpsChanged(unsigned sps)
{
- numberFormat = numberFormatId;
-
- switch(numberFormat)
- {
- case NumberFormat_uint8:
- sampleSize = 1;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_int8:
- sampleSize = 1;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_uint16:
- sampleSize = 2;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_int16:
- sampleSize = 2;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_uint32:
- sampleSize = 4;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_int32:
- sampleSize = 4;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_float:
- sampleSize = 4;
- readSample = &MainWindow::readSampleAs;
- break;
- case NumberFormat_ASCII:
- sampleSize = 0; // these two members should not be used
- readSample = NULL; // in this mode
- break;
- }
-
- if (numberFormat == NumberFormat_ASCII)
- {
- QObject::disconnect(&(this->serialPort), &QSerialPort::readyRead, 0, 0);
- QObject::connect(&(this->serialPort), &QSerialPort::readyRead,
- this, &MainWindow::onDataReadyASCII);
- portControl.enableSkipByte();
- }
- else
- {
- QObject::disconnect(&(this->serialPort), &QSerialPort::readyRead, 0, 0);
- QObject::connect(&(this->serialPort), &QSerialPort::readyRead,
- this, &MainWindow::onDataReady);
- portControl.enableSkipByte(false);
- }
-}
-
-template double MainWindow::readSampleAs()
-{
- T data;
- this->serialPort.read((char*) &data, sizeof(data));
-
- if (ui->rbLittleE->isChecked())
- {
- data = qFromLittleEndian(data);
- }
- else
- {
- data = qFromBigEndian(data);
- }
-
- return double(data);
+ spsLabel.setText(QString::number(sps) + "sps");
}
bool MainWindow::isDemoRunning()
@@ -592,37 +394,13 @@ bool MainWindow::isDemoRunning()
return ui->actionDemoMode->isChecked();
}
-void MainWindow::spsTimerTimeout()
-{
- spsLabel.setText(QString::number(sampleCount/SPS_UPDATE_TIMEOUT) + "sps");
- sampleCount = 0;
-}
-
-void MainWindow::demoTimerTimeout()
-{
- const double period = 100;
- demoCount++;
- if (demoCount >= 100) demoCount = 0;
-
- if (!ui->actionPause->isChecked())
- {
- for (unsigned int ci = 0; ci < numOfChannels; ci++)
- {
- // we are calculating the fourier components of square wave
- double value = 4*sin(2*M_PI*double((ci+1)*demoCount)/period)/((2*(ci+1))*M_PI);
- addChannelData(ci, &value, 1);
- }
- ui->plot->replot();
- }
-}
-
void MainWindow::enableDemo(bool enabled)
{
if (enabled)
{
if (!serialPort.isOpen())
{
- demoTimer.start();
+ dataFormatPanel.enableDemo(true);
ui->actionDemoMode->setChecked(true);
demoIndicator.show();
ui->plot->replot();
@@ -634,7 +412,7 @@ void MainWindow::enableDemo(bool enabled
}
else
{
- demoTimer.stop();
+ dataFormatPanel.enableDemo(false);
ui->actionDemoMode->setChecked(false);
demoIndicator.hide();
ui->plot->replot();
@@ -659,6 +437,7 @@ void MainWindow::onExportCsv()
{
QTextStream fileStream(&file);
+ unsigned numOfChannels = channelBuffers.size();
for (unsigned int ci = 0; ci < numOfChannels; ci++)
{
fileStream << "Channel " << ci;
diff --git a/mainwindow.h b/mainwindow.h
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -36,6 +36,7 @@
#include "portcontrol.h"
#include "commandpanel.h"
+#include "dataformatpanel.h"
#include "ui_about_dialog.h"
#include "framebuffer.h"
#include "snapshotmanager.h"
@@ -56,20 +57,7 @@ public:
const QString &msg);
private:
- enum NumberFormat
- {
- NumberFormat_uint8,
- NumberFormat_uint16,
- NumberFormat_uint32,
- NumberFormat_int8,
- NumberFormat_int16,
- NumberFormat_int32,
- NumberFormat_float,
- NumberFormat_ASCII
- };
-
Ui::MainWindow *ui;
- QButtonGroup numberFormatButtons;
QDialog aboutDialog;
void setupAboutDialog();
@@ -78,61 +66,35 @@ private:
PortControl portControl;
unsigned int numOfSamples;
- unsigned int numOfChannels;
QList curves;
// Note: FrameBuffer s are owned by their respective QwtPlotCurve s.
QList channelBuffers;
- // `data` contains i th channels data
- void addChannelData(unsigned int channel, double* data, unsigned size);
-
- NumberFormat numberFormat;
- unsigned int sampleSize; // number of bytes in the selected number format
- double (MainWindow::*readSample)();
-
- // note that serialPort should already have enough bytes present
- template double readSampleAs();
-
- bool skipByteRequested;
-
- const int SPS_UPDATE_TIMEOUT = 1; // second
QLabel spsLabel;
- unsigned int sampleCount;
- QTimer spsTimer;
CommandPanel commandPanel;
+ DataFormatPanel dataFormatPanel;
SnapshotManager snapshotMan;
- // demo
- QTimer demoTimer;
- int demoCount;
+ QwtPlotTextLabel demoIndicator;
bool isDemoRunning();
- QwtPlotTextLabel demoIndicator;
private slots:
void onPortToggled(bool open);
- void onDataReady(); // used with binary number formats
- void onDataReadyASCII(); // used with ASCII number format
void onPortError(QSerialPort::SerialPortError error);
- void skipByte();
-
void onNumOfSamplesChanged(int value);
void onAutoScaleChecked(bool checked);
void onYScaleChanged();
void onRangeSelected();
-
- void onNumOfChannelsChanged(int value);
- void onNumberFormatButtonToggled(int numberFormatId, bool checked);
- void selectNumberFormat(NumberFormat numberFormatId);
+ void onNumOfChannelsChanged(unsigned value);
void clearPlot();
- void spsTimerTimeout();
+ void onSpsChanged(unsigned sps);
- void demoTimerTimeout();
void enableDemo(bool enabled);
void onExportCsv();
diff --git a/mainwindow.ui b/mainwindow.ui
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -51,236 +51,6 @@
false
-
-
- Data Format
-
-
- -
-
-
-
-
-
- Number Of Channels:
-
-
-
- -
-
-
-
- 60
- 0
-
-
-
- false
-
-
- 1
-
-
- 32
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- -
-
-
- 0
-
-
-
-
-
- Number Format:
-
-
-
-
-
-
- unsigned 4 bytes integer
-
-
- uint32
-
-
-
- -
-
-
- signed 1 byte integer
-
-
- int8
-
-
-
- -
-
-
- unsigned 1 byte integer
-
-
- uint8
-
-
- true
-
-
-
- -
-
-
- Comma Separated Values
-
-
- ASCII(CSV)
-
-
-
- -
-
-
- signed 2 bytes integer
-
-
- int16
-
-
-
- -
-
-
- signed 4 bytes integer
-
-
- int32
-
-
-
- -
-
-
- 4 bytes floating point number
-
-
- float
-
-
-
- -
-
-
- unsigned 2 bytes integer
-
-
- uint16
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 1
-
-
-
-
-
-
- -
-
-
- 0
-
-
-
-
-
-
- 0
- 0
-
-
-
- Byte Order:
-
-
-
-
-
-
- least significant byte first
-
-
- Little Endian
-
-
- true
-
-
-
- -
-
-
- most significant byte first
-
-
- Big Endian
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 1
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::MinimumExpanding
-
-
-
- 1
- 20
-
-
-
-
-
-
Plot
diff --git a/serialplot.pro b/serialplot.pro
--- a/serialplot.pro
+++ b/serialplot.pro
@@ -49,7 +49,8 @@ SOURCES += main.cpp\
plotsnapshotoverlay.cpp \
commandpanel.cpp \
commandwidget.cpp \
- commandedit.cpp
+ commandedit.cpp \
+ dataformatpanel.cpp
HEADERS += mainwindow.h \
utils.h \
@@ -68,14 +69,16 @@ HEADERS += mainwindow.h \
plotsnapshotoverlay.h \
commandpanel.h \
commandwidget.h \
- commandedit.h
+ commandedit.h \
+ dataformatpanel.h
FORMS += mainwindow.ui \
about_dialog.ui \
portcontrol.ui \
snapshotview.ui \
commandpanel.ui \
- commandwidget.ui
+ commandwidget.ui \
+ dataformatpanel.ui
INCLUDEPATH += qmake/