pyrtlsdr: Why is my output different than universal radio hacker? I'm trying to build a script to do some signal processing from my RTLSDR. But, the bits I'm getting is not what I would expect.

The preamble using 'Universal Radio Hacker' looks like this:


But after plotting all values my script is seeing (-1 until +1) it looks like this:


Often I'm also getting plots that don't make any sense. At least the last one has some resemblance of the URH preamble, but also a lot of plots don't. 

What am I missing.. 'Universal radio hacker' also uses pyrtlsdr, so I know it can work. 
- Complex, real, imaginary - Can't say that I understand it fully. Something wrong there ?
- Noise, gain.. Not 100% sure what to do there. URH seems to set gain to 25, but when I do that I don't get anything, so I left it at 'auto' 
- I should be getting (almost) all of the samples. In the beginning I did lose some, but after I moved the postprocessing logic into separate processes it seems fine. 

My script: 

from rtlsdr import RtlSdr
from datetime import datetime
import asyncio
import matplotlib.pyplot as plt
from multiprocessing import Process, Queue


async def get_samples(sdr, q1):
    counter = 0
    timestamp1 = datetime.now()
    # Get this many samples every time
    async for samples in sdr.stream():
        q1.put(samples)
        counter += 1
        timestamp2 = datetime.now()
        if (timestamp2 - timestamp1).total_seconds() &gt; 1:
            # To see if we missed any samples. Should be close to srate samples p/s
            print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'GETSAMPLES -', int((counter * 131072) / (timestamp2 - timestamp1).total_seconds()), 'samples p/s')
            counter = 0
            timestamp1 = datetime.now()


def check_samples(q1, q2, noise, samplesperbit):
    while True:
        values = []
        withinnoisecounter = 0
        signal = False
        if q1.qsize() &gt; 10:
            print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'CHECKSAMPLES - Warning: Queue depth is', q1.qsize())
        samples = q1.get()
        for sample in samples:
            if not signal:
                # Start when signal breaks out of noise range
                if sample.real &gt; noise or sample.real &lt; -noise:
                    print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'CHECKSAMPLES - signal detected')
                    signal = True
                    values.append(sample.real)
            else:
                values.append(sample.real)
                if not (sample.real &gt; noise or sample.real &lt; -noise):
                    withinnoisecounter += 1
                elif withinnoisecounter &gt; 0:
                    withinnoisecounter = 0
                if withinnoisecounter &gt; samplesperbit * 3:
                    # Break when signal is within noise range 3 * samplesperbit
                    break
        if signal:
            q2.put(values)


def decode_fsk(q2, srate):
    # ToDo, now it just plots
    while True:
        values = q2.get()
        plt.figure(figsize=(20, 5))
        # Preamble should be in here
        plt.plot(values[:2000])
        plt.show()


def main():
    noise = 0.9
    # 38400 * 30 to get exactly 30 samples per bit.
    srate = 1152000
    samplesperbit = 1000000 / 38400 / (1000000 / srate)
    sdr = RtlSdr()
    # Just like in URH
    sdr.freq_correction = 1
    sdr.sample_rate = srate
    sdr.center_freq = 868.200e6
    sdr.gain = 'auto'
    # Run check_samples in another thread to make sure we don't miss any samples
    q1 = Queue()
    q2 = Queue()
    p1 = Process(target=check_samples, args=(q1, q2, noise, samplesperbit))
    p1.start()
    # Run decode_fsk in another thread to make sure we don't miss any samples
    p2 = Process(target=decode_fsk, args=(q2, srate))
    p2.start()
    # This is the main loop
    loop = asyncio.get_event_loop()
    loop.run_until_complete(get_samples(sdr, q1))


if __name__ == "__main__":
    main()


Thanks!
Your signal recording clearly shows that you have long streaks of 1.0 – that probably means you're clipping.

Your signal is thus broken. Make a new recording with less gain.