Worker_DAQ

class dvg_qdeviceio.Worker_DAQ(qdev, DAQ_trigger=DAQ_TRIGGER.INTERNAL_TIMER, DAQ_function=None, DAQ_interval_ms=100, DAQ_timer_type=0, critical_not_alive_count=1, debug=False, **kwargs)[source]

Bases: QObject

This worker acquires data from the I/O device, either periodically or aperiodically. It does so by calling a user-supplied function, passed as initialization parameter DAQ_function, containing device I/O operations and subsequent data processing, every time the worker updates. There are different modes of operation for this worker to perform an update. This is set by initialization parameter DAQ_trigger.

An instance of this worker will be created and placed inside a new thread by a call to QDeviceIO.create_worker_DAQ().

The Worker_DAQ routine is robust in the following sense. It can be set to quit as soon as a communication error appears, or it could be set to allow a certain number of communication errors before it quits. The latter can be useful in non-critical implementations where continuity of the program is of more importance than preventing drops in data transmission. This, obviously, is a work-around for not having to tackle the source of the communication error, but sometimes you just need to struggle on. E.g., when your Arduino is out in the field and picks up occasional unwanted interference/ground noise that messes with your data transmission. See initialization parameter critical_not_alive_count.

Parameters:
  • qdev (QDeviceIO) – Reference to the parent QDeviceIO class instance, automatically set when being initialized by QDeviceIO.create_worker_DAQ().

  • DAQ_trigger (int, optional) – Mode of operation. See DAQ_TRIGGER.

    Default: DAQ_TRIGGER.INTERNAL_TIMER.

  • DAQ_function (function | None, optional) – Reference to a user-supplied function containing the device I/O operations and subsequent data processing, to be invoked every DAQ update.

    Default: None.

    Important

    The function must return True when the communication with the device was successful, and False otherwise.

    Warning

    Neither directly change the GUI, nor print to the terminal from out of this function. Doing so might temporarily suspend the function and could mess with the timing stability of the worker. (You’re basically undermining the reason to have multithreading in the first place). That could be acceptable, though, when you need to print debug or critical error information to the terminal, but be aware about the possible negative effects.

    Instead, connect to QDeviceIO.signal_DAQ_updated() from out of the main/GUI thread to instigate changes to the terminal/GUI when needed.

    Example

    Pseudo-code, where time and temperature are variables that live at a higher scope, presumably at the main scope level. The function dev.query_temperature() contains the device I/O operations, e.g., sending out a query over RS232 and collecting the device reply. In addition, the function notifies if the communication was successful. Hence, the return values of dev.query_temperature() are success as boolean and reply as a tuple containing a time stamp and a temperature reading.

    def my_DAQ_function():
        [success, reply] = dev.query_temperature()
        if not(success):
            print("Device IOerror")
            return False    # Return failure
    
        # Parse readings into separate variables and store them
        try:
            [time, temperature] = reply
        except Exception as err:
            print(err)
            return False    # Return failure
    
        return True         # Return success
    
  • DAQ_interval_ms (int, optional) – Only useful in mode DAQ_TRIGGER.INTERNAL_TIMER. Desired data-acquisition update interval in milliseconds.

    Default: 100.

  • DAQ_timer_type (PyQt5.QtCore.Qt.TimerType, optional) – Only useful in mode DAQ_TRIGGER.INTERNAL_TIMER. The update interval is timed to a QTimer running inside Worker_DAQ. The default value PyQt5.QtCore.Qt.TimerType.PreciseTimer tries to ensure the best possible timer accuracy, usually ~1 ms granularity depending on the OS, but it is resource heavy so use sparingly. One can reduce the CPU load by setting it to less precise timer types PyQt5.QtCore.Qt.TimerType.CoarseTimer or PyQt5.QtCore.Qt.TimerType.VeryCoarseTimer.

    Default: PyQt5.QtCore.Qt.TimerType.PreciseTimer.

  • critical_not_alive_count (int, optional) – The worker will allow for up to a certain number of consecutive communication failures with the device, before hope is given up and a QDeviceIO.signal_connection_lost() is emitted. Use at your own discretion.

    Default: 1.

  • debug (bool, optional) – Print debug info to the terminal? Warning: Slow! Do not leave on unintentionally.

    Default: False.

  • **kwargs – All remaining keyword arguments will be passed onto inherited class QObject.

Attributes:

qdev

Reference to the parent QDeviceIO class instance.

Type:QDeviceIO
dev

Reference to the user-supplied device class instance containing I/O methods, automatically set when calling QDeviceIO.create_worker_DAQ(). It is a shorthand for self.qdev.dev.

Type:object | None
DAQ_function

See the similarly named initialization parameter.

Type:function | None
critical_not_alive_count

See the similarly named initialization parameter.

Type:int

Methods

Worker_DAQ.pause()[source]

Only useful in mode DAQ_TRIGGER.CONTINUOUS. Pause the worker to stop listening for data. After worker_DAQ has achieved the paused state, it will emit signal_DAQ_paused().

This method should not be called from another thread. Connect this slot to a signal instead.

Worker_DAQ.unpause()[source]

Only useful in mode DAQ_TRIGGER.CONTINUOUS. Unpause the worker to resume listening for data. Once worker_DAQ has successfully resumed, it will emit signal_DAQ_updated() for every DAQ update.

This method should not be called from another thread. Connect this slot to a signal instead.

Worker_DAQ.wake_up()[source]

Only useful in mode DAQ_TRIGGER.SINGLE_SHOT_WAKE_UP. See the description at QDeviceIO.wake_up_DAQ().

This method can be called from another thread.