diff --git a/misc/pseudo_device.py b/misc/pseudo_device.py --- a/misc/pseudo_device.py +++ b/misc/pseudo_device.py @@ -6,7 +6,7 @@ # # Currently this script only outputs ASCII(comma separated) data. # -# Copyright © 2015 Hasan Yavuz Özderya +# Copyright © 2018 Hasan Yavuz Özderya # # This file is part of serialplot. # @@ -26,6 +26,22 @@ import os, pty, time, struct, math +def ascii_test_str(port): + text = """ +1,2,3 +2,4,6 +3,8,11 +1,2,3 +-1,-1,-1 +nana +0,0,0 +1,na,na + """ + while True: + for line in text.splitlines(): + os.write(port, bytes(line+"\r\n", 'utf8')) + time.sleep(1) + def ascii_test(port): """Put ASCII test data through pseudo terminal.""" print("\n") @@ -109,8 +125,9 @@ def run(): try: # float_sine(master) - frame_test(master) + # frame_test(master) # ascii_test(master) + ascii_test_str(master) finally: # close the pseudo terminal files os.close(master) diff --git a/src/asciireader.cpp b/src/asciireader.cpp --- a/src/asciireader.cpp +++ b/src/asciireader.cpp @@ -110,57 +110,59 @@ void AsciiReader::onDataReady() continue; } - auto separatedValues = line.split(delimiter, QString::SkipEmptyParts); - - unsigned numReadChannels; // effective number of channels to read - unsigned numComingChannels = separatedValues.length(); - - if (autoNumOfChannels) - { - // did number of channels changed? - if (numComingChannels != _numChannels) - { - _numChannels = numComingChannels; - updateNumChannels(); - emit numOfChannelsChanged(numComingChannels); + const SamplePack* samples = parseLine(line); + if (samples != nullptr) { + // update number of channels if in auto mode + if (autoNumOfChannels ) { + unsigned nc = samples->numChannels(); + if (nc != _numChannels) { + _numChannels = nc; + updateNumChannels(); + // TODO: is `numOfChannelsChanged` signal still used? + emit numOfChannelsChanged(nc); + } } - numReadChannels = numComingChannels; - } - else if (numComingChannels >= _numChannels) - { - numReadChannels = _numChannels; - } - else // there is missing channel data - { - numReadChannels = separatedValues.length(); - qWarning() << "Incoming data is missing data for some channels!"; - qWarning() << "Read line: " << line; - } + + Q_ASSERT(samples->numChannels() == _numChannels); - // parse read line - unsigned numDataBroken = 0; - SamplePack samples(1, _numChannels); - for (unsigned ci = 0; ci < numReadChannels; ci++) - { - bool ok; - samples.data(ci)[0] = separatedValues[ci].toDouble(&ok); - if (!ok) - { - qWarning() << "Data parsing error for channel: " << ci; - qWarning() << "Read line: " << line; - samples.data(ci)[0] = 0; - numDataBroken++; - } - } - - if (numReadChannels > numDataBroken) - { // commit data - feedOut(samples); + feedOut(*samples); } } } +SamplePack* AsciiReader::parseLine(const QString& line) const +{ + auto separatedValues = line.split(delimiter, QString::SkipEmptyParts); + unsigned numComingChannels = separatedValues.length(); + + // check number of channels (skipped if auto num channels is enabled) + if ((!numComingChannels) || (!autoNumOfChannels && numComingChannels != _numChannels)) + { + qWarning() << "Line parsing error: invalid number of channels!"; + qWarning() << "Read line: " << line; + return nullptr; + } + + // parse data per channel + auto samples = new SamplePack(1, numComingChannels); + for (unsigned ci = 0; ci < numComingChannels; ci++) + { + bool ok; + samples->data(ci)[0] = separatedValues[ci].toDouble(&ok); + if (!ok) + { + qWarning() << "Data parsing error for channel: " << ci; + qWarning() << "Read line: " << line; + + delete samples; + return nullptr; + } + } + + return samples; +} + void AsciiReader::saveSettings(QSettings* settings) { _settingsWidget.saveSettings(settings); diff --git a/src/asciireader.h b/src/asciireader.h --- a/src/asciireader.h +++ b/src/asciireader.h @@ -21,7 +21,9 @@ #define ASCIIREADER_H #include +#include +#include "samplepack.h" #include "abstractreader.h" #include "asciireadersettings.h" @@ -50,6 +52,12 @@ private: private slots: void onDataReady() override; + /** + * Parses given line and returns sample pack. + * + * Returns `nullptr` in case of error. + */ + SamplePack* parseLine(const QString& line) const; }; #endif // ASCIIREADER_H