diff --git a/examples/config.yaml b/examples/config.yaml index f66a907d5d5ece99c931271f43a9506725b3bea9..60506c6da0dade93e86b6235bd9fc0afb78e5711 100644 --- a/examples/config.yaml +++ b/examples/config.yaml @@ -1,6 +1,10 @@ -# - Configuration file stored 2023-11-09 09:34:42.752230 - +# - Configuration file stored 2023-11-09 16:31:39.113641 - CaptDeviceConfig: #!!python/object:controller.CaptDeviceConfig - sample_rate: 50000 # sample_rate: None + sample_rate: 50000 # Sample rate: Sample rate of the device + streaming_rate: 500 # Streaming rate: Streaming rate in Hz (should be below 1kHz) + ain_channel: 0 # Analog In Channel: Analog in channel. Defines which channel is used for capturing. + show_simulator: True # Show Simulators: Show available simulators in the device list provided by the DreamWaves API. + streaming_history: 2000 # Streaming history (ms): Defines the range of the stream in ms total_samples: 200000 # total_samples: None sample_time: 45 # sample_time: None ad2_raw_out_file: "{output_directory}/measurement/ad2_raw/ad2_out_{wafer_nr}_{date}.csv" # ad2_raw_out_file: None diff --git a/examples/main.py b/examples/main.py index 69e74543d7ff25d589fd803ae543252685e4a621..765617a57d1f6f0a96f7ec20f58b7a5a4c26fb4a 100644 --- a/examples/main.py +++ b/examples/main.py @@ -26,8 +26,9 @@ if __name__ == "__main__": ) - app = QApplication() setup_logging() + app = QApplication() + conf = CaptDevice.Config() conf.load("config.yaml") diff --git a/src/CaptDeviceControl/CaptDeviceConfig.py b/src/CaptDeviceControl/CaptDeviceConfig.py index 00f4490771ac3db4e5cec26de0359fc6465d7bc8..273afe6d7326646355ec6e11e2345959f0a80e02 100644 --- a/src/CaptDeviceControl/CaptDeviceConfig.py +++ b/src/CaptDeviceControl/CaptDeviceConfig.py @@ -11,9 +11,25 @@ class CaptDeviceConfig(cfg.ConfigNode): def __init__(self) -> None: super().__init__() - self.sample_rate = cfg.Field(50000) + self.sample_rate = cfg.Field(50000, friendly_name="Sample rate", + description="Sample rate of the device") + self.streaming_rate = cfg.Field(500, friendly_name="Streaming rate", + description="Streaming rate in Hz (should be below 1kHz)") + + self.ain_channel = cfg.Field(0, friendly_name="Analog In Channel", + description="Analog in channel. Defines which channel is used for capturing.") + self.show_simulator = cfg.Field(True, friendly_name="Show Simulators", + description="Show available simulators in the device list " + "provided by the DreamWaves API.") + self.streaming_history = cfg.Field(2000, friendly_name="Streaming history (ms)", + description="Defines the range of the stream in ms") + + + + # TODO: Old configs (not used and will probably removed in future) self.total_samples = cfg.Field(200000) self.sample_time = cfg.Field(45) self.ad2_raw_out_file = cfg.Field("{output_directory}/measurement/ad2_raw/ad2_out_{wafer_nr}_{date}.csv") + self.register() diff --git a/src/CaptDeviceControl/controller/AD2CaptDeviceController.py b/src/CaptDeviceControl/controller/AD2CaptDeviceController.py index 4d7b9739e1f82e122d551fa1b2dc575112ff9460..201bc06813020c4c236c6bb9567839bf8b8cbfa6 100644 --- a/src/CaptDeviceControl/controller/AD2CaptDeviceController.py +++ b/src/CaptDeviceControl/controller/AD2CaptDeviceController.py @@ -1,11 +1,11 @@ #!/.venv/Scripts/python -from ctypes import c_int, byref, create_string_buffer, cdll, c_int32 +from ctypes import c_int, byref, create_string_buffer, cdll, c_int32, c_uint, c_double from controller.BaseAD2CaptDevice import BaseAD2CaptDevice from model.AD2CaptDeviceModel import AD2CaptDeviceModel -from constants.dwfconstants import enumfilterUSB, enumfilterType +from constants.dwfconstants import enumfilterUSB, enumfilterType, enumfilterDemo class AD2CaptDeviceController(BaseAD2CaptDevice): @@ -16,12 +16,45 @@ class AD2CaptDeviceController(BaseAD2CaptDevice): # This is required for acquiring the data - def connect_device(self, device_id): - self.start_device_process(device_id, channel=0) + self.start_device_process(device_id) return True - + def read_hardware_config(self, iDevice): + hw_info_dict = {} + hdwf = c_int() + int0 = c_int() + int1 = c_int() + uint0 = c_uint() + dbl0 = c_double() + dbl1 = c_double() + dbl2 = c_double() + self.dwf.FDwfDeviceConfigOpen(c_int(iDevice), c_int(0), byref(hdwf)) + if hdwf.value == 0: + szerr = create_string_buffer(512) + self.dwf.FDwfGetLastErrorMsg(szerr) + raise Exception(str(szerr.value)) + + self.dwf.FDwfAnalogInChannelCount(hdwf, byref(int0)) + hw_info_dict["analog_in_channels"] = int(int0.value) + + self.dwf.FDwfAnalogIOChannelCount(hdwf, byref(int0)) + hw_info_dict["analog_io_channels"] = int(int0.value) + + self.dwf.FDwfAnalogInBufferSizeInfo(hdwf, 0, byref(int0)) + hw_info_dict["buffer_size"] = int(int0.value) + + self.dwf.FDwfAnalogInBitsInfo(hdwf, byref(int0)) + hw_info_dict["adc_bits"] = int(int0.value) + + self.dwf.FDwfAnalogInChannelRangeInfo(hdwf, byref(dbl0), byref(dbl1), byref(dbl2)) + hw_info_dict["range"] = (int(dbl0.value), int(dbl1.value), int(dbl2.value)) + + self.dwf.FDwfAnalogInChannelOffsetInfo(hdwf, byref(dbl0), byref(dbl1), byref(dbl2)) + hw_info_dict["offset"] = (int(dbl0.value), int(dbl1.value), int(dbl2.value)) + + return hw_info_dict + def discover_connected_devices(self): # enumerate connected devices connected_devices = [] @@ -32,8 +65,8 @@ class AD2CaptDeviceController(BaseAD2CaptDevice): # (c_int32(enumfilterType.value | enumfilterAudio.value), 'Audio'), # (c_int32(enumfilterType.value | enumfilterDemo.value), 'Demo')]: cDevice = c_int() - filter, type = (c_int32(enumfilterType.value | enumfilterUSB.value), 'USB') - #filter, type = (c_int32(enumfilterType.value | enumfilterDemo.value), 'USB') + # filter, type = (c_int32(enumfilterType.value | enumfilterUSB.value), 'USB') + filter, type = (c_int32(enumfilterType.value | enumfilterUSB.value | enumfilterDemo.value), 'USB') self.dwf.FDwfEnum(filter, byref(cDevice)) self.model.num_of_connected_devices = cDevice @@ -43,22 +76,28 @@ class AD2CaptDeviceController(BaseAD2CaptDevice): for iDevice in range(0, cDevice.value): self.dwf.FDwfEnumDeviceName(c_int(iDevice), devicename) self.dwf.FDwfEnumSN(c_int(iDevice), serialnum) - connected_devices.append({ + hw_info = self.read_hardware_config(iDevice) + srn = str(serialnum.value.decode('UTF-8')) + if "demo" in srn.lower(): + type = "Simulator " + con_dev_dict = { 'type': type, 'device_id': int(iDevice), 'device_name': str(devicename.value.decode('UTF-8')), - 'serial_number': str(serialnum.value.decode('UTF-8')) - }) + 'serial_number': srn + } + con_dev_dict = dict(con_dev_dict, **hw_info) + connected_devices.append(con_dev_dict) + self.logger.info(connected_devices) self.model.connected_devices = connected_devices - self.logger.info(f"Discoverd {len(self.model.connected_devices)} devices.") + self.logger.info(f"Discovered {len(self.model.connected_devices)} devices.") return self.model.connected_devices def close_device(self): self.end_process_flag.value = 1 - # def _open_device(self, device_index): # devicename = create_string_buffer(64) # serialnum = create_string_buffer(16) diff --git a/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py b/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py index dd64d303c8c008690db2703f4bb3747450bd3675..58a889ea84eb01b736a51e7a0e196f14cf5d517c 100644 --- a/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py +++ b/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py @@ -32,15 +32,15 @@ class BaseAD2CaptDevice(QObject): self.lock = Lock() self.proc = None self.stream_data_queue = Queue() - self.capture_data_queue = Queue() self.state_queue = Queue() + self.start_capture_flag = Value('i', 0, lock=self.lock) self.end_process_flag = Value('i', False, lock=self.lock) # Number of sa + self.streaming_data_dqueue: deque = None # a dqueue, initialize later - self.data_dqueue = None # initialize later self.status_dqueue = deque(maxlen=int(1)) self.unconsumed_capture_data = 0 @@ -84,16 +84,17 @@ class BaseAD2CaptDevice(QObject): self.logger.info(f"[{self.pref} Task] >>>>>>>>>>> Reset acquisition!") def _init_device_parameters(self): - sample_rate = int(self.model.ad2captdev_config.get_sample_rate()) - total_samples = int(self.model.ad2captdev_config.get_total_samples()) - channel = 0 # TODO Read channel from input - - self.model.sample_rate = int(sample_rate) - self.model.n_samples = int(total_samples) - self.model.selected_ain_channel = int(channel) - self.logger.info(f"AD2 device initialized {self.model.selected_ain_channel} with " - f"acquisition rate {self.model.sample_rate} Hz and " - f"samples {self.model.n_samples}") + pass + #sample_rate = int(self.model.ad2captdev_config.get_sample_rate()) + #total_samples = int(self.model.ad2captdev_config.get_total_samples()) + #channel = 0 # TODO Read channel from input + + #self.model.sample_rate = int(sample_rate) + #self.model.n_samples = int(total_samples) + #self.model.selected_ain_channel = int(channel) + #self.logger.info(f"AD2 device initialized {self.model.selected_ain_channel} with " + # f"acquisition rate {self.model.sample_rate} Hz and " + # f"samples {self.model.n_samples}") # ================================================================================================================== # @@ -136,16 +137,17 @@ class BaseAD2CaptDevice(QObject): self.model.capturing_finished = False # ================================================================================================================== - def start_device_process(self, device_id, channel=0): + def start_device_process(self, device_id): self.logger.info(f"[{self.pref} Task] Starting capturing process...") - print(f"maxlen={int(self.model.duration_streaming_history * self.model.sample_rate)}") - self.data_dqueue = deque(maxlen=int(self.model.duration_streaming_history * self.model.sample_rate)) - print(self.model.duration_streaming_history * self.model.sample_rate) + #self.logger.debug(f"Dataqueue maxlen={int(self.model.duration_streaming_history * self.model.sample_rate)}") + self.streaming_data_dqueue = deque(maxlen=int(self.model.duration_streaming_history * self.model.sample_rate)) + #print(self.model.duration_streaming_history * self.model.sample_rate) + self.stream_data_queue.maxsize = int(self.model.duration_streaming_history * self.model.sample_rate) self.proc = Process(target=mp_capture, args=( self.stream_data_queue, self.capture_data_queue, self.state_queue, self.start_capture_flag, self.end_process_flag, - device_id, channel, self.model.sample_rate) + device_id, self.model.selected_ain_channel, self.model.sample_rate) ) self.proc.start() @@ -163,23 +165,28 @@ class BaseAD2CaptDevice(QObject): [self.model.recorded_samples.append(e) for e in d] # self.model.samples_captured = len(self.model.recorded_samples) self.status_dqueue.append(s) - time.sleep(0.01) + #time.sleep(0.01) self.logger.info("Capture Data consume thread ended") def qt_stream_data(self): + nth_cnt = 1 + nth = 2 while not self.kill_thread and not bool(self.end_process_flag.value): while self.stream_data_queue.qsize() > 0: self.model.unconsumed_stream_samples = self.stream_data_queue.qsize() - for d in self.stream_data_queue.get(block=True)[0]: - self.data_dqueue.append(d) - time.sleep(0.01) + for d in self.stream_data_queue.get()[0]: + #if nth_cnt == nth: + self.streaming_data_dqueue.append(d) + # nth_cnt = 0 + #nth_cnt += 1 + #time.sleep(0.01) self.logger.info("Streaming data consume thread ended") def qt_get_state(self): while not self.kill_thread and not bool(self.end_process_flag.value): while self.state_queue.qsize() > 0: self._set_ad2state_from_process(self.state_queue.get()) - time.sleep(0.1) + #time.sleep(0.1) self.logger.info("Status data consume thread ended") def _set_ad2state_from_process(self, ad2state: AD2State): diff --git a/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py b/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py index 3e225c8c49d8770922c0165878f71ee5134db541..34c8d6759c53b0be2563c4adc5f2126267a04810 100644 --- a/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py +++ b/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py @@ -1,5 +1,7 @@ from ctypes import c_int, c_byte +from model.AD2Constants import AD2Constants + class AD2State: def __init__(self): @@ -29,7 +31,7 @@ class AD2State: self._aout_channels: list = [] # Acquired Signal Information - self._acquisition_state: c_byte = c_byte() + self._acquisition_state: int = AD2Constants.CapturingState.STOPPED() self._recording_time: float = -1 self._samples_captured: int = 0 self._samples_lost: int = -1 @@ -39,6 +41,7 @@ class AD2State: self._device_ready: bool = False self._device_capturing = False + def reinit(self, fields: dict): for k, v in fields.items(): setattr(self, k, v) @@ -180,7 +183,7 @@ class AD2StateMPSetter(AD2State): @AD2State.selected_ain_channel.setter def selected_ain_channel(self, value): - self._selected_channel = value + self._selected_ain_channel = value self._state_queue.put(self.to_simple_class()) # =========== Analog In Information diff --git a/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py b/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py index 1bdbf26a614a7d852a77a9700809004a58591276..cfa41392ba54d6a7b91b28468db64505380bfd66 100644 --- a/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py +++ b/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py @@ -6,6 +6,7 @@ christoph.schmidt@tugraz.at """ import os +import random import sys import time from ctypes import c_int, byref, c_double, cdll, create_string_buffer, c_int32 @@ -13,7 +14,7 @@ from ctypes import c_int, byref, c_double, cdll, create_string_buffer, c_int32 from controller.mp_AD2Capture.AD2StateMPSetter import AD2StateMPSetter from model.AD2Constants import AD2Constants from constants.dwfconstants import acqmodeRecord, DwfStateConfig, DwfStatePrefill, DwfStateArmed, enumfilterType, \ - enumfilterUSB + enumfilterUSB, enumfilterDemo # ====================================================================================================================== @@ -38,7 +39,7 @@ def _mp_log_warning(msg, prefix="AD2 Thread"): # ====================================================================================================================== # Process Main function, used for capturing and streaming data # ====================================================================================================================== -def mp_capture(data_queue, capture_data_queue, state_queue, +def mp_capture(stream_data_queue, capture_data_queue, state_queue, start_capture, end_process, device_id, channel, sample_rate): """ @@ -49,7 +50,7 @@ def mp_capture(data_queue, capture_data_queue, state_queue, :param end_process: :param device_id: :param sample_rate: - :param data_queue: Queue to put the data into. + :param stream_data_queue: Queue to put the data into. :param channel: Channel to capture data from. :return: None """ @@ -58,8 +59,8 @@ def mp_capture(data_queue, capture_data_queue, state_queue, # Using the modulo operation allow us to determine the variable stream_n that is required # to scale down the streaming rate. stream_rate = 1000 # Hz - stream_n = sample_rate / stream_rate - stream_sample_cnt = 0 + #stream_n = sample_rate / stream_rate + #stream_sample_cnt = 0 time_capture_started = 0 capturing_notified = False @@ -69,9 +70,11 @@ def mp_capture(data_queue, capture_data_queue, state_queue, ad2_state.pid = os.getpid() - ad2_state.channel = channel + ad2_state.selected_ain_channel = channel ad2_state.sample_rate = sample_rate - _mp_log_debug(f"Setting up device {device_id} with channel {channel} and acquisition rate {sample_rate} Hz") + _mp_log_debug(f"Setting up device {device_id} with " + f"channel {ad2_state.selected_ain_channel} and " + f"acquisition rate {ad2_state.sample_rate} Hz") dwf, hdwf = _mp_open_device(device_id, ad2_state) @@ -95,10 +98,11 @@ def mp_capture(data_queue, capture_data_queue, state_queue, dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1)) _mp_log_info("Device configured. Starting acquisition.") - ad2_state.selected_ain_channel = channel + cSamples = 0 ad2_state.device_ready = True capture_samples = 0 + while end_process.value == False: # Checks the state of the acquisition. To read the data from the device, set fReadData to TRUE. For # single acquisition mode, the data will be read only when the acquisition is finished @@ -132,12 +136,17 @@ def mp_capture(data_queue, capture_data_queue, state_queue, # cAvailable = c_int(self.ad2capt_model.n_samples - cSamples) rgdSamples = (c_double * cAvailable.value)() - dwf.FDwfAnalogInStatusData(hdwf, c_int(ad2_state.channel), byref(rgdSamples), + dwf.FDwfAnalogInStatusData(hdwf, c_int(ad2_state.selected_ain_channel), byref(rgdSamples), cAvailable) # get channel data # Print how many samples are available status = {"available": cAvailable.value, 'captured': 0, 'lost': cLost.value, 'corrupted': cCorrupted.value, "time": time.time()} - data_queue.put(([(float(s)) for it, s in enumerate(rgdSamples)], status)) + print(status) + time.sleep(random.random()) + #print(len(rgdSamples)) + stream_data_queue.put( + ([(float(s)) for s in rgdSamples], status) + ) if start_capture.value == 1: if not capturing_notified: @@ -209,7 +218,7 @@ def _t_setup_sine_wave(dwf, hdwf, ad2_state: AD2StateMPSetter): _mp_log_debug("Generating AM sine wave...") dwf.FDwfAnalogOutNodeEnableSet(hdwf, c_int(0), c_int(0), c_int(1)) # carrier dwf.FDwfAnalogOutNodeFunctionSet(hdwf, c_int(0), c_int(0), c_int(1)) # sine - dwf.FDwfAnalogOutNodeFrequencySet(hdwf, c_int(0), c_int(0), c_double(1)) + dwf.FDwfAnalogOutNodeFrequencySet(hdwf, c_int(0), c_int(0), c_double(0.1)) dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, c_int(0), c_int(0), c_double(1)) # dwf.FDwfAnalogOutNodeOffsetSet(hdwf, c_int(0), c_int(0), c_double(0.5)) # dwf.FDwfAnalogOutNodeEnableSet(hdwf, c_int(0), c_int(2), c_int(1)) # AM @@ -250,7 +259,7 @@ def _mp_discover_connected_devices(dwf): # (c_int32(enumfilterType.value | enumfilterAudio.value), 'Audio'), # (c_int32(enumfilterType.value | enumfilterDemo.value), 'Demo')]: cDevice = c_int() - filter, type = (c_int32(enumfilterType.value | enumfilterUSB.value), 'USB') + filter, type = (c_int32(enumfilterType.value | enumfilterDemo.value| enumfilterUSB.value), 'USB') # filter, type = (c_int32(enumfilterType.value | enumfilterDemo.value), 'DEMO') _mp_log_debug(f"Filtering {type} devices...") dwf.FDwfEnum(filter, byref(cDevice)) @@ -268,7 +277,7 @@ def _mp_discover_connected_devices(dwf): 'device_name': str(devicename.value.decode('UTF-8')), 'serial_number': str(serialnum.value.decode('UTF-8')) }) - _mp_log_debug(f"Found {type} device: {devicename.value.decode('UTF-8')} ({serialnum.value.decode('UTF-8')})") + #_mp_log_debug(f"Found {type} device: {devicename.value.decode('UTF-8')} ({serialnum.value.decode('UTF-8')})") # print(connected_devices) # print(f"Discoverd {len(self.model.connected_devices)} devices.") return connected_devices diff --git a/src/CaptDeviceControl/model/AD2CaptDeviceModel.py b/src/CaptDeviceControl/model/AD2CaptDeviceModel.py index 536328ef3b49dc2fa527c715ef473d9fe76f1ead..4e11ae37bfa263874664cfe8ea7483be58c07037 100644 --- a/src/CaptDeviceControl/model/AD2CaptDeviceModel.py +++ b/src/CaptDeviceControl/model/AD2CaptDeviceModel.py @@ -28,6 +28,7 @@ class AD2CaptDeviceSignals(QObject): # Acquisition Settings sample_rate_changed = Signal(int) + streaming_rate_changed = Signal(int) selected_ain_channel_changed = Signal(int) duration_streaming_history_changed = Signal(int) @@ -120,6 +121,8 @@ class AD2CaptDeviceModel: # Acquisition Settings self._sample_rate: int = self.ad2captdev_config.sample_rate.value + self._streaming_rate: int = self.ad2captdev_config.streaming_rate.value + self._selected_ain_channel: int = 0 self._duration_streaming_history: float = 0 @@ -286,8 +289,18 @@ class AD2CaptDeviceModel: @sample_rate.setter def sample_rate(self, value): self._sample_rate = value - self.signals.sample_rate_changed.emit(self._sample_rate) self.ad2captdev_config.sample_rate.set(self._sample_rate) + self.signals.sample_rate_changed.emit(self._sample_rate) + + @property + def streaming_rate(self): + return self._sample_rate + + @streaming_rate.setter + def streaming_rate(self, value): + self._streaming_rate = value + self.ad2captdev_config.streaming_rate.set(self._streaming_rate) + self.signals.streaming_rate_changed.emit(self._streaming_rate) @property def selected_ain_channel(self) -> int: @@ -299,6 +312,7 @@ class AD2CaptDeviceModel: self._selected_ain_channel = int(value.value) else: self._selected_ain_channel = int(value) + self.ad2captdev_config.ain_channel.set(self._selected_ain_channel) self.signals.selected_ain_channel_changed.emit(self.selected_ain_channel) @property diff --git a/src/CaptDeviceControl/view/AD2CaptDeviceView.py b/src/CaptDeviceControl/view/AD2CaptDeviceView.py index 7a1e322cc10a987fcccb2df9ee2edd61589cdd2c..a094b47111a9965c12e96b3c3418f98df820277a 100644 --- a/src/CaptDeviceControl/view/AD2CaptDeviceView.py +++ b/src/CaptDeviceControl/view/AD2CaptDeviceView.py @@ -1,4 +1,5 @@ import logging +from collections import deque import numpy as np @@ -31,6 +32,8 @@ class ControlWindow(QMainWindow): self._ui = Ui_AD2ControlWindow() self._ui.setupUi(self) + self._ui.btn_start_capture = PlayPushButton(self._ui.btn_start_capture) + # self.capt_info = WidgetCapturingInformation() @@ -47,11 +50,11 @@ class ControlWindow(QMainWindow): # Timer for periodically updating the plot self.capture_update_timer = QTimer() - self.capture_update_timer.setInterval(50) + self.capture_update_timer.setInterval(10) self.capture_update_timer.timeout.connect(self._on_capture_update_plot) self.stream_update_timer = QTimer() - self.stream_update_timer.setInterval(50) + self.stream_update_timer.setInterval(10) self.stream_update_timer.timeout.connect(self._on_stream_update_timer_timeout) self.stream_samples_frequency = 1000 @@ -75,8 +78,13 @@ class ControlWindow(QMainWindow): self._ui.btn_start_capture.clicked.connect(self.on_btn_start_capture_clicked) self._ui.btn_stop.clicked.connect(self.on_btn_stop_clicked) - # self._ui.sb_acquisition_rate.valueChanged.connect(self.on_btn_stop_clicked) - self.model.ad2captdev_config.sample_rate.view.add_new_view(self._ui.sb_acquisition_rate) + self._ui.cb_device_select.currentIndexChanged.connect(self._on_device_selected_changed) + self._ui.cb_channel_select.currentIndexChanged.connect(self._ui_on_selected_ain_changed) + + self._ui.sb_acquisition_rate.valueChanged.connect(self._ui_on_sample_rate_changed) + #self.model.ad2captdev_config.sample_rate.view.add_new_view(self._ui.sb_acquisition_rate) + + #self.model.ad2captdev_config.ain_channel.view.add_new_view(self._ui.cb_channel_select) #() self._ui.cb_duration_streaming_history.currentIndexChanged.connect( @@ -97,8 +105,8 @@ class ControlWindow(QMainWindow): self.model.signals.device_index_changed.connect(self._on_device_index_changed) # Acquisition Settings - self.model.signals.sample_rate_changed.connect(self._on_sample_rate_changed) - self.model.signals.selected_ain_channel_changed.connect(self._on_selected_ain_channel_changed) + self.model.signals.sample_rate_changed.connect(self._model_on_sample_rate_changed) + self.model.signals.selected_ain_channel_changed.connect(self._model_on_selected_ain_changed) # Analog In Information self.model.signals.ain_channels_changed.connect(self._on_ain_channels_changed) @@ -170,6 +178,11 @@ class ControlWindow(QMainWindow): # ================================================================================================================== # Slots for Model # ================================================================================================================== + def _on_device_selected_changed(self, index): + # First populate the AIn box+ + m: dict = self.model.connected_devices[index] + self.model.ain_channels = list(range(0, int(m['analog_in_channels']))) + def _on_dwf_version_changed(self, dwf_version): self.dev_info.dwf_version = dwf_version # self.ad2_settings['DWF Version'] = dwf_version @@ -213,16 +226,29 @@ class ControlWindow(QMainWindow): self.update_ad2_settings_list_view() def _on_device_index_changed(self, device_index): - pass + print(device_index) # ============== Acquisition Settings - def _on_sample_rate_changed(self, sample_rate: int): + + + def _model_on_sample_rate_changed(self, sample_rate: int): self._ui.sb_acquisition_rate.setRange(1, 1e9) self._ui.sb_acquisition_rate.setValue(sample_rate) + def _ui_on_sample_rate_changed(self, sample_rate: int): + self.model.sample_rate = sample_rate + + def _model_on_selected_ain_changed(self, channel): + """ Gets called if the model is changed directly (should modify the UI)""" + self._on_selected_ain_channel_changed(channel) + self._ui.cb_channel_select.setCurrentIndex(channel) + def _ui_on_selected_ain_changed(self, channel): + """ Gets called if the ui changes the field (should modify the model) """ + self._on_selected_ain_channel_changed(channel) + self.model.selected_ain_channel = channel def _on_selected_ain_channel_changed(self, channel): self.dev_info.analog_in_channel = channel - self._ui.cb_channel_select.setCurrentIndex(channel) + # ============== Analog In Information def _on_ain_channels_changed(self, list_of_ad_ins): @@ -319,19 +345,22 @@ class ControlWindow(QMainWindow): self.logger.debug(f"Start Recording: {start_recording}") if start_recording: self._ui.btn_stop.setEnabled(True) - self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_pause()) + #self._ui.btn_start_capture.setStyleSheet(PlayPushButton.style_pause()) + #self._ui.btn_start_capture.pause() self._ui.btn_start_capture.setText("Pause Capture") def _on_stop_recording_changed(self, stop_recording): self.logger.debug(f"Stop Recording: {stop_recording}") if stop_recording: self._ui.btn_stop.setEnabled(False) - self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_play()) + #self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_play()) + #self._ui.btn_start_capture.play() self._ui.btn_start_capture.setText("Start Capture") def _on_pause_recording_changed(self, pause_recording): self._ui.btn_stop.setEnabled(True) - self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_play()) + #self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_play()) + #self._ui.btn_start_capture.play() def _on_reset_recording_changed(self, reset_recording): pass @@ -363,7 +392,9 @@ class ControlWindow(QMainWindow): def _on_stream_update_timer_timeout(self): self.scope_original.clear() # print(self.ad2device.recorded_samples) - self.scope_original.plot(list(self.controller.data_dqueue)[::self.stream_n], pen=pg.mkPen(width=1)) + self.scope_original.plot( + list(self.controller.streaming_data_dqueue),#[::self.stream_n], + pen=pg.mkPen(width=1)) self._ui.lcd_unconsumed_stream.display(self.model.unconsumed_stream_samples) @@ -398,7 +429,6 @@ class ControlWindow(QMainWindow): self.controller.stop_capture() self._ui.btn_start_capture.setText("Start Capture") self._ui.btn_stop.setEnabled(False) - self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_play()) self.capture_update_timer.stop() self.scope_captured.clear() @@ -409,6 +439,7 @@ class ControlWindow(QMainWindow): def _on_cb_duration_streaming_history_currentIndexChanged(self, index): self.model.duration_streaming_history = self._ui.cb_duration_streaming_history.currentData() + self.controller.streaming_data_dqueue = deque(maxlen=int(self.model.duration_streaming_history * self.model.sample_rate)) # ================================================================================================================== #