Raspberry Pi problem?
Raspberry Pi problem?
In fact it works exactly the same as the PC for a while, but then apparently suffer from severe 'interference' for a while, before switching back to working again, and so on. Each state lasts for a variable period of typically an hour or two.
I do not believe this actually to be interference, though, because although it happens reliably on the RPi, if you wait long enough, I've never seen it on the PC.
Here's an image showing a transition from the 'interference' state back to working (time increases up the page at about 4 pixels/second, frequency to the right at about 2 Hz/pixel). It also shows a couple of real meteor signals.
.
In an attempt to isolate whether this is a bug in my code, I've tried writing out raw IQ samples to disk directly from the stream callback, and performing the analysis offline. The problem still appears in that mode, so I believe artefact to be present in the samples by the time I get my hands on them.
I'm passing
fsMHz=2.000
rfMHz=143.050
bwType=mir_sdr_BW_0_200
ifType=mir_sdr_IF_0_450
to mir_sdr_StreamInit()
Are there any known issues of this nature with the SDRplay API on Raspberry Pi?
Cheers,
John
Reason: No reason
Re: Raspberry Pi problem?
Also suspicious is that the average spacing between noise bursts is 126 samples, which is exactly one quarter of the numSamples=504 samples passed to the stream callback.
This data was taken with no antenna plugged in, so I'm more convinced than ever that this is not real interference, but was generated internally to the RSP or SDRplay API somehow.
Reason: No reason
Re: Raspberry Pi problem?
Franco
Reason: No reason
Re: Raspberry Pi problem?
Does this happen to correlate with your screen saver?Each state lasts for a variable period of typically an hour or two.

Reason: No reason
Re: Raspberry Pi problem?
Thanks for the thought, but I'm pretty certain that's not it: the noise switches on and off in the middle of the night, it looks identical independent of whether an antenna is plugged in, and restarting the application reliably returns things to a no-noise state.mikael wrote:That looks like HDMI interference to me.Does this happen to correlate with your screen saver?Each state lasts for a variable period of typically an hour or two.
Cheers,
John
Reason: No reason
Re: Raspberry Pi problem?
I'll try that... note, though, that I'm currently using a 450 kHz IF (see mir_sdr_StreamInit parameters listed in my original post, above), and this change will force me to switch to using an IF of zero, so presumably will change quite a lot of the internal processing in the SDRplay API.fventuri wrote:Can you try using a fs > 2.685MHz to see if that artifact goes away?
Franco
What I have discovered is that the DC offset correction mode matters. I started with the calls
Code: Select all
mir_sdr_SetDcMode(4, 1);
mir_sdr_SetDcTrackTime(63);
Code: Select all
mir_sdr_SetDcMode(3, 1);
Cheers,
John
Reason: No reason
Re: Raspberry Pi problem?
With an fs of any of 2.000, 2.400, 3.000; a decimation factor of 4; and an intermediate frequency of zero, the problem does not occur. I ran it for 24 hours each, which should have been plenty of time.
Reverting to my previous setting of fs=2.000, intermediate frequency=450 kHz (with an implied decimation of 4), the problem occurred seven times during the 24 hour run.
So I wrote a small test program to try to generate the issue...
Code: Select all
#include "mirsdrapi-rsp.h"
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
static long cbCount = 0;
static double em100 = 0;
static bool noisy = false;
static double emax (short *xi, short *xq, unsigned int numSamples)
{
double em = 0;
for (int j = 0; j < numSamples; ++j)
{
const double i = xi[j];
const double q = xq[j];
const double e = i*i + q*q;
if (e > em) em = e;
}
return em;
}
static void s_callback (short *xi, short *xq, unsigned int firstSampleNum, int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, unsigned int reset, void *cbContext)
{
if (++cbCount <= 100)
{
// Use first 100 calls to find typical maximum signal level
const double em = emax (xi, xq, numSamples);
if (em > em100) em100 = em;
}
else
{
// Is this packet much noisier than normal?
const double em = emax (xi, xq, numSamples);
if ((cbCount % 10000) == 0)
{
printf ("*** Signal max power %.0f at callback %ld\n", (double) em, (long) cbCount);
fflush (stdout);
}
const bool nn = em > 4 * em100;
// Print message on transitions from normal->noisy and vice versa
if (nn != noisy)
{
printf ("*** Noise state %d at callback %ld\n", (int) nn, (long) cbCount);
fflush (stdout);
noisy = nn;
}
}
}
static void s_callbackGC (unsigned int gRdB, unsigned int lnaGRdB, void *cbContext)
{
mir_sdr_GainValuesT gv;
const mir_sdr_ErrT err = mir_sdr_GetCurrentGain (&gv);
assert (err == mir_sdr_Success);
}
int main (int, char**)
{
mir_sdr_ErrT err;
float ver;
err = mir_sdr_ApiVersion (&ver);
assert (err == mir_sdr_Success);
assert (ver == MIR_SDR_API_VERSION);
err = mir_sdr_DebugEnable (1);
assert (err == mir_sdr_Success);
err = mir_sdr_SetPpm (6.24);
assert (err == mir_sdr_Success);
err = mir_sdr_AgcControl (mir_sdr_AGC_DISABLE, 0, 0, 0, 0, 0, 0);
assert (err == mir_sdr_Success);
int newGr = 50;
int sysGr = 0;
int samplePerPacket;
err = mir_sdr_StreamInit (&newGr, 2.000, 143.050, mir_sdr_BW_0_200, mir_sdr_IF_0_450, 1, &sysGr, mir_sdr_USE_SET_GR_ALT_MODE, &samplePerPacket, s_callback, s_callbackGC, NULL);
assert (err == mir_sdr_Success);
err = mir_sdr_SetDcMode (4, 1);
assert (err == mir_sdr_Success);
err = mir_sdr_SetDcTrackTime (63);
assert (err == mir_sdr_Success);
mir_sdr_GainValuesT gv;
err = mir_sdr_GetCurrentGain (&gv);
assert (err == mir_sdr_Success);
sleep (INT_MAX);
}
but then it switches into the noisy state for a while with messages like*** Signal max power 3501 at callback 120000
*** Signal max power 2320 at callback 130000
*** Signal max power 2069 at callback 140000
*** Signal max power 3977 at callback 150000
*** Signal max power 1514 at callback 160000
Perhaps significantly, the switch to a noisy state happens at the some time as the sdr API writes debug messages like*** Signal max power 111454745 at callback 1760000
*** Signal max power 131692826 at callback 1770000
*** Signal max power 109825885 at callback 1780000
*** Signal max power 103865485 at callback 1790000
*** Signal max power 128117700 at callback 1800000
Obviously I don't know what these messages mean, but the coincidence in timing seems certain to be significant!Warning: DriverCallback() transfer error 0x16e3208 0
No offset diff1=0x000001f8 diff2=0x000001f8
No offset samp1=0xc8efd0ba samp2=0xc8efd2b2 samp2=0xc8efd4aa
bufOffset=0
Gap=0x37182d32 e=0xc8eed2c2 a=0x6fff4
Gap=0xfffffe23 e=0x701ec a=0x7000f
Gap=0xfffbfdfc e=0x70207 a=0x30003
Gap=0x2fe0a e=0x301fb a=0x60005
Gap=0xafe07 e=0x601fd a=0x110004
Gap=0xfff9fe0a e=0x1101fc a=0xb0006
Gap=0xfffdfe0a e=0xb01fe a=0x90008
Gap=0xfff8fe09 e=0x90200 a=0x20009
Gap=0x3fe01 e=0x20201 a=0x60002
Gap=0xfe13 e=0x601fa a=0x7000d
Gap=0xfdfb e=0x70205 a=0x80000
Gap=0x2fe17 e=0x801f8 a=0xb000f
:
(and many, many similar lines)
:
One other oddity, which may or may not be significant: even when working noise-free, the sdr API writes messages like
every couple of minutes. These look as if they are something to do with DC correction, which surprised me because the code is running in DcMode=4 (one-shot), and my code does not perform any gain changes which might re-trigger the correction. In addition, I notice that the qDCoffset value printed in the first line of these sequences is always 0.000000000, which also seemed odd.238096: iDCoffset=1275.313558262 qDCoffset=0.000000000
mir_sdr_SetGrAltMode: in: 0 1 (1) 0 0 0
mir_sdr_SetGrAltMode: GR->50[50,0,0,0] gRset->0x32 DCCALmode=4 DCCALspd=1 GrToggle->1
mir_sdr_GetCurrentGainVal : hwVer=1 freq=143.05 bw=200 if=450, bbGr=50, lnaState=0, minGr=20, amPort1En=0, apiDownConvert=1
mir_sdr_GetCurrentGainVal : hwVer=1 freq=143.05 group=4 gainState=0, corr=-9.50, freq0=120.00 freq1=146.00 gain0=114.03 gain1=114.52: curr_no_b
b=104.96 max=84.96 min=3.28 curr=54.96
mir_sdr_SetGrAltMode: out: 50 1 50 0 0
mir_sdr_ReadPacket: Gain update confirmed: Gr=50dB GrToggle=1 gset=0x32
grChanged @ 238475
DCoffsetCorrection: switched to tracking mode diff=2 curr=830.26 last=832.58
Hopefully this should be enough to allow you (SDRplay) to reproduce and track down the problem, but if you need any more information from me, please ask!
Cheers,
John
Reason: No reason
Re: Raspberry Pi problem?
In one shot mode there is a regular update every minute or two for offset correction as you say. The reason the Q channel is 0.0 is because you are in Low-IF mode. Only the I channel is used and then that is down converted to produce IQ samples to the callback.
Best regards,
SDRplay Support
Reason: No reason
Re: Raspberry Pi problem?
In addition, even if I strip everything out of the stream callback so the example code becomes
Code: Select all
#include "mirsdrapi-rsp.h"
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
static void s_callback (short *xi, short *xq, unsigned int firstSampleNum, int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, unsigned int reset, void *cbContext)
{
}
static void s_callbackGC (unsigned int gRdB, unsigned int lnaGRdB, void *cbContext)
{
}
int main (int, char**)
{
mir_sdr_ErrT err;
float ver;
err = mir_sdr_ApiVersion (&ver);
assert (err == mir_sdr_Success);
assert (ver == MIR_SDR_API_VERSION);
err = mir_sdr_DebugEnable (1);
assert (err == mir_sdr_Success);
err = mir_sdr_SetPpm (6.24);
assert (err == mir_sdr_Success);
err = mir_sdr_AgcControl (mir_sdr_AGC_DISABLE, 0, 0, 0, 0, 0, 0);
assert (err == mir_sdr_Success);
int newGr = 50;
int sysGr = 0;
int samplePerPacket;
err = mir_sdr_StreamInit (&newGr, 2.000, 143.050, mir_sdr_BW_0_200, mir_sdr_IF_0_450, 1, &sysGr, mir_sdr_USE_SET_GR_ALT_MODE, &samplePerPacket, s_callback, s_callbackGC, NULL);
assert (err == mir_sdr_Success);
err = mir_sdr_SetDcMode (4, 1);
assert (err == mir_sdr_Success);
err = mir_sdr_SetDcTrackTime (63);
assert (err == mir_sdr_Success);
mir_sdr_GainValuesT gv;
err = mir_sdr_GetCurrentGain (&gv);
assert (err == mir_sdr_Success);
sleep (INT_MAX);
}
after a while.Warning: DriverCallback() transfer error 0x1521740 0
No offset diff1=0x0008000a diff2=0xfff50001
No offset samp1=0x0004fffd samp2=0x000d0007 samp2=0x00020008
Offset diff1=0x000001f8 diff2=0x000001f8
Offset samp1=0x56262332 samp2=0x5626252a samp2=0x56262722
bufOffset=512
Gap=0x2d678 e=0x5622fdfa a=0x5625d472
Warning: DriverCallback() transfer error 0x1521740 0
No offset diff1=0xfff20000 diff2=0x000dffff
No offset samp1=0x00060007 samp2=0xfff80007 samp2=0x00060006
Offset diff1=0x000001f8 diff2=0x000001f8
Offset samp1=0x5728d9ea samp2=0x5728dbe2 samp2=0x5728ddda
bufOffset=512
Gap=0xa8e33f95 e=0x5726c072 a=0xa0007
Gap=0xfffafe05 e=0xa01ff a=0x50004
Gap=0x3fe15 e=0x501fc a=0x90011
Gap=0xfffefe03 e=0x90209 a=0x8000c
Gap=0xfe02 e=0x80204 a=0x90006
Gap=0xafe0c e=0x901fe a=0x14000a
Gap=0xfff3fdff e=0x140202 a=0x80001
Gap=0xfffcfe0f e=0x801f9 a=0x50008
Gap=0x6fe08 e=0x50200 a=0xc0008
Gap=0x3fe0e e=0xc0200 a=0x10000e
Gap=0xffecfdf3 e=0x100206 a=0xfffcfff9
Gap=0x6fe15 e=0xfffd01f1 a=0x40006
Gap=0xfffefe03 e=0x401fe a=0x30001
Gap=0x1fe0e e=0x301f9 a=0x50007
Gap=0x1fe01 e=0x501ff a=0x70000
Gap=0xfffafe0c e=0x701f8 a=0x20004
Gap=0x9fe0c e=0x201fc a=0xc0008
(etc.)
Does this happen for you, too, if you run this example code?
*
Thank you also for the explanation of the intermittent DC offset corrections: perhaps the API documentation could be corrected, as it says
and does not mention that there's a periodic update in addition to this.one shot mode (correction applied each time gain update performed)
Cheers,
John
Reason: No reason
Re: Raspberry Pi problem?
Press '1' when running top to see the individual core load. On my system your test app takes 50% on one core.
How are you building your app? I'm using this simple Makefile...
Code: Select all
EXE = example
RM = /bin/rm -f
MV = /bin/mv -f
MKDIR = /bin/mkdir -p
CC = gcc -g
LD = gcc -g
LN = ln
CFLAGS = -O3 -fPIC -Wall
INCS = -I/usr/local/include
LINKFLAGS =
LIB_OBJS = example.o
all: $(EXE)
$(EXE): $(LIB_OBJS)
@$(LD) $(LINKFLAGS) -o $(EXE) $(LIB_OBJS) -lpthread -lc -lm -ldl -lmirsd
rapi-rsp
%.o: %.c
@echo "Compiling" $<
@$(CC) $(CFLAGS) $(INCS) -c $<
clean:
@echo "Remove all object files"
@$(RM) $(LIB_OBJS) $(EXE) *.h~ *.c~ Makefile~
Best regards,
SDRplay Support
Reason: No reason