From 3fea5fb4148f52a72910624c8e13832ed431421c Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Fri, 25 Jun 2021 13:46:03 +0100 Subject: [PATCH] Send multiple streams to scope --- .../channelrx/radioclock/radioclockgui.cpp | 18 +-- plugins/channelrx/radioclock/radioclockgui.h | 2 - plugins/channelrx/radioclock/radioclockgui.ui | 132 ------------------ .../radioclock/radioclocksettings.cpp | 6 - .../channelrx/radioclock/radioclocksettings.h | 2 - .../channelrx/radioclock/radioclocksink.cpp | 83 +++-------- plugins/channelrx/radioclock/readme.md | 21 ++- 7 files changed, 40 insertions(+), 224 deletions(-) diff --git a/plugins/channelrx/radioclock/radioclockgui.cpp b/plugins/channelrx/radioclock/radioclockgui.cpp index cf90cd51f..0b500552e 100644 --- a/plugins/channelrx/radioclock/radioclockgui.cpp +++ b/plugins/channelrx/radioclock/radioclockgui.cpp @@ -176,18 +176,6 @@ void RadioClockGUI::on_timezone_currentIndexChanged(int index) applySettings(); } -void RadioClockGUI::on_channel1_currentIndexChanged(int index) -{ - m_settings.m_scopeCh1 = index; - applySettings(); -} - -void RadioClockGUI::on_channel2_currentIndexChanged(int index) -{ - m_settings.m_scopeCh2 = index; - applySettings(); -} - void RadioClockGUI::onWidgetRolled(QWidget* widget, bool rollDown) { (void) widget; @@ -259,10 +247,11 @@ RadioClockGUI::RadioClockGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Bas m_scopeVis = m_radioClock->getScopeSink(); m_scopeVis->setGLScope(ui->glScope); - m_scopeVis->setNbStreams(1); + m_scopeVis->setNbStreams(7); m_scopeVis->setLiveRate(1000); ui->glScope->connectTimer(MainCore::instance()->getMasterTimer()); ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope); + ui->scopeGUI->setStreams(QStringList({"IQ", "MagSq", "TH", "FM", "Data", "Samp", "GotMM"})); ui->status->setText("Looking for minute marker"); @@ -342,9 +331,6 @@ void RadioClockGUI::displaySettings() displayStreamIndex(); - ui->channel1->setCurrentIndex(m_settings.m_scopeCh1); - ui->channel2->setCurrentIndex(m_settings.m_scopeCh2); - blockApplySettings(false); } diff --git a/plugins/channelrx/radioclock/radioclockgui.h b/plugins/channelrx/radioclock/radioclockgui.h index 940c64e05..c6e167f11 100644 --- a/plugins/channelrx/radioclock/radioclockgui.h +++ b/plugins/channelrx/radioclock/radioclockgui.h @@ -89,8 +89,6 @@ private slots: void on_threshold_valueChanged(int value); void on_modulation_currentIndexChanged(int index); void on_timezone_currentIndexChanged(int index); - void on_channel1_currentIndexChanged(int index); - void on_channel2_currentIndexChanged(int index); void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDialogCalled(const QPoint& p); void handleInputMessages(); diff --git a/plugins/channelrx/radioclock/radioclockgui.ui b/plugins/channelrx/radioclock/radioclockgui.ui index 46f4720a9..efb3721cf 100644 --- a/plugins/channelrx/radioclock/radioclockgui.ui +++ b/plugins/channelrx/radioclock/radioclockgui.ui @@ -586,136 +586,6 @@ 3 - - - - - - Real - - - - - - - - 0 - 0 - - - - Signal to feed to scope as stream 0 real data - - - - I - - - - - Mag Sq - - - - - Mag Sq LPF - - - - - Threshold - - - - - FM demod LPF - - - - - Data - - - - - Sample - - - - - Got minute marker - - - - - - - - - 0 - 0 - - - - Imag - - - - - - - - 0 - 0 - - - - Signal to feed to scope as stream 0 imag data - - - - Q - - - - - Mag Sq - - - - - Mag Sq LPF - - - - - Threshold - - - - - FM Demod LPF - - - - - Data - - - - - Sample - - - - - Got minute marker - - - - - - @@ -778,8 +648,6 @@ timezone date time - channel1 - channel2 diff --git a/plugins/channelrx/radioclock/radioclocksettings.cpp b/plugins/channelrx/radioclock/radioclocksettings.cpp index 604f1a079..d560faf6e 100644 --- a/plugins/channelrx/radioclock/radioclocksettings.cpp +++ b/plugins/channelrx/radioclock/radioclocksettings.cpp @@ -37,8 +37,6 @@ void RadioClockSettings::resetToDefaults() m_threshold = 5; m_modulation = MSF; m_timezone = BROADCAST; - m_scopeCh1 = 2; - m_scopeCh2 = 3; m_rgbColor = QColor(102, 0, 0).rgb(); m_title = "Radio Clock"; m_streamIndex = 0; @@ -58,8 +56,6 @@ QByteArray RadioClockSettings::serialize() const s.writeFloat(4, m_threshold); s.writeS32(5, (int)m_modulation); s.writeS32(6, (int)m_timezone); - s.writeS32(10, m_scopeCh1); - s.writeS32(11, m_scopeCh2); s.writeU32(12, m_rgbColor); s.writeString(13, m_title); if (m_channelMarker) { @@ -97,8 +93,6 @@ bool RadioClockSettings::deserialize(const QByteArray& data) d.readFloat(4, &m_threshold, 30); d.readS32(5, (int *)&m_modulation, DCF77); d.readS32(6, (int *)&m_timezone, BROADCAST); - d.readS32(10, &m_scopeCh1, 2); - d.readS32(11, &m_scopeCh2, 3); d.readU32(12, &m_rgbColor, QColor(102, 0, 0).rgb()); d.readString(13, &m_title, "Radio Clock"); d.readBlob(14, &bytetmp); diff --git a/plugins/channelrx/radioclock/radioclocksettings.h b/plugins/channelrx/radioclock/radioclocksettings.h index df1765af5..ac5f69b41 100644 --- a/plugins/channelrx/radioclock/radioclocksettings.h +++ b/plugins/channelrx/radioclock/radioclocksettings.h @@ -41,8 +41,6 @@ struct RadioClockSettings LOCAL, UTC } m_timezone; - int m_scopeCh1; - int m_scopeCh2; quint32 m_rgbColor; QString m_title; diff --git a/plugins/channelrx/radioclock/radioclocksink.cpp b/plugins/channelrx/radioclock/radioclocksink.cpp index f3ee2f023..8a734b1e3 100644 --- a/plugins/channelrx/radioclock/radioclocksink.cpp +++ b/plugins/channelrx/radioclock/radioclocksink.cpp @@ -66,14 +66,22 @@ void RadioClockSink::sampleToScope(Complex sample) { if (m_scopeSink) { - Real r = std::real(sample) * SDR_RX_SCALEF; - Real i = std::imag(sample) * SDR_RX_SCALEF; - SampleVector m_sampleBuffer1; - m_sampleBuffer1.push_back(Sample(r, i)); - std::vector vbegin; - vbegin.push_back(m_sampleBuffer1.begin()); - m_scopeSink->feed(vbegin, m_sampleBuffer1.end() - m_sampleBuffer1.begin()); - m_sampleBuffer1.clear(); + ComplexVector m_sampleBuffer[7]; + m_sampleBuffer[0].push_back(sample); + m_sampleBuffer[1].push_back(Complex(m_magsq, 0.0f)); + m_sampleBuffer[2].push_back(Complex(m_threshold, 0.0f)); + m_sampleBuffer[3].push_back(Complex(m_fmDemodMovingAverage.asDouble(), 0.0f)); + m_sampleBuffer[4].push_back(Complex(m_data, 0.0f)); + m_sampleBuffer[5].push_back(Complex(m_sample, 0.0f)); + m_sampleBuffer[6].push_back(Complex(m_gotMinuteMarker, 0.0f)); + std::vector vbegin; + for (int i = 0; i < 7; i++) { + vbegin.push_back(m_sampleBuffer[i].begin()); + } + m_scopeSink->feed(vbegin, m_sampleBuffer[0].end() - m_sampleBuffer[0].begin()); + for (int i = 0; i < 7; i++) { + m_sampleBuffer[i].clear(); + } } } @@ -596,63 +604,8 @@ void RadioClockSink::processOneSample(Complex &ci) msf60(); } - // Select signals to feed to scope - Complex scopeSample; - switch (m_settings.m_scopeCh1) - { - case 0: - scopeSample.real(ci.real() / SDR_RX_SCALEF); - break; - case 1: - scopeSample.real(magsq * 1e6); - break; - case 2: - scopeSample.real(m_magsq * 1e6); - break; - case 3: - scopeSample.real(m_threshold * 1e6); - break; - case 4: - scopeSample.real(m_fmDemodMovingAverage.asDouble()); - break; - case 5: - scopeSample.real(m_data); - break; - case 6: - scopeSample.real(m_sample); - break; - case 7: - scopeSample.real(m_gotMinuteMarker); - break; - } - switch (m_settings.m_scopeCh2) - { - case 0: - scopeSample.imag(ci.imag() / SDR_RX_SCALEF); - break; - case 1: - scopeSample.imag(magsq * 1e6); - break; - case 2: - scopeSample.imag(m_magsq * 1e6); - break; - case 3: - scopeSample.imag(m_threshold * 1e6); - break; - case 4: - scopeSample.imag(m_fmDemodMovingAverage.asDouble()); - break; - case 5: - scopeSample.imag(m_data); - break; - case 6: - scopeSample.imag(m_sample); - break; - case 7: - scopeSample.imag(m_gotMinuteMarker); - break; - } - sampleToScope(scopeSample); + // Feed signals to scope + sampleToScope(Complex(re, im)); } void RadioClockSink::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force) diff --git a/plugins/channelrx/radioclock/readme.md b/plugins/channelrx/radioclock/readme.md index 8f145254d..5d9355354 100644 --- a/plugins/channelrx/radioclock/readme.md +++ b/plugins/channelrx/radioclock/readme.md @@ -12,7 +12,7 @@ If you'd like other transmitters to be supported (such as WWVB), please upload a Typically, it will take two minutes before the time is able to be displayed (up to one minute to find the minute marker, then another minute to receive the timecode). -Although the atomic clocks used to transmit the timecode are extremely accurate, propagation, SDR data transfer and demodulation delays limit accuracy of the displayed time to around 1 second. +Although the atomic clocks used to transmit the timecode are extremely accurate, propagation, SDR data transfer and demodulation delays limit accuracy of the displayed time to around 1 second.

Interface

@@ -76,3 +76,22 @@ Displays the demodulator status. This can be: The date and time fields are only valid when the status indicates OK. If while in the OK state several second markers are not detected, the status will return to Looking for minute marker. + +

Waveforms

+ +The scope shows how various variables within the demodulator vary with time. These can be used to help debug operation of the demodulator. + +The signals available include: + +- IQ - IQ data at channel sample rate (1kHz). +- MagSq - Magnitude squared (power) of received signal after being filtered with a moving average filter. +- TH - Current threshold, which is moving average of MagSq - TH setting. +- FM - Output of FM demodulator for TDF demodulator only. +- Data - Demodulated data. For MSF/DCF77, this data=MagSq>TH. +- Samp - Indicates when data is sampled (either for the second marker or for a timecode data bit). +- GotMM - Indicates whether the minute marker has been received. Cleared when synchronization to second marker is lost. + +As an example of how this can be used, we can plot the MagSq as X and the calculated TH as Y, which can help to set the value of the +TH setting to an approproate level. + +![Radio clock plugin GUI](../../../doc/img/RadioClock_waveforms.png)