diff --git a/debian/changelog b/debian/changelog index 21a540f07..b84f7bfb6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,8 +3,9 @@ sdrangel (4.2.4-1) unstable; urgency=medium * LimeSDR: use LimeSuite 18.10.0 for builds * DSD demod: use 1 dB steps for squelch * Scope: fixed some trigger issues. Fixes issue #233 + * Scope: implemented trigger holdoff. May fix more trigger issues. - -- Edouard Griffiths, F4EXB Wed, 24 Oct 2018 21:14:18 +0200 + -- Edouard Griffiths, F4EXB Sat, 27 Oct 2018 21:14:18 +0200 sdrangel (4.2.3-1) unstable; urgency=medium diff --git a/doc/img/ChAnalyzerNG_plugin_scope3.png b/doc/img/ChAnalyzerNG_plugin_scope3.png index 87781e7d6..09b8e1af2 100644 Binary files a/doc/img/ChAnalyzerNG_plugin_scope3.png and b/doc/img/ChAnalyzerNG_plugin_scope3.png differ diff --git a/doc/img/ChAnalyzerNG_plugin_scope3.xcf b/doc/img/ChAnalyzerNG_plugin_scope3.xcf index ae2a5e1a7..f4db77e17 100644 Binary files a/doc/img/ChAnalyzerNG_plugin_scope3.xcf and b/doc/img/ChAnalyzerNG_plugin_scope3.xcf differ diff --git a/plugins/channelrx/chanalyzer/readme.md b/plugins/channelrx/chanalyzer/readme.md index 8fd9755a0..19ee2fda7 100644 --- a/plugins/channelrx/chanalyzer/readme.md +++ b/plugins/channelrx/chanalyzer/readme.md @@ -386,7 +386,17 @@ This button selects the negative edge triggering. Trigger is raised only of the This button selects both signal edges triggering. Trigger is raised if the signal crosses threshold in any direction. This actually combines the positive and negative edge testing with an or condition. -

9. Trigger level adjustment

+

9. Trigger holdoff

+ +Use this button to control the trigger holdoff in a number of samples from 1 to 12. + +The above level condition is counted for a number of samples and if it is has been true for the holdoff number of samples the condition is declared true. A similar count is used for the false condition (below level). + +When the condition is declared true the counter of false conditions is reset and accordingly when the condition is declared false the counter of true conditions is reset. + +A value above 1 helps eliminating false triggers when small spikes appear on the leading or falling edge of a larger pulse. A value of 1 (minimum) means that the holdoff is not active. + +

10. Trigger level adjustment

This pair of sliders let you adjust the trigger level, The level appears on the left of the sliders. @@ -406,26 +416,26 @@ The bottom slider is a fine adjustment. Each step moves the trigger level by an - MagDB: 0.01 dB - Phi, dPhi: 20.0E-6 -

10: Trigger delay

+

11: Trigger delay

The actual trigger top can be moved forward by a number of samples. This pair of slider lets you adjust this delay. The delay in time units appears at the left of the sliders and the amount of samples as a tooltip The top slider is a coarse adjustment. Each step moves the delay by a trace length. The bottom slider is a fine adjustment. Each step moves the delay by 20 samples -

11. Pre-trigger delay

+

12. Pre-trigger delay

The trace can start an amount of time before the trigger top. This pair of sliders let you adjust this amount of time which is displayed at the left of the sliders. The corresponding number of samples appear as a tooltip. The top slider is a coarse adjustment. Each step moves the delay by a hundreth of the trace length. The bottom slider is a fine adjustment. Each step moves the delay by 20 samples. -

12. Trigger line color

+

13. Trigger line color

This area shows the current trigger line color. When clicking on it a color chooser dialog appears that lets you change the color of the current trigger line color. This line appears when the selected trace projection matches the trigger projection. -

13. One-shot trigger

+

14. One-shot trigger

This button toggles a one shot trigger. When the (final) trigger is raised only one trace is processed until the button is released. -

14. Freerun

+

15. Freerun

When active the triggers are disabled and traces are processed continuously. This is the default at plugin start time. diff --git a/sdrgui/dsp/scopevis.h b/sdrgui/dsp/scopevis.h index 2d6084e79..45742b5cd 100644 --- a/sdrgui/dsp/scopevis.h +++ b/sdrgui/dsp/scopevis.h @@ -105,6 +105,7 @@ public: int m_triggerLevelFine; bool m_triggerPositiveEdge; //!< Trigger on the positive edge (else negative) bool m_triggerBothEdges; //!< Trigger on both edges (else only one) + uint32_t m_triggerHoldoff; //!< Trigger holdoff in number of samples uint32_t m_triggerDelay; //!< Delay before the trigger is kicked off in number of samples (trigger delay) double m_triggerDelayMult; //!< Trigger delay as a multiplier of trace length int m_triggerDelayCoarse; @@ -123,6 +124,7 @@ public: m_triggerLevelFine(0), m_triggerPositiveEdge(true), m_triggerBothEdges(false), + m_triggerHoldoff(1), m_triggerDelay(0), m_triggerDelayMult(0.0), m_triggerDelayCoarse(0), @@ -572,13 +574,18 @@ private: bool m_prevCondition; //!< Condition (above threshold) at previous sample uint32_t m_triggerDelayCount; //!< Counter of samples for delay uint32_t m_triggerCounter; //!< Counter of trigger occurences + uint32_t m_trues; //!< Count of true conditions for holdoff processing + uint32_t m_falses; //!< Count of false conditions for holdoff processing + TriggerCondition(const TriggerData& triggerData) : m_projector(Projector::ProjectionReal), m_triggerData(triggerData), m_prevCondition(false), m_triggerDelayCount(0), - m_triggerCounter(0) + m_triggerCounter(0), + m_trues(0), + m_falses(0) { } @@ -607,6 +614,8 @@ private: m_prevCondition = false; m_triggerDelayCount = 0; m_triggerCounter = 0; + m_trues = 0; + m_falses = 0; } void operator=(const TriggerCondition& other) @@ -1021,7 +1030,7 @@ private: class TriggerComparator { public: - TriggerComparator() : m_level(0), m_reset(true), m_holdoff(2), m_trues(0), m_falses(0) + TriggerComparator() : m_level(0), m_reset(true) { computeLevels(); } @@ -1046,20 +1055,20 @@ private: if (condition) { - if (m_trues < m_holdoff) { + if (triggerCondition.m_trues < triggerCondition.m_triggerData.m_triggerHoldoff) { condition = false; - m_trues++; + triggerCondition.m_trues++; } else { - m_falses = 0; + triggerCondition.m_falses = 0; } } else { - if (m_falses < m_holdoff) { + if (triggerCondition.m_falses < triggerCondition.m_triggerData.m_triggerHoldoff) { condition = true; - m_falses++; + triggerCondition.m_falses++; } else { - m_trues = 0; + triggerCondition.m_trues = 0; } } @@ -1106,9 +1115,6 @@ private: Real m_levelPowerDB; Real m_levelPowerLin; bool m_reset; - uint32_t m_holdoff; - uint32_t m_trues; - uint32_t m_falses; }; GLScope* m_glScope; diff --git a/sdrgui/gui/glscopegui.cpp b/sdrgui/gui/glscopegui.cpp index b4fe97e64..2ffca3cdb 100644 --- a/sdrgui/gui/glscopegui.cpp +++ b/sdrgui/gui/glscopegui.cpp @@ -220,6 +220,7 @@ QByteArray GLScopeGUI::serialize() const s.writeFloat(218 + 16*i, triggerData.m_triggerColorR); s.writeFloat(219 + 16*i, triggerData.m_triggerColorG); s.writeFloat(220 + 16*i, triggerData.m_triggerColorB); + s.writeU32(221 + 16*i, triggerData.m_triggerHoldoff); } return s.final(); @@ -402,6 +403,9 @@ bool GLScopeGUI::deserialize(const QByteArray& data) d.readFloat(219 + 16*iTrigger, &g, 1.0f); d.readFloat(220 + 16*iTrigger, &b, 1.0f); m_focusedTriggerColor.setRgbF(r, g, b); + d.readU32(221 + 16*iTrigger, &uintValue, 1); + ui->trigHoldoff->setValue(uintValue); + ui->trigHoldoffText->setText(tr("%1").arg(uintValue)); fillTriggerData(triggerData); @@ -895,6 +899,12 @@ void GLScopeGUI::on_trigBoth_toggled(bool checked) changeCurrentTrigger(); } +void GLScopeGUI::on_trigHoldoff_valueChanged(int value) +{ + ui->trigHoldoffText->setText(tr("%1").arg(value)); + changeCurrentTrigger(); +} + void GLScopeGUI::on_trigLevelCoarse_valueChanged(int value __attribute__((unused))) { setTrigLevelDisplay(); @@ -1338,6 +1348,7 @@ void GLScopeGUI::fillTriggerData(ScopeVis::TriggerData& triggerData) triggerData.m_triggerLevelFine = ui->trigLevelFine->value(); triggerData.m_triggerPositiveEdge = ui->trigPos->isChecked(); triggerData.m_triggerBothEdges = ui->trigBoth->isChecked(); + triggerData.m_triggerHoldoff = ui->trigHoldoff->value(); triggerData.m_triggerRepeat = ui->trigCount->value(); triggerData.m_triggerDelayMult = ui->trigDelayCoarse->value() + ui->trigDelayFine->value() / (ScopeVis::m_traceChunkSize / 10.0); triggerData.m_triggerDelay = (int) (m_traceLenMult * ScopeVis::m_traceChunkSize * triggerData.m_triggerDelayMult); @@ -1405,6 +1416,8 @@ void GLScopeGUI::setTriggerUI(const ScopeVis::TriggerData& triggerData) } } + ui->trigHoldoffText->setText(tr("%1").arg(triggerData.m_triggerHoldoff)); + ui->trigLevelCoarse->setValue(triggerData.m_triggerLevelCoarse); ui->trigLevelFine->setValue(triggerData.m_triggerLevelFine); setTrigLevelDisplay(); diff --git a/sdrgui/gui/glscopegui.h b/sdrgui/gui/glscopegui.h index c5d181f35..de6687807 100644 --- a/sdrgui/gui/glscopegui.h +++ b/sdrgui/gui/glscopegui.h @@ -227,6 +227,7 @@ private slots: void on_trigPos_toggled(bool checked); void on_trigNeg_toggled(bool checked); void on_trigBoth_toggled(bool checked); + void on_trigHoldoff_valueChanged(int value); void on_trigLevelCoarse_valueChanged(int value); void on_trigLevelFine_valueChanged(int value); void on_trigDelayCoarse_valueChanged(int value); diff --git a/sdrgui/gui/glscopegui.ui b/sdrgui/gui/glscopegui.ui index 04a336824..bcc06e97e 100644 --- a/sdrgui/gui/glscopegui.ui +++ b/sdrgui/gui/glscopegui.ui @@ -1558,6 +1558,54 @@ kS/s + + + + H: + + + + + + + + 24 + 24 + + + + Trigger holdoff in number of samples + + + 1 + + + 12 + + + 1 + + + + + + + + 15 + 0 + + + + Number of samples for holdoff + + + 10 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + +