0

I am developing a Python script in which I am sampling data from a BLE device at a rate of about 50-200Hz. As of right now, I am doing this synchronously:

while True:
  if time_now > time_before + (1/sample_rate):
    do_stuff()

This works great, except for the fact that it is blocking the thread and other applications completely (if I want to combine with a Qt GUI, e.g.). What is the correct way to go about this issue?

  • Can I easily implement a multithreading setup, where each "sampler" (while-loop) gets its own thread?
  • Should I implement timer operations, and how do I make sure the script is not killed while waiting for a new sample?

My problem is similar to this, which, however, is for C#.

Community
  • 1
  • 1
casparjespersen
  • 3,460
  • 5
  • 38
  • 63
  • I would separate the polling procedure in a dedicated thread, that will write samples somewhere (memory, queue, etc..), Then, in the other parts of the application, I would read those samples when available. The advantage is that a hw fault / block would not block your script logic – BeerBaron Feb 14 '17 at 15:44
  • Do you need to poll at all? Doesn't the device implement notifications so that you will be asynchronously and automagically notified each time a characteristic changes? Look at BLE examples to see how to enable change notifications for a given characteristic. – Kuba hasn't forgotten Monica Feb 14 '17 at 19:12

2 Answers2

1

If the sampling itself doesn't take much time, you could use a QTimer and do the sampling in a slot on timeout. If it takes a lot of time blocking on I/O and not executing python code, you should probably use a Thread for the polling and send the result to the main thread using a signal. If the sampling uses a lot of time executing python code, you are out of luck with most python implementations because of the GIL (Global Interpreter Lock). In most python implementations only one thread can actively execute python code. So real parallelism in pyhton is often done by creating new processes instead of new threads.

MofX
  • 1,569
  • 12
  • 22
0

I love the Javascript setInterval pattern, my guess is this is more like what you want.

import threading

def setInterval(func,time):
    e = threading.Event()
    while not e.wait(time):
        func()

def foo():
    print "do poll here"

# using
setInterval(foo,5)

https://stackoverflow.com/a/39842247/1598412

Community
  • 1
  • 1
ShaBANG
  • 193
  • 1
  • 11