AaronJPung
AaronJPung

Reputation: 1144

Terminating an asyncio loop with RTL-SDR after N seconds

I'm building a function to allow a user to stream RTL-SDR data for N seconds.

Attempt 1

Currently, my script uses two functions, one of which monitors timeout conditions and signals the program to finish the async when the timeout condition is met. Here's my current script:

import asyncio
import datetime
starttime = datetime.datetime.now() 
stoptime = starttime + datetime.timedelta(0,5)

async def timeout():
    while datetime.datetime.now()<stoptime:
        await asyncio.sleep(0.5)

async def streaming(sdr):
    async for samples in sdr.stream():
        print(samples)

async def main():
    sdr = RtlSdr()
    task1 = asyncio.create_task(timeout())
    task2 = asyncio.create_task(streaming(sdr))
    await asyncio.wait({task1, task2}, return_when=asyncio.FIRST_COMPLETED)
    sdr.stop()
    sdr.close()

if __name__ == "__main__":
    asyncio.run(main())

The script seems to run fine for the N=5 seconds I specify, printing out the data samples I request. But when the 5 seconds are over, the samples stop printing (as expected), but the program hangs and does not complete.

I really think I'm missing a "timeout" parameter or something more simple than what I'm doing, but I haven't found it yet. The timeout parameter asyncio.wait does contain does not solve my issue.

Attempt 2

I've tried implementing more simple logic based on rtlsdraio:

import asyncio
from rtlsdr import RtlSdr
import datetime

# Define start/stop times
starttime = datetime.datetime.now() 
stoptime = starttime + datetime.timedelta(0,5)

async def streaming():
    sdr = RtlSdr()

    async for samples in sdr.stream():
        if datetime.datetime.now()>stoptime:
            await sdr.stop()
        else:
            print(samples)

    # done
    sdr.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(streaming())

The logic seems to work fine, but it throws an error at the end that I'm not sure how to get around:

Traceback (most recent call last):
  File "e:\Dropbox\Repositories\sdr_analysis\src\test_asyncio3.py", line 21, in <module>
    loop.run_until_complete(streaming())
  File "C:\Users\aaron\miniconda3\envs\gprMax\lib\asyncio\base_events.py", line 649, in run_until_complete
    return future.result()
  File "e:\Dropbox\Repositories\sdr_analysis\src\test_asyncio3.py", line 13, in streaming
    await sdr.stop()
  File "<string>", line 91, in stop
  File "C:\Users\aaron\miniconda3\envs\gprMax\lib\concurrent\futures\thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "C:\Users\aaron\miniconda3\envs\gprMax\lib\site-packages\rtlsdr\rtlsdraio.py", line 193, in <lambda>
    self.async_iter = AsyncCallbackIter(func_start=lambda cb: func_start(cb, num_samples_or_bytes),
  File "C:\Users\aaron\miniconda3\envs\gprMax\lib\site-packages\rtlsdr\rtlsdr.py", line 659, in read_samples_async
    self.read_bytes_async(self._samples_converter_callback, num_bytes, context)
  File "C:\Users\aaron\miniconda3\envs\gprMax\lib\site-packages\rtlsdr\rtlsdr.py", line 604, in read_bytes_async
    raise LibUSBError(result, 'Could not read %d bytes' % (num_bytes))
rtlsdr.rtlsdr.LibUSBError: <LIBUSB_ERROR_NOT_FOUND (-5): Entity not found> "Could not read 262144 bytes"

Attempt 3

This code seems to technically work fine. When I run main(), I get returns from the RTLSDR, and after 2 seconds it exits the loop. My problem now is that I'm having trouble breaking out of async.main().

import asyncio
import datetime
from rtlsdr import RtlSdr

sdr = RtlSdr()

async def main():
    starttime = datetime.datetime.now() 
    stoptime = starttime + datetime.timedelta(0,2)
    while datetime.datetime.now() < stoptime:
        print(sdr.stream())
    print('out')
    sdr.stream().aclose()
    return

def printme():
    print("here now")

asyncio.run(main())
printme()

After the 2 seconds is over, my terminal simply shows

...
<rtlsdr.rtlsdraio.AsyncCallbackIter object at 0x000001EE501F2F80>
<rtlsdr.rtlsdraio.AsyncCallbackIter object at 0x000001EE501F3100>
<rtlsdr.rtlsdraio.AsyncCallbackIter object at 0x000001EE501F3280>
out
2024-02-06 06:57:57.820080
Allocating 15 (non-zero-copy) user-space buffers

Upvotes: 1

Views: 231

Answers (0)

Related Questions