Hi,
I didn't find rtl_sdr with implemented direct sampling mode, so I made the patch. Also it has an option to set RTL AGC on.
This feature allows to use tuners as cheap data loggers without changing the schematic of the tuners. You can just connect wires directly to pins 1-2 of RTL2832 (I channel, diff. input) or pins 3-4 (Q channel, diff. input). When direct sampling mode is on - tuner's chip outputs are disabled and doesn't affect external signal.
For example, this command will write 8 bit samples to file 'mydata' at 2.4 MHz sampling rate with automatic gain:
rtl_sdr.exe -f 0 -s 2400000 -i -G mydata
Hope this will be useful for somebody as it was for me.
If you will accept the patch - please, update the windows binaries.
Thanks,
psb.
-------------------------------------------------------------------------------
diff --git a/src/rtl_sdr.c b/src/rtl_sdr.c
index eeb6dba..3564329 100644
--- a/src/rtl_sdr.c
+++ b/src/rtl_sdr.c
@@ -42,6 +42,7 @@
static int do_exit = 0;
static uint32_t bytes_to_read = 0;
static rtlsdr_dev_t *dev = NULL;
+static int samp_mode = 0;
void usage(void)
{
@@ -54,6 +55,9 @@ void usage(void)
"\t[-b output_block_size (default: 16 * 16384)]\n"
"\t[-n number of samples to read (default: 0, infinite)]\n"
"\t[-S force sync output (default: async)]\n"
+ "\t[-i set direct sampling mode (I)]\n"
+ "\t[-q set direct sampling mode (Q)]\n"
+ "\t[-G use RTL automatic gain]\n"
"\tfilename (a '-' dumps samples to stdout)\n\n");
exit(1);
}
@@ -81,6 +85,8 @@ static void sighandler(int signum)
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
+ uint32_t i, r;
+ unsigned char *p1, *p2;
if (ctx) {
if (do_exit)
return;
@@ -91,7 +97,16 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
rtlsdr_cancel_async(dev);
}
- if (fwrite(buf, 1, len, (FILE*)ctx) != len) {
+ if (samp_mode) {
+ // For direct sampling mode we throw out each 2nd value,
+ // i.e., save only one channel data - I or Q.
+ for (i=0, p1=buf, p2=buf; i<len; i+=2, p2++)
+ *p1++ = *p2++;
+ r = (fwrite(buf, 1, len/2, (FILE*)ctx) == len/2);
+ } else
+ r = (fwrite(buf, 1, len, (FILE*)ctx) == len);
+
+ if (!r) {
fprintf(stderr, "Short write, samples lost, exiting!\n");
rtlsdr_cancel_async(dev);
}
@@ -119,8 +134,10 @@ int main(int argc, char **argv)
uint32_t out_block_size = DEFAULT_BUF_LENGTH;
int device_count;
char vendor[256], product[256], serial[256];
+ uint32_t use_rtlagc = 0;
+ unsigned char *p1, *p2;
- while ((opt = getopt(argc, argv, "d:f:g:s:b:n:S::")) != -1) {
+ while ((opt = getopt(argc, argv, "d:f:g:s:b:n:S::Gqi")) != -1) {
switch (opt) {
case 'd':
dev_index = atoi(optarg);
@@ -143,6 +160,15 @@ int main(int argc, char **argv)
case 'S':
sync_mode = 1;
break;
+ case 'q':
+ samp_mode = 2;
+ break;
+ case 'i':
+ samp_mode = 1;
+ break;
+ case 'G':
+ use_rtlagc = 1;
+ break;
default:
usage();
break;
@@ -205,6 +231,15 @@ int main(int argc, char **argv)
if (r < 0)
fprintf(stderr, "WARNING: Failed to set sample rate.\n");
+ /* Set direct sampling */
+ if (samp_mode) {
+ r = rtlsdr_set_direct_sampling(dev, samp_mode);
+ if (r < 0)
+ fprintf(stderr, "WARNING: Failed to set direct sampling mode.\n");
+ else
+ fprintf(stderr, "Tuner set to direct sampling mode (%c).\n", (samp_mode==1)?'I':'Q');
+ }
+
/* Set the frequency */
r = rtlsdr_set_center_freq(dev, frequency);
if (r < 0)
@@ -231,6 +266,21 @@ int main(int argc, char **argv)
fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0);
}
+ /* Set RTL automatic gain */
+ if (1 == use_rtlagc) {
+ /* Enable automatic RTL gain */
+ r = rtlsdr_set_agc_mode(dev, 1);
+ if (r < 0)
+ fprintf(stderr, "WARNING: Failed to enable RTL automatic gain.\n");
+ else
+ fprintf(stderr, "RTL automatic gain enabled.\n");
+ } else {
+ /* Disable automatic RTL gain */
+ r = rtlsdr_set_agc_mode(dev, 0);
+ if (r < 0)
+ fprintf(stderr, "WARNING: Failed to disable RTL automatic gain.\n");
+ }
+
if(strcmp(filename, "-") == 0) { /* Write samples to stdout */
file = stdout;
#ifdef _WIN32
@@ -263,7 +313,16 @@ int main(int argc, char **argv)
do_exit = 1;
}
- if (fwrite(buffer, 1, n_read, file) != (size_t)n_read) {
+ if (samp_mode) {
+ // For direct sampling mode we throw out each 2nd value,
+ // i.e., save only one channel data - I or Q.
+ for (i=0, p1=buffer, p2=buffer; i<n_read; i+=2, p2++)
+ *p1++ = *p2++;
+ r = (fwrite(buffer, 1, n_read/2, file)== n_read/2);
+ } else
+ r = (fwrite(buffer, 1, n_read, file) == n_read);
+
+ if (!r) {
fprintf(stderr, "Short write, samples lost, exiting!\n");
break;
}
I heard someone recently made rtl-sdr work on an n900. Is it just
working drivers, or is it actually usable? I ask, because the
processor may not be up to the job.
Hey all.
I've been shouting it all over /r/rtlsdr and ##rtlsdr, but just for
you fine folks that are only on the ML, here[1] is what I've been up
to the past week:
Overhauled scanning in rtl_fm. This fixed a number of issues, where
either scanning did not work at all and some brokenness on OpenBSD.
It also meant giving up on the async API entirely.
Released a whole new application, rtl_power. This is something I'd
had bouncing around on my hard drive for many months, half-unwritten
due to over-complexity. It'll generate CSV files of arbitrarily
slow/wide/detailed FFTs. Also a little visualization script[2] that
won't choke when you give it 50,000 columns of data.
In the process of testing rtl_power, two more things came up. First
was windows builds. I've got a half-finished mingw32 build script[3]
that'll let me produce windows binaries[4] on a linux host. These
have been confirmed to actually run and probably work. Only W32 for
now, but just because I was too lazy to build the W64 toolchain.
Second was the discovery[5] that scanning had gotten a whole lot
slower since my original experiments with rtl_fm. 85mS to retune is
unacceptably slow. Since the r820t driver is the slowest, I started
looking into figuring out what is going on. Still figuring that out
but I have done basic cleanups to the code (removing redundancy,
particularly around register writes) and the driver is 15% shorter
with no modifications to code behavior.
I would not mind talking to Steve or one of the other devs on IRC
about some of the more ambiguous aspects of the driver. (Like, why
some reg writes are backed up to R828_Arry[] and others aren't. And
is that array thread safe at all? If not I'll have to do some very
large changes to support multiple dongles in rtl_power.)
I would really like to get these changes merged, particularly the
rtl_fm stuff because the version in the official repo is rather
bit-rotten.
-Kyle
http://kmkeen.com
[1] https://github.com/keenerd/rtl-sdr
[2] http://www.reddit.com/r/RTLSDR/comments/1ktzwi/
[3] http://kmkeen.com/tmp/mingw32.sh.txt
[4] http://kmkeen.com/tmp/rtl-sdr-mingw32-2013-08-28.zip
[5] http://www.reddit.com/r/RTLSDR/comments/1l2vlx/
single_manchester() considers both i and i+1, but the loop only
tests that i is in bounds. This causes undefined behavior, including
but not limited to a SIGBUS-related crash on Mac OS X.
---
src/rtl_adsb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/rtl_adsb.c b/src/rtl_adsb.c
index 44b62e2..3c353a0 100644
--- a/src/rtl_adsb.c
+++ b/src/rtl_adsb.c
@@ -258,6 +258,7 @@ void manchester(uint16_t *buf, int len)
uint16_t a=0, b=0;
uint16_t bit;
int i, i2, start, errors;
+ int maximum_i = len - 1; // len-1 since we look at i and i+1
// todo, allow wrap across buffers
i = 0;
while (i < len) {
@@ -275,7 +276,7 @@ void manchester(uint16_t *buf, int len)
i2 = start = i;
errors = 0;
/* mark bits until encoding breaks */
- for ( ; i < len; i+=2, i2++) {
+ for ( ; i < maximum_i; i+=2, i2++) {
bit = single_manchester(a, b, buf[i], buf[i+1]);
a = buf[i];
b = buf[i+1];
--
1.8.3.4
Hi everyone,
although there are some comparisons between the R820T and the E4000
already [1, 2], I also did some tests with another use-case in mind.
I'm working on a thing similar to RTLSDR-Scanner [3]. I want to
monitor a large part of the spectrum continuously.
So I compared the R820T with the E4000 using RTLSDR-Scanner w/ and w/o
an antenna.
My results are here:
https://docs.google.com/folder/d/0ByDAKwyEiyx_XzZ5ZnpRV1VZWDQ/edit?usp=shar…
There's much more spurs with the E4000 than w/ the R820T. According to
[1, 2] one also would expect a better overall sensivity compared to
the E4000.
However, the GSM900 signals for example seem to be way better with the
E4000 according to the RTLSDR-Scanner. Tuning to a certain channel w/
OsmoSDR Source in GNUradio gives about the same SNR - contrary to the
RTLSDR-Scanner output. Can anyone explain this?
Also, the DVB-T channel at 502MHz is quite weak in the R820T
RTLSDR-Scanner output when compared to the E4000. I had a closer look
at the lower limit of the channel in gnuradio. This can be seen in the
502MHz_*.png pictures. The E4000 produces a nice +20dB step while one
can hardly see the channel in the R820T spectrum. I don't understand
this as well. Is this AGC-related? Manually setting a fixed gain
didn't really help though...
Any explanations?
Thank you!
Best regards,
Hunz
[1] http://steve-m.de/projects/rtl-sdr/tuner_comparison/
[2] http://www.hamradioscience.com/rtl2832u-r820t-vs-rtl2832u-e4000/#more-1852
[3] https://github.com/EarToEarOak/RTLSDR-Scanner
I heard someone recently made rtl-sdr work on an n900. Is it just
working drivers, or is it actually usable? I ask, because the
processor may not be up to the job.
I have had great help before from this list, so many thanks for that.
I am using an ezcap tuner with a raspberry pi running a Debian based linux
OS called Raspbian. I have built the drivers from the git hub and they
work fine. As an aside, I found the installation much easier than when I
tried it directly on my PC.
My question is that I find that if I plug the USB device in when linux is
running, it causes a re-boot of the whole OS. (btw, disconnection has no
effect). Is this the case with full blown linux systems, or just some
peculiarity of the more limited raspberry pi? Also, it is a bit of a
nuisance, so does anyone know of a way to stop this?
many thanks Richard