fventuri / gr-sdrplay3

Out-of-tree GNU Radio module for SDRplay RSP devices - SDRplay API V3.X
GNU General Public License v3.0
42 stars 8 forks source link

Problems when using QT GUI Widgets to adjust RSP gains #43

Open gozillah opened 2 months ago

gozillah commented 2 months ago

image

I would like to use QT GUI Range widgets to adjust the RSPduo gains dynamically.

May be there is a reason, but I have no explanation for the RF gains' type to be string. Never mind, as long as I enter numerical gains there the flowgraph is working. However, if I input the ID of a QT GUI Range widget (e.g. 'rfatten0' in the above example) I get the following error message:

Traceback (most recent call last):
  File "C:\Users\me\gr-examples\sdrplay\Test.py", line 220, in <module>
    main()
  File "C:\Users\me\gr-examples\sdrplay\Test.py", line 198, in main
    tb = top_block_cls()
         ^^^^^^^^^^^^^^^
  File "C:\Users\me\gr-examples\sdrplay\Test.py", line 103, in __init__
    self.sdrplay3_rspduo_0.set_gain(-float('rfatten0'), -float('rfatten1'), 'RF')
                                     ^^^^^^^^^^^^^^^^^
ValueError: could not convert string to float: 'rfatten0'
rspduo :info: total samples: [0,0]

>>> Done (return code 1)

Whether the QT GUI Range value in 'rfatten0' is of type float or int does not seem to be relevant.

So for the time being I am remaining with the numerical values in the RF gains:

image

Starting this flowgraph provides the expected results (with some overload warnings). But as soon as I am interactively lowering the QT GUI Range value of 'ifatten0', the flowgraph stops with the following error message:

Traceback (most recent call last):
  File "C:\Users\me\radioconda\Lib\site-packages\gnuradio\qtgui\range.py", line 242, in changed
    self.notifyChanged(self.rangeType(value))
  File "C:\Users\me\gr-examples\sdrplay\Test.py", line 183, in set_ifatten0
    self.sdrplay3_rspduo_0.set_gain(-self.ifatten0, -{if_gRdB1}, 'IF')
                                                      ^^^^^^^^
NameError: name 'if_gRdB1' is not defined

>>> Done (return code 3221226505)

test.zip

fventuri commented 2 months ago

@gozillah - thanks for reporting this problem with the RSPduo block for GRC. I'll try a few things here during the weekend when I have some free time, and I'll let you know what I find out.

I do know that the RF gain reduction setting takes a string because the user can either set the RF gain reduction as a number of dB, or they can pass the string 'LNA', where they can tell they want to set a specific LNA state (which is how RF gaid reduction is actually controlled in SDRplay RSPs).

Franco

gozillah commented 2 months ago

Thanks for your swift reply (as always - amazing!)

The first issue (ValueError: could not convert string to float: 'rfatten0') may be the result of QT GUI Range issuing only float or int types, not strings (as expected by your RSPduo implementation). I don't know how to work around this.

I discovered the discussion at link. TL;DR. Is there anywhere a full documentation about all options of specifying gains in gr-sdrplay3?

It is still essential for me to be able to control gains via QT GUI widgets.

fventuri commented 2 months ago

@gozillah - you probably are already aware that there's a tab called 'Documentation' in each RSP source block that gives you some basic information about the controls available in that block. For instance in the RSPduo block that information page has the following about 'RF Attenuation', where it tells you that it can also be specified as LNA (say 'LNA3'):

RF Attenuation:
RF attenuation in dB [0-X] where X depends on center freq and High-Z antenna
(see LNAstate table in the Users Guide)
RF attenuation as LNA state: LNA<LNAstate>

On the other hand to take full advantage of your RSPduo, you probably should become familiar with its gain (reduction) system, LNA state, hardware filters and IF filters, etc. For these I recommend the 'RSPduo Technical Information' document available here: https://www.sdrplay.com/wp-content/uploads/2018/06/RSPDuo-Technical-Information-R1P1.pdf For the gain reduction tables that show how the LNA state affects RF gain reduction depending on the RSP model, band, and antenna port type, please see the latest 'SDRplay API Specification' guide: https://www.sdrplay.com/docs/SDRplay_API_Specification_v3.15.pdf - those tables are toward the end on pages 38-39

Finally for more specialized information, like using both tuners of your RSpduo for diversity reception, since you are on Windows, I suggest experimenting with SDRuno (which is free), reading its excellent Users Guide (https://www.sdrplay.com/docs/SDRplay_SDRuno_User_Manual.pdf) and, last but not least, browsing the many posts related to diversity reception in the SDRPlayUsers group on groups.io: https://groups.io/g/SDRPlayUsers

Franco

gozillah commented 2 months ago

Thank you for the links which I have been browsing and will study in-depth later on. For the time being I would like to solve a single problem: How to modify RF and IF attenuation via QT GUI widgets while the flowgraph is running.

From your explanations I got the point of RF attenuation to be entered as a string, either a string representing a numerical value (dB) or a string composed of 'LNA' followed by a digit in the range of 0 to 9 (again as a string), e.g. 'LNA5', representing a 'LNA state'.

This is not possible with a QT GUI Range (lacking a string type) but with a QT GUI Chooser. So I modified my flowgraph:

image

See my grc in the Zip file file below. However I still get the same error message:

 File "C:\Users\Ich\gr-examples\sdrplay\Test.py", line 124, in __init__
    self.sdrplay3_rspduo_0.set_gain(-float('rf_atten0'), -float(rf_atten_1), 'RF')
                                     ^^^^^^^^^^^^^^^^^^
ValueError: could not convert string to float: 'rf_atten0'

Obviously gr-sdrplay3 is expecting, in the callback routine for RF attenuation, something which it could convert to a float. What I am delivering is a string arriving from my QT GUI Chooser widget. Looking at your code in link I see in the callback section

   % if rspduo_mode.nindepgain == '2':
    % if 'LNA' in str(rf_gR0).upper() and 'LNA' in str(rf_gR1).upper():
    set_gain(int(${rf_gR0}[3:]), int(${rf_gR1}[3:]), 'LNAstate')
    % else:
    set_gain(-float(${rf_gR0}), -float(${rf_gR1}), 'RF')

and in link

// Gain methods
double rspduo_impl::set_gain(const double gain, const std::string& name, const int tuner)
...
void rspduo_impl::set_gain(const double gain_A, const double gain_B, const std::string& name)

When I set RF attenuation manually in your 'SDRplay: RSPduo' block as a constant string, then everything works as expected. However when I inject the RF attenuation (string) value by QT GUI Chooser, then your current code seems to be unable to convert it to float because in this case it is not a constant.

The problem with injecting IF attenuation from a QT GUI Chooser may have similar causes.

test.zip

fventuri commented 2 months ago

@gozillah - I changed the GNU Radio Companion blocks for the SDRplay RSPs to set the RF gain reduction in two separate controls: the first one when the user wants to assign the value in dB, and the second one when the user prefers assigning it as LNA state. This way I can use numeric types ('real' and 'int') in both cases, and there should be no problem using variables as you do in your flowgraph.

I just pushed the new GRC block definitions for the SDRplay RSPs in the new branch fix-rf-gain-reduction-in-grc-blocks (https://github.com/fventuri/gr-sdrplay3/tree/fix-rf-gain-reduction-in-grc-blocks). If you don't want to rebuild and reinstall 'gr-sdrplay3', you can just copy the YAML files from the repository: https://github.com/fventuri/gr-sdrplay3/tree/fix-rf-gain-reduction-in-grc-blocks/grc and replace them in the radioconda install of GNU Radio: %RADIOCONDA_DIR%\Library\share\gnuradio\grc\blocks

Franco

gozillah commented 2 months ago

According to some initial (still a bit superficial) tests it is working on my RSPduo, at least with dBs (not tested LNAx yet). And as well with the IF attenuation (no error message there any more). Thank you! I will perform further tests and report.

I wonder how it was possible to fixed this in .yml only, i.e. without adapting the .cc callback routine. But my .yml / GRC knowledge is still at some -60 dB (my .yml block files look comparatively basic).

fventuri commented 2 months ago

@gozillah - there are three basic approaches to build and run a GNU Radio flowgraph:

  1. draw a flowgraph in GNU Radio Companion, have GRC generate the Python script, and run the Python script via GRC. This is the easiest way
  2. write a Python script (possibly modifying the one generated by GRC above, and say adding other Python modules, like multiprocessing, etc). This is a little more complex than the previous way, but it allows the full flexibility of Python. Also this is what is actually behind GRC; GRC just provides a nice and easy GUI for these steps
  3. write a C++ program to use the GNU Radio blocks natively - this is the hardest way but it is definitely doable. Useful when you need to create a library or interface directly with other programs written in C++ or languages that allow to call C++ functions

The error you posted in your initial message shows some bad Python syntax in the Python script generated by GRC, so the problem is somewhere in going from 1. to 2. The generation of the Python code in GRC is controlled by those YAML block files via a Python templating module called 'mako'; if you look inside those .yml files you'll see many references to templates. Unfortunately the keywords and syntax available for these YAML block files are not very well documented, so the best approach IMHO is to download the source code for GNU Radio, and learn from the existing blocks in the in-tree modules to see how many of the features of Python+mako can be used.

Franco

gozillah commented 1 month ago

According to some initial (still a bit superficial) tests it is working on my RSPduo, at least with dBs (not tested LNAx yet). And as well with the IF attenuation (no error message there any more). Thank you! I will perform further tests and report.

I am using the new separate RF attenuation controls frequently. So far no further issues.

May I suggest to renounce on the 'Disabled / Enabled' options for the AGC controls in 'sdrplay3_rspXXX.block.yml' and leave this a generic 'bool'. The benefit would be that the AGC could be on/off-controlled from a Qt GUI widget (e.g. QT GUI Checkbox or Chooser) in a GRC dashboard. Or would it be possible to extend the 'Disabled / Enabled' options list by a generic boolean element?

I removed (# commented-out) the AGC, AGC0 and AGC1 'options' and 'option_labels' in the yml file and installed a QT GUI Check Box for AGC0 and AGC1 with default value False (AGC off) and the QT GUI Check Box's ID in SRDplay's AGC0 and AGC1 properties fields. Upon transitioning from AGC off to AGC on via the QT GUI Check Box, GRC reported 'rspduo warning: overload detected - please reduce gain' and the Windows 10 SDRplay server crashed. The prevailing (high) attenuation values had been acceptable to the RSPduo both with the modified yml file with AGC off and with the generic yml file. The overload exception was not recoverable by simply transitioning to AGC off in the QT GUI Check Box.

test.zip

fventuri commented 1 month ago

@gozillah - I'll take a look at your suggestions. I think it should be possible to modify the GRC blocks .yml files to take additional values for Enabled/Disabled options.

Right now I have a couple of 'open' branches (synchronous-updates and message-passing: https://github.com/fventuri/gr-sdrplay3/issues/45#issuecomment-2198376407) that contain changes to those .yml files too. I would like to make sure those changes are good, and merge them into the main branch before adding more changes to the GRC blocks .yml files.

Franco