RSSI value doesn't match Spec plot

I am trying to record RSSI values of both the center frequency and the sidebands of various stations. The following command is an example of what I am executing to do this:
`python3 -s -p 8073 -m am --tlimit=10 --s-meter=0 --sdt-sec=5 --ts -f 860`

However, I seem to have discovered that the RSSI value returned by does not match the value at that frequency. Rather, it seems to measure a wider range of frequencies (about 5kHz on either side). Thus, I am getting the largest RSSI value within 5kHz of the frequency I'm measuring at, when I just want the RSSI value at that frequency.

For example, this station is at 860kHz:

The peak RSSI value is at about -56 dBm, the sidebands are at about -102 dBm, and the noise level is at -122 dBm.
When I measure the RSSI value at a frequency between 856 to 864 kHz, I get -56dBm, which I would only expect to get when measuring right at 860 kHz. Similarly, I get -102 dBm at frequencies all the way down to 845 kHz, when I would only expect this down to 850.

Essentially, the range of frequencies looked at seems to be too large, and I want to narrow the resolution to get the RSSI value right at the frequency of interest so that my data matches the Spec plot. How can I do this?

I have noticed that if I measure in CW mode instead of AM, it seems to be much more accurate. Also, if I measure in LSB mode, it is slightly more accurate than AM, though it's not super clear how it is obtaining these values.


  • The RSSI value returned by kiwirecorder is the same as the S-meter (in dBm) shown on the main user interface and the values displayed by the S-meter extension. S-meter values by definition are always the total power of the bandwidth-limited signal. So the value will take into account the sideband power and vary if the passband width is changed.

    If what you want is an individual value in a single bin as shown by the "spec" button display then you need to use kiwiwfrecorder instead. Or if you want to measure the carrier of an AM signal just reduce the passband to a low value like 50 Hz to eliminate the contribution of the sidebands.

    All of this can be demonstrated rather easily. I used a UK Kiwi and measured the nice strong, steady carrier of TDF on 162 kHz. It has no sidebands. In AM mode with a 10 kHz passband the S-meter says S9+23 and S-meter extension -50 dBm. These two values agree (S9 = -73 dBm, so S9+23 = -50 dBm). I type "/50" in the frequency entry box to drop the passband to 50 Hz. The S-meter values are the same since only the carrier is being measured.

    If I press the "spec" button the waterfall value at the carrier frequency is exactly -50 dBm even though this is being computed by a path that is completely independent of the audio/S-meter.

    You can do a similar measurement on a digital signal like STANAG 4285 or DRM that has a wide, flat, equal-amplitude spectrum. Measure with the S_meter extension using, say, a 2 kHz passband. Then drop the passband to 1 kHz. The S_meter reading will drop by 3 dBm. Half power to the S-meter equals -3 dBm. An example of that:


  • @jks thanks! How can I change the passband though?

    Also, can you explain how the RSSI values are obtained in LSB mode? I want to compare the signal strength of the carrier to the signal strength of the sideband. Right now my method is to simply take various signal strength measurements at the center frequency and the nearby frequencies to determine where the sideband is and how its strength compares to the carrier. Is there a better method?
  • jksjks
    edited June 2020
    Change passband in kiwirecorder? It's right in the "--help" output and shown in the Makefile examples. "-L passband_lo_cutoff_Hz", "-H passband_hi_cuttof_Hz". So "-L -5000 -H 5000" is a 10 kHz wide pb centered around the carrier you might use with AM and "-L 300 -H 3000" is a 2700 Hz wide pb you might use with USB.

    The RSSI/S-meter value is computed from the audio IQ stream before any demodulation. So the demod mode doesn't matter. Only the passband matters.
  • @jks this is very helpful! When you say "S-meter values by definition are always the total power of the bandwidth-limited signal," what does this mean? Is it like the average power of the entire passband (basically the integral of the spec plot divided by the passband width), or is it the max value within the passband, or something else?
  • jksjks
    edited June 2020
    The S-meter code is literally:
    s_meter_power = I*I + Q*Q
    s_meter_dBm = 10.0 * log10(s_meter_power / SND_MAX_VAL)
    s_meter_value = an_averaging_function(s_meter_dBm)
    Where I and Q are the two quadrature components (complex number) of the audio signal after passband filtering. So it contains all the data you see (and hear) within the yellow passband area on the waterfall, except that the actual data is coming from the audio path not the waterfall path. So it doesn't have anything to do with the spec plot. The spec plot is just the waterfall data plotted in a non-scrolling way (as a 2D graph).

    It's easy to forget because they both typically tune together. But the audio and waterfall are two entirely independent DDC (digital down conversion) receivers. You can re-tune the waterfall to go look at a completely different part of the spectrum without effecting the currently received audio. So a "4-channel" Kiwi is actually an 8-channel DDC SDR. This is why the unbalanced FPGA configurations are possible, i.e. rx8_wf2. The lack of waterfall on the other 6 audio channels is made up for by the audio FFT computed on the browser basically for free.
  • @jks why are the values negative, instead of starting at 0? If I wanted the values to start at 0, is there a certain constant I should add?
  • dBm is an absolute quanity, referenced to 1 milliwatt. I think what you want is dB which are relative. You can adjust to any level of relative dB you want.
  • I’m trying to do a calculation that involves dividing the sideband power by the carrier power, but for the calculation to work, I need valid positive power values.
  • I think you want to convert dBm to milliwatts before your calculation
  • Oh yes, I think that's it.

    The equation from jks above says
    s_meter_dBm = 10.0 * log10(s_meter_power / SND_MAX_VAL)
    I think s_meter_power is in mW, so I just need to reverse this equation, which yields:
    power_mW = 10^(s_meter_dBm / 10) * SND_MAX_VAL

    What is SND_MAX_VAL? It's not super important, because when I divide it will cancel out, but I'm just curious.
  • jksjks
    edited June 2020
    In the previous I should have used SND_MAX_PWR, instead of SND_MAX_VAL, where:
    s_meter_power = I*I + Q*Q;
    s_meter_dB = 10.0 * log10((s_meter_power / SND_MAX_PWR) + 1e-30);    // 1e-30 prevents log10(0)
    s_meter_dBm = an_averaging_function(s_meter_dB) + calibration_correction_value;
    The CuteSDR routines used by the Kiwi software assume input data is scaled to +32767.0/-32768.0 The S_meter dBm calculation requires a scale to +/- 1.0 Hence SND_MAX_VAL is 32767 and the division by SND_MAX_PWR needed.
Sign In or Register to comment.