Reputation: 1144
I'm building a function to allow a user to stream RTL-SDR data for N seconds.
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.
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"
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