Changeset - a31b6ac829d6
[Not reviewed]
Merge default
0 18 2
Hasan Yavuz ÖZDERYA - 6 years ago 2019-04-17 15:36:18
hy@ozderya.net
Merge with reader-stat
20 files changed with 288 insertions and 49 deletions:
0 comments (0 inline, 0 general)
CMakeLists.txt
Show inline comments
 
@@ -136,6 +136,7 @@ add_executable(${PROGRAM_NAME} WIN32
 
  src/samplecounter.cpp
 
  src/ledwidget.cpp
 
  src/datatextview.cpp
 
  src/bpslabel.cpp
 
  misc/windows_icon.rc
 
  ${UI_FILES}
 
  ${RES_FILES}
serialplot.pro
Show inline comments
 
@@ -72,7 +72,8 @@ SOURCES += \
 
    src/updatechecker.cpp \
 
    src/updatecheckdialog.cpp \
 
    src/demoreadersettings.cpp \
 
    src/datatextview.cpp
 
    src/datatextview.cpp \
 
    src/bpslabel.cpp
 

	
 
HEADERS += \
 
    src/mainwindow.h \
 
@@ -116,7 +117,8 @@ HEADERS += \
 
    src/updatechecker.h \
 
    src/updatecheckdialog.h \
 
    src/demoreadersettings.h \
 
    src/datatextview.h
 
    src/datatextview.h \
 
    src/bpslabel.h
 

	
 
FORMS += \
 
    src/mainwindow.ui \
src/abstractreader.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -23,6 +23,7 @@ AbstractReader::AbstractReader(QIODevice
 
    QObject(parent)
 
{
 
    _device = device;
 
    bytesRead = 0;
 
}
 

	
 
void AbstractReader::pause(bool enabled)
 
@@ -43,3 +44,15 @@ void AbstractReader::enable(bool enabled
 
        disconnectSinks();
 
    }
 
}
 

	
 
void AbstractReader::onDataReady()
 
{
 
    bytesRead += readData();
 
}
 

	
 
unsigned AbstractReader::getBytesRead()
 
{
 
    unsigned r = bytesRead;
 
    bytesRead = 0;
 
    return r;
 
}
src/abstractreader.h
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -49,6 +49,9 @@ public:
 
    /// None of the current readers support X channel at the moment
 
    bool hasX() const final { return false; };
 

	
 
    /// Read and 'zero' the byte counter
 
    unsigned getBytesRead();
 

	
 
signals:
 
    // TODO: should we keep this?
 
    void numOfChannelsChanged(unsigned);
 
@@ -63,12 +66,25 @@ public slots:
 
    void pause(bool enabled);
 

	
 
protected:
 
    /// Reader should read from this device in `readData()` function.
 
    QIODevice* _device;
 

	
 
    /// Reader should check this variable to determine if reading is
 
    /// paused in `readData()`
 
    bool paused;
 

	
 
protected slots:
 
    /// all derived readers has to override this function
 
    virtual void onDataReady() = 0;
 
    /**
 
     * Called when `readyRead` is signaled by the device. This is
 
     * where the implementors should read the data and return the
 
     * exact number of bytes read from the device.
 
     */
 
    virtual unsigned readData() = 0;
 

	
 
private:
 
    unsigned bytesRead;
 

	
 
private slots:
 
    void onDataReady();
 
};
 

	
 
#endif // ABSTRACTREADER_H
src/asciireader.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -70,21 +70,20 @@ void AsciiReader::enable(bool enabled)
 
    if (enabled)
 
    {
 
        firstReadAfterEnable = true;
 
        QObject::connect(_device, &QIODevice::readyRead,
 
                         this, &AsciiReader::onDataReady);
 
    }
 
    else
 
    {
 
        QObject::disconnect(_device, 0, this, 0);
 
        disconnectSinks();
 
    }
 

	
 
    AbstractReader::enable(enabled);
 
}
 

	
 
void AsciiReader::onDataReady()
 
unsigned AsciiReader::readData()
 
{
 
    unsigned numBytesRead = 0;
 

	
 
    while(_device->canReadLine())
 
    {
 
        QString line = QString(_device->readLine());
 
        QByteArray bytes = _device->readLine();
 
        QString line = QString(bytes);
 
        numBytesRead += bytes.size();
 

	
 
        // discard only once when we just started reading
 
        if (firstReadAfterEnable)
 
@@ -130,6 +129,8 @@ void AsciiReader::onDataReady()
 
            delete samples;
 
        }
 
    }
 

	
 
    return numBytesRead;
 
}
 

	
 
SamplePack* AsciiReader::parseLine(const QString& line) const
src/asciireader.h
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -50,8 +50,10 @@ private:
 

	
 
    bool firstReadAfterEnable = false;
 

	
 
    unsigned readData() override;
 

	
 
private slots:
 
    void onDataReady() override;
 

	
 
    /**
 
     * Parses given line and returns sample pack.
 
     *
src/binarystreamreader.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -107,50 +107,58 @@ void BinaryStreamReader::onNumOfChannels
 
    emit numOfChannelsChanged(value);
 
}
 

	
 
void BinaryStreamReader::onDataReady()
 
unsigned BinaryStreamReader::readData()
 
{
 
    // a package is a set of channel data like {CHAN0_SAMPLE, CHAN1_SAMPLE...}
 
    int packageSize = sampleSize * _numChannels;
 
    int bytesAvailable = _device->bytesAvailable();
 
    unsigned packageSize = sampleSize * _numChannels;
 
    unsigned bytesAvailable = _device->bytesAvailable();
 
    unsigned totalRead = 0;
 

	
 
    // skip 1 byte if requested
 
    if (skipByteRequested && bytesAvailable > 0)
 
    {
 
        _device->read(1);
 
        totalRead++;
 
        skipByteRequested = false;
 
        bytesAvailable--;
 
    }
 

	
 
    // skip 1 sample (channel) if requested
 
    if (skipSampleRequested && bytesAvailable >= (int) sampleSize)
 
    if (skipSampleRequested && bytesAvailable >= sampleSize)
 
    {
 
        _device->read(sampleSize);
 
        totalRead += sampleSize;
 
        skipSampleRequested = false;
 
        bytesAvailable -= sampleSize;
 
    }
 

	
 
    if (bytesAvailable < packageSize) return;
 
    if (bytesAvailable < packageSize) return totalRead;
 

	
 
    int numOfPackagesToRead =
 
    unsigned numOfPackagesToRead =
 
        (bytesAvailable - (bytesAvailable % packageSize)) / packageSize;
 
    unsigned numBytesToRead = numOfPackagesToRead * packageSize;
 

	
 
    totalRead += numBytesToRead;
 

	
 
    if (paused)
 
    {
 
        // read and discard data
 
        _device->read(numOfPackagesToRead*packageSize);
 
        return;
 
        _device->read(numBytesToRead);
 
        return totalRead;
 
    }
 

	
 
    // actual reading
 
    SamplePack samples(numOfPackagesToRead, _numChannels);
 
    for (int i = 0; i < numOfPackagesToRead; i++)
 
    for (unsigned i = 0; i < numOfPackagesToRead; i++)
 
    {
 
        for (unsigned int ci = 0; ci < _numChannels; ci++)
 
        for (unsigned ci = 0; ci < _numChannels; ci++)
 
        {
 
            samples.data(ci)[i] = (this->*readSample)();
 
        }
 
    }
 
    feedOut(samples);
 

	
 
    return totalRead;
 
}
 

	
 
template<typename T> double BinaryStreamReader::readSampleAs()
src/binarystreamreader.h
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -60,10 +60,11 @@ private:
 
     */
 
    template<typename T> double readSampleAs();
 

	
 
    unsigned readData() override;
 

	
 
private slots:
 
    void onNumberFormatChanged(NumberFormat numberFormat);
 
    void onNumOfChannelsChanged(unsigned value);
 
    void onDataReady() override;
 
};
 

	
 
#endif // BINARYSTREAMREADER_H
src/bpslabel.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2019 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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "bpslabel.h"
 

	
 
const char* BPS_TOOLTIP = "bits per second";
 
const char* BPS_TOOLTIP_ERR = "Maximum baud rate may be reached!";
 

	
 
BPSLabel::BPSLabel(PortControl* portControl,
 
                   DataFormatPanel* dataFormatPanel,
 
                   QWidget *parent) :
 
    QLabel(parent)
 
{
 
    _portControl = portControl;
 
    _dataFormatPanel = dataFormatPanel;
 
    prevBytesRead = 0;
 

	
 
    setText("0bps");
 
    setToolTip(tr(BPS_TOOLTIP));
 

	
 
    connect(&bpsTimer, &QTimer::timeout,
 
            this, &BPSLabel::onBpsTimeout);
 

	
 
    connect(portControl, &PortControl::portToggled,
 
            this, &BPSLabel::onPortToggled);
 
}
 

	
 
void BPSLabel::onBpsTimeout()
 
{
 
    uint64_t curBytesRead = _dataFormatPanel->bytesRead();
 
    uint64_t bytesRead = curBytesRead - prevBytesRead;
 
    prevBytesRead = curBytesRead;
 

	
 
    unsigned bits = bytesRead * 8;
 
    unsigned maxBps = _portControl->maxBitRate();
 
    QString str;
 
    if (bits >= maxBps)
 
    {
 
        // TODO: an icon for bps warning
 
        str = QString(tr("!%1/%2bps")).arg(bits).arg(maxBps);
 
        setToolTip(tr(BPS_TOOLTIP_ERR));
 
    }
 
    else
 
    {
 
        str = QString(tr("%1bps")).arg(bits);
 
        setToolTip(tr(BPS_TOOLTIP));
 
    }
 
    setText(str);
 
}
 

	
 
void BPSLabel::onPortToggled(bool open)
 
{
 
    if (open)
 
    {
 
        bpsTimer.start(1000);
 
    }
 
    else
 
    {
 
        bpsTimer.stop();
 
        // if not cleared last displayed value is stuck
 
        setText("0bps");
 
        setToolTip(tr(BPS_TOOLTIP));
 
    }
 
}
src/bpslabel.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2019 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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#ifndef BPSLABEL_H
 
#define BPSLABEL_H
 

	
 
#include <QLabel>
 
#include <QTimer>
 

	
 
#include "portcontrol.h"
 
#include "dataformatpanel.h"
 

	
 
/**
 
 * Displays bits per second read from device.
 
 *
 
 * Displays a warning if maximum bit rate is reached.
 
 */
 
class BPSLabel : public QLabel
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit BPSLabel(PortControl* portControl,
 
                      DataFormatPanel* dataFormatPanel,
 
                      QWidget *parent = 0);
 

	
 
private:
 
    PortControl* _portControl;
 
    DataFormatPanel* _dataFormatPanel;
 
    QTimer bpsTimer;
 

	
 
    uint64_t prevBytesRead;
 

	
 
private slots:
 
    void onBpsTimeout();
 
    void onPortToggled(bool open);
 
};
 

	
 
#endif // BPSLABEL_H
src/dataformatpanel.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -39,6 +39,7 @@ DataFormatPanel::DataFormatPanel(QSerial
 
    serialPort = port;
 
    paused = false;
 
    readerBeforeDemo = nullptr;
 
    _bytesRead = 0;
 

	
 
    // initalize default reader
 
    currentReader = &bsReader;
 
@@ -130,6 +131,12 @@ void DataFormatPanel::selectReader(Abstr
 
    emit sourceChanged(currentReader);
 
}
 

	
 
uint64_t DataFormatPanel::bytesRead()
 
{
 
    _bytesRead += currentReader->getBytesRead();
 
    return _bytesRead;
 
}
 

	
 
void DataFormatPanel::saveSettings(QSettings* settings)
 
{
 
    settings->beginGroup(SettingGroup_DataFormat);
src/dataformatpanel.h
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -20,9 +20,9 @@
 
#ifndef DATAFORMATPANEL_H
 
#define DATAFORMATPANEL_H
 

	
 
#include <stdint.h>
 
#include <QWidget>
 
#include <QButtonGroup>
 
#include <QTimer>
 
#include <QSerialPort>
 
#include <QList>
 
#include <QSettings>
 
@@ -50,6 +50,8 @@ public:
 
    unsigned numChannels() const;
 
    /// Returns active source (reader)
 
    Source* activeSource();
 
    /// Returns total number of bytes read
 
    uint64_t bytesRead();
 
    /// Stores data format panel settings into a `QSettings`
 
    void saveSettings(QSettings* settings);
 
    /// Loads data format panel settings from a `QSettings`.
 
@@ -77,6 +79,7 @@ private:
 
    void selectReader(AbstractReader* reader);
 

	
 
    bool paused;
 
    uint64_t _bytesRead;
 

	
 
    DemoReader demoReader;
 
    AbstractReader* readerBeforeDemo;
src/demoreader.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -53,8 +53,9 @@ void DemoReader::enable(bool enabled)
 
    else
 
    {
 
        timer.stop();
 
        disconnectSinks();
 
    }
 

	
 
    AbstractReader::enable(enabled);
 
}
 

	
 
unsigned DemoReader::numChannels() const
 
@@ -91,7 +92,8 @@ void DemoReader::onNumChannelsChanged(un
 
    updateNumChannels();
 
}
 

	
 
void DemoReader::onDataReady()
 
unsigned DemoReader::readData()
 
{
 
    // intentionally empty, required by AbstractReader
 
    return 0;
 
}
src/demoreader.h
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -55,10 +55,11 @@ private:
 
    QTimer timer;
 
    int count;
 

	
 
    unsigned readData() override;
 

	
 
private slots:
 
    void demoTimerTimeout();
 
    void onNumChannelsChanged(unsigned value);
 
    void onDataReady() override;
 
};
 

	
 
#endif // DEMOREADER_H
src/framedreader.cpp
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -184,9 +184,11 @@ void FramedReader::onFrameSizeChanged(un
 
    reset();
 
}
 

	
 
void FramedReader::onDataReady()
 
unsigned FramedReader::readData()
 
{
 
    if (settingsInvalid) return;
 
    unsigned numBytesRead = 0;
 

	
 
    if (settingsInvalid) return numBytesRead;
 

	
 
    // loop until we run out of bytes or more bytes is required
 
    unsigned bytesAvailable;
 
@@ -196,6 +198,7 @@ void FramedReader::onDataReady()
 
        {
 
            char c;
 
            _device->getChar(&c);
 
            numBytesRead++;
 
            if (c == syncWord[sync_i]) // correct sync byte?
 
            {
 
                sync_i++;
 
@@ -213,6 +216,7 @@ void FramedReader::onDataReady()
 
        {
 
            frameSize = 0;
 
            _device->getChar((char*) &frameSize);
 
            numBytesRead++;
 

	
 
            if (frameSize == 0) // check size
 
            {
 
@@ -242,10 +246,13 @@ void FramedReader::onDataReady()
 
            else // read data bytes and checksum
 
            {
 
                readFrameDataAndCheck();
 
                numBytesRead += checksumEnabled ? frameSize+1 : frameSize;
 
                reset();
 
            }
 
        }
 
    }
 

	
 
    return numBytesRead;
 
}
 

	
 
void FramedReader::reset()
 
@@ -263,7 +270,7 @@ void FramedReader::readFrameDataAndCheck
 
    // if paused just read and waste data
 
    if (paused)
 
    {
 
        _device->read((checksumEnabled ? frameSize+1 : frameSize));
 
        _device->read(checksumEnabled ? frameSize+1 : frameSize);
 
        return;
 
    }
 

	
src/framedreader.h
Show inline comments
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -79,8 +79,9 @@ private:
 
    /// @note should be called only if there are enough bytes on device
 
    void readFrameDataAndCheck();
 

	
 
    unsigned readData() override;
 

	
 
private slots:
 
    void onDataReady() override;
 

	
 
    void onNumberFormatChanged(NumberFormat numberFormat);
 
    void onNumOfChannelsChanged(unsigned value);
src/mainwindow.cpp
Show inline comments
 
@@ -73,7 +73,8 @@ MainWindow::MainWindow(QWidget *parent) 
 
    dataFormatPanel(&serialPort),
 
    recordPanel(&stream),
 
    textView(&stream),
 
    updateCheckDialog(this)
 
    updateCheckDialog(this),
 
    bpsLabel(&portControl, &dataFormatPanel, this)
 
{
 
    ui->setupUi(this);
 

	
 
@@ -234,13 +235,21 @@ MainWindow::MainWindow(QWidget *parent) 
 
    plotMan->setNumOfSamples(numOfSamples);
 
    plotMan->setPlotWidth(plotControlPanel.plotWidth());
 

	
 
    // init bps (bits per second) counter
 
    ui->statusBar->addPermanentWidget(&bpsLabel);
 

	
 
    // Init sps (sample per second) counter
 
    spsLabel.setText("0sps");
 
    spsLabel.setToolTip("samples per second (per channel)");
 
    spsLabel.setToolTip(tr("samples per second (per channel)"));
 
    ui->statusBar->addPermanentWidget(&spsLabel);
 
    connect(&sampleCounter, &SampleCounter::spsChanged,
 
            this, &MainWindow::onSpsChanged);
 

	
 
    bpsLabel.setMinimumWidth(70);
 
    bpsLabel.setAlignment(Qt::AlignRight);
 
    spsLabel.setMinimumWidth(70);
 
    spsLabel.setAlignment(Qt::AlignRight);
 

	
 
    // init demo
 
    QObject::connect(ui->actionDemoMode, &QAction::toggled,
 
                     this, &MainWindow::enableDemo);
 
@@ -360,6 +369,11 @@ void MainWindow::onPortToggled(bool open
 
    // make sure demo mode is disabled
 
    if (open && isDemoRunning()) enableDemo(false);
 
    ui->actionDemoMode->setEnabled(!open);
 

	
 
    if (!open)
 
    {
 
        spsLabel.setText("0sps");
 
    }
 
}
 

	
 
void MainWindow::onSourceChanged(Source* source)
src/mainwindow.h
Show inline comments
 
@@ -47,6 +47,7 @@
 
#include "updatecheckdialog.h"
 
#include "samplecounter.h"
 
#include "datatextview.h"
 
#include "bpslabel.h"
 

	
 
namespace Ui {
 
class MainWindow;
 
@@ -91,6 +92,7 @@ private:
 
    PlotMenu plotMenu;
 
    DataTextView textView;
 
    UpdateCheckDialog updateCheckDialog;
 
    BPSLabel bpsLabel;
 

	
 
    void handleCommandLineOptions(const QCoreApplication &app);
 

	
src/portcontrol.cpp
Show inline comments
 
@@ -514,6 +514,27 @@ void PortControl::openPort()
 
    }
 
}
 

	
 
unsigned PortControl::maxBitRate() const
 
{
 
    float baud = serialPort->baudRate();
 
    float dataBits = serialPort->dataBits();
 
    float parityBits = serialPort->parity() == QSerialPort::NoParity ? 0 : 1;
 

	
 
    float stopBits;
 
    if (serialPort->stopBits() == QSerialPort::OneAndHalfStop)
 
    {
 
        stopBits = 1.5;
 
    }
 
    else
 
    {
 
        stopBits = serialPort->stopBits();
 
    }
 

	
 
    float frame_size = 1 /* start bit */ + dataBits + parityBits + stopBits;
 

	
 
    return float(baud) / frame_size;
 
}
 

	
 
void PortControl::saveSettings(QSettings* settings)
 
{
 
    settings->beginGroup(SettingGroup_Port);
src/portcontrol.h
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2019 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
@@ -50,6 +50,8 @@ public:
 
    void selectPort(QString portName);
 
    void selectBaudrate(QString baudRate);
 
    void openPort();
 
    /// Returns maximum bit rate for current baud rate
 
    unsigned maxBitRate() const;
 

	
 
    /// Stores port settings into a `QSettings`
 
    void saveSettings(QSettings* settings);
0 comments (0 inline, 0 general)