Skip to content
Snippets Groups Projects
Commit fa7b4e35 authored by Schmidt, Christoph's avatar Schmidt, Christoph
Browse files

UI now runs again - Added new files

parent 98571c73
No related branches found
No related tags found
No related merge requests found
# - 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 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 total_samples: 200000 # total_samples: None
sample_time: 45 # sample_time: 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 ad2_raw_out_file: "{output_directory}/measurement/ad2_raw/ad2_out_{wafer_nr}_{date}.csv" # ad2_raw_out_file: None
...@@ -26,8 +26,9 @@ if __name__ == "__main__": ...@@ -26,8 +26,9 @@ if __name__ == "__main__":
) )
app = QApplication()
setup_logging() setup_logging()
app = QApplication()
conf = CaptDevice.Config() conf = CaptDevice.Config()
conf.load("config.yaml") conf.load("config.yaml")
......
...@@ -11,9 +11,25 @@ class CaptDeviceConfig(cfg.ConfigNode): ...@@ -11,9 +11,25 @@ class CaptDeviceConfig(cfg.ConfigNode):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() 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.total_samples = cfg.Field(200000)
self.sample_time = cfg.Field(45) 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.ad2_raw_out_file = cfg.Field("{output_directory}/measurement/ad2_raw/ad2_out_{wafer_nr}_{date}.csv")
self.register() self.register()
#!/.venv/Scripts/python #!/.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 controller.BaseAD2CaptDevice import BaseAD2CaptDevice
from model.AD2CaptDeviceModel import AD2CaptDeviceModel from model.AD2CaptDeviceModel import AD2CaptDeviceModel
from constants.dwfconstants import enumfilterUSB, enumfilterType from constants.dwfconstants import enumfilterUSB, enumfilterType, enumfilterDemo
class AD2CaptDeviceController(BaseAD2CaptDevice): class AD2CaptDeviceController(BaseAD2CaptDevice):
...@@ -16,11 +16,44 @@ class AD2CaptDeviceController(BaseAD2CaptDevice): ...@@ -16,11 +16,44 @@ class AD2CaptDeviceController(BaseAD2CaptDevice):
# This is required for acquiring the data # This is required for acquiring the data
def connect_device(self, device_id): def connect_device(self, device_id):
self.start_device_process(device_id, channel=0) self.start_device_process(device_id)
return True 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): def discover_connected_devices(self):
# enumerate connected devices # enumerate connected devices
...@@ -32,8 +65,8 @@ class AD2CaptDeviceController(BaseAD2CaptDevice): ...@@ -32,8 +65,8 @@ class AD2CaptDeviceController(BaseAD2CaptDevice):
# (c_int32(enumfilterType.value | enumfilterAudio.value), 'Audio'), # (c_int32(enumfilterType.value | enumfilterAudio.value), 'Audio'),
# (c_int32(enumfilterType.value | enumfilterDemo.value), 'Demo')]: # (c_int32(enumfilterType.value | enumfilterDemo.value), 'Demo')]:
cDevice = c_int() cDevice = c_int()
filter, type = (c_int32(enumfilterType.value | enumfilterUSB.value), 'USB') # 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 | enumfilterDemo.value), 'USB')
self.dwf.FDwfEnum(filter, byref(cDevice)) self.dwf.FDwfEnum(filter, byref(cDevice))
self.model.num_of_connected_devices = cDevice self.model.num_of_connected_devices = cDevice
...@@ -43,22 +76,28 @@ class AD2CaptDeviceController(BaseAD2CaptDevice): ...@@ -43,22 +76,28 @@ class AD2CaptDeviceController(BaseAD2CaptDevice):
for iDevice in range(0, cDevice.value): for iDevice in range(0, cDevice.value):
self.dwf.FDwfEnumDeviceName(c_int(iDevice), devicename) self.dwf.FDwfEnumDeviceName(c_int(iDevice), devicename)
self.dwf.FDwfEnumSN(c_int(iDevice), serialnum) 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, 'type': type,
'device_id': int(iDevice), 'device_id': int(iDevice),
'device_name': str(devicename.value.decode('UTF-8')), '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.logger.info(connected_devices)
self.model.connected_devices = 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 return self.model.connected_devices
def close_device(self): def close_device(self):
self.end_process_flag.value = 1 self.end_process_flag.value = 1
# def _open_device(self, device_index): # def _open_device(self, device_index):
# devicename = create_string_buffer(64) # devicename = create_string_buffer(64)
# serialnum = create_string_buffer(16) # serialnum = create_string_buffer(16)
......
...@@ -32,15 +32,15 @@ class BaseAD2CaptDevice(QObject): ...@@ -32,15 +32,15 @@ class BaseAD2CaptDevice(QObject):
self.lock = Lock() self.lock = Lock()
self.proc = None self.proc = None
self.stream_data_queue = Queue() self.stream_data_queue = Queue()
self.capture_data_queue = Queue() self.capture_data_queue = Queue()
self.state_queue = Queue() self.state_queue = Queue()
self.start_capture_flag = Value('i', 0, lock=self.lock) self.start_capture_flag = Value('i', 0, lock=self.lock)
self.end_process_flag = Value('i', False, lock=self.lock) self.end_process_flag = Value('i', False, lock=self.lock)
# Number of sa # 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.status_dqueue = deque(maxlen=int(1))
self.unconsumed_capture_data = 0 self.unconsumed_capture_data = 0
...@@ -84,16 +84,17 @@ class BaseAD2CaptDevice(QObject): ...@@ -84,16 +84,17 @@ class BaseAD2CaptDevice(QObject):
self.logger.info(f"[{self.pref} Task] >>>>>>>>>>> Reset acquisition!") self.logger.info(f"[{self.pref} Task] >>>>>>>>>>> Reset acquisition!")
def _init_device_parameters(self): def _init_device_parameters(self):
sample_rate = int(self.model.ad2captdev_config.get_sample_rate()) pass
total_samples = int(self.model.ad2captdev_config.get_total_samples()) #sample_rate = int(self.model.ad2captdev_config.get_sample_rate())
channel = 0 # TODO Read channel from input #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.sample_rate = int(sample_rate)
self.model.selected_ain_channel = int(channel) #self.model.n_samples = int(total_samples)
self.logger.info(f"AD2 device initialized {self.model.selected_ain_channel} with " #self.model.selected_ain_channel = int(channel)
f"acquisition rate {self.model.sample_rate} Hz and " #self.logger.info(f"AD2 device initialized {self.model.selected_ain_channel} with "
f"samples {self.model.n_samples}") # f"acquisition rate {self.model.sample_rate} Hz and "
# f"samples {self.model.n_samples}")
# ================================================================================================================== # ==================================================================================================================
# #
...@@ -136,16 +137,17 @@ class BaseAD2CaptDevice(QObject): ...@@ -136,16 +137,17 @@ class BaseAD2CaptDevice(QObject):
self.model.capturing_finished = False 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...") self.logger.info(f"[{self.pref} Task] Starting capturing process...")
print(f"maxlen={int(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.data_dqueue = deque(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) #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, self.proc = Process(target=mp_capture,
args=( args=(
self.stream_data_queue, self.capture_data_queue, self.state_queue, self.stream_data_queue, self.capture_data_queue, self.state_queue,
self.start_capture_flag, self.end_process_flag, 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() self.proc.start()
...@@ -163,23 +165,28 @@ class BaseAD2CaptDevice(QObject): ...@@ -163,23 +165,28 @@ class BaseAD2CaptDevice(QObject):
[self.model.recorded_samples.append(e) for e in d] [self.model.recorded_samples.append(e) for e in d]
# self.model.samples_captured = len(self.model.recorded_samples) # self.model.samples_captured = len(self.model.recorded_samples)
self.status_dqueue.append(s) self.status_dqueue.append(s)
time.sleep(0.01) #time.sleep(0.01)
self.logger.info("Capture Data consume thread ended") self.logger.info("Capture Data consume thread ended")
def qt_stream_data(self): def qt_stream_data(self):
nth_cnt = 1
nth = 2
while not self.kill_thread and not bool(self.end_process_flag.value): while not self.kill_thread and not bool(self.end_process_flag.value):
while self.stream_data_queue.qsize() > 0: while self.stream_data_queue.qsize() > 0:
self.model.unconsumed_stream_samples = self.stream_data_queue.qsize() self.model.unconsumed_stream_samples = self.stream_data_queue.qsize()
for d in self.stream_data_queue.get(block=True)[0]: for d in self.stream_data_queue.get()[0]:
self.data_dqueue.append(d) #if nth_cnt == nth:
time.sleep(0.01) self.streaming_data_dqueue.append(d)
# nth_cnt = 0
#nth_cnt += 1
#time.sleep(0.01)
self.logger.info("Streaming data consume thread ended") self.logger.info("Streaming data consume thread ended")
def qt_get_state(self): def qt_get_state(self):
while not self.kill_thread and not bool(self.end_process_flag.value): while not self.kill_thread and not bool(self.end_process_flag.value):
while self.state_queue.qsize() > 0: while self.state_queue.qsize() > 0:
self._set_ad2state_from_process(self.state_queue.get()) 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") self.logger.info("Status data consume thread ended")
def _set_ad2state_from_process(self, ad2state: AD2State): def _set_ad2state_from_process(self, ad2state: AD2State):
......
from ctypes import c_int, c_byte from ctypes import c_int, c_byte
from model.AD2Constants import AD2Constants
class AD2State: class AD2State:
def __init__(self): def __init__(self):
...@@ -29,7 +31,7 @@ class AD2State: ...@@ -29,7 +31,7 @@ class AD2State:
self._aout_channels: list = [] self._aout_channels: list = []
# Acquired Signal Information # Acquired Signal Information
self._acquisition_state: c_byte = c_byte() self._acquisition_state: int = AD2Constants.CapturingState.STOPPED()
self._recording_time: float = -1 self._recording_time: float = -1
self._samples_captured: int = 0 self._samples_captured: int = 0
self._samples_lost: int = -1 self._samples_lost: int = -1
...@@ -39,6 +41,7 @@ class AD2State: ...@@ -39,6 +41,7 @@ class AD2State:
self._device_ready: bool = False self._device_ready: bool = False
self._device_capturing = False self._device_capturing = False
def reinit(self, fields: dict): def reinit(self, fields: dict):
for k, v in fields.items(): for k, v in fields.items():
setattr(self, k, v) setattr(self, k, v)
...@@ -180,7 +183,7 @@ class AD2StateMPSetter(AD2State): ...@@ -180,7 +183,7 @@ class AD2StateMPSetter(AD2State):
@AD2State.selected_ain_channel.setter @AD2State.selected_ain_channel.setter
def selected_ain_channel(self, value): def selected_ain_channel(self, value):
self._selected_channel = value self._selected_ain_channel = value
self._state_queue.put(self.to_simple_class()) self._state_queue.put(self.to_simple_class())
# =========== Analog In Information # =========== Analog In Information
......
...@@ -6,6 +6,7 @@ christoph.schmidt@tugraz.at ...@@ -6,6 +6,7 @@ christoph.schmidt@tugraz.at
""" """
import os import os
import random
import sys import sys
import time import time
from ctypes import c_int, byref, c_double, cdll, create_string_buffer, c_int32 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 ...@@ -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 controller.mp_AD2Capture.AD2StateMPSetter import AD2StateMPSetter
from model.AD2Constants import AD2Constants from model.AD2Constants import AD2Constants
from constants.dwfconstants import acqmodeRecord, DwfStateConfig, DwfStatePrefill, DwfStateArmed, enumfilterType, \ from constants.dwfconstants import acqmodeRecord, DwfStateConfig, DwfStatePrefill, DwfStateArmed, enumfilterType, \
enumfilterUSB enumfilterUSB, enumfilterDemo
# ====================================================================================================================== # ======================================================================================================================
...@@ -38,7 +39,7 @@ def _mp_log_warning(msg, prefix="AD2 Thread"): ...@@ -38,7 +39,7 @@ def _mp_log_warning(msg, prefix="AD2 Thread"):
# ====================================================================================================================== # ======================================================================================================================
# Process Main function, used for capturing and streaming data # 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, start_capture, end_process,
device_id, channel, sample_rate): device_id, channel, sample_rate):
""" """
...@@ -49,7 +50,7 @@ def mp_capture(data_queue, capture_data_queue, state_queue, ...@@ -49,7 +50,7 @@ def mp_capture(data_queue, capture_data_queue, state_queue,
:param end_process: :param end_process:
:param device_id: :param device_id:
:param sample_rate: :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. :param channel: Channel to capture data from.
:return: None :return: None
""" """
...@@ -58,8 +59,8 @@ def mp_capture(data_queue, capture_data_queue, state_queue, ...@@ -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 # Using the modulo operation allow us to determine the variable stream_n that is required
# to scale down the streaming rate. # to scale down the streaming rate.
stream_rate = 1000 # Hz stream_rate = 1000 # Hz
stream_n = sample_rate / stream_rate #stream_n = sample_rate / stream_rate
stream_sample_cnt = 0 #stream_sample_cnt = 0
time_capture_started = 0 time_capture_started = 0
capturing_notified = False capturing_notified = False
...@@ -69,9 +70,11 @@ def mp_capture(data_queue, capture_data_queue, state_queue, ...@@ -69,9 +70,11 @@ def mp_capture(data_queue, capture_data_queue, state_queue,
ad2_state.pid = os.getpid() ad2_state.pid = os.getpid()
ad2_state.channel = channel ad2_state.selected_ain_channel = channel
ad2_state.sample_rate = sample_rate 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) dwf, hdwf = _mp_open_device(device_id, ad2_state)
...@@ -95,10 +98,11 @@ def mp_capture(data_queue, capture_data_queue, state_queue, ...@@ -95,10 +98,11 @@ def mp_capture(data_queue, capture_data_queue, state_queue,
dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1)) dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1))
_mp_log_info("Device configured. Starting acquisition.") _mp_log_info("Device configured. Starting acquisition.")
ad2_state.selected_ain_channel = channel
cSamples = 0 cSamples = 0
ad2_state.device_ready = True ad2_state.device_ready = True
capture_samples = 0 capture_samples = 0
while end_process.value == False: while end_process.value == False:
# Checks the state of the acquisition. To read the data from the device, set fReadData to TRUE. For # 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 # 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, ...@@ -132,12 +136,17 @@ def mp_capture(data_queue, capture_data_queue, state_queue,
# cAvailable = c_int(self.ad2capt_model.n_samples - cSamples) # cAvailable = c_int(self.ad2capt_model.n_samples - cSamples)
rgdSamples = (c_double * cAvailable.value)() 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 cAvailable) # get channel data
# Print how many samples are available # Print how many samples are available
status = {"available": cAvailable.value, 'captured': 0, 'lost': cLost.value, status = {"available": cAvailable.value, 'captured': 0, 'lost': cLost.value,
'corrupted': cCorrupted.value, "time": time.time()} '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 start_capture.value == 1:
if not capturing_notified: if not capturing_notified:
...@@ -209,7 +218,7 @@ def _t_setup_sine_wave(dwf, hdwf, ad2_state: AD2StateMPSetter): ...@@ -209,7 +218,7 @@ def _t_setup_sine_wave(dwf, hdwf, ad2_state: AD2StateMPSetter):
_mp_log_debug("Generating AM sine wave...") _mp_log_debug("Generating AM sine wave...")
dwf.FDwfAnalogOutNodeEnableSet(hdwf, c_int(0), c_int(0), c_int(1)) # carrier 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.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.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.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 # dwf.FDwfAnalogOutNodeEnableSet(hdwf, c_int(0), c_int(2), c_int(1)) # AM
...@@ -250,7 +259,7 @@ def _mp_discover_connected_devices(dwf): ...@@ -250,7 +259,7 @@ def _mp_discover_connected_devices(dwf):
# (c_int32(enumfilterType.value | enumfilterAudio.value), 'Audio'), # (c_int32(enumfilterType.value | enumfilterAudio.value), 'Audio'),
# (c_int32(enumfilterType.value | enumfilterDemo.value), 'Demo')]: # (c_int32(enumfilterType.value | enumfilterDemo.value), 'Demo')]:
cDevice = c_int() 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') # filter, type = (c_int32(enumfilterType.value | enumfilterDemo.value), 'DEMO')
_mp_log_debug(f"Filtering {type} devices...") _mp_log_debug(f"Filtering {type} devices...")
dwf.FDwfEnum(filter, byref(cDevice)) dwf.FDwfEnum(filter, byref(cDevice))
...@@ -268,7 +277,7 @@ def _mp_discover_connected_devices(dwf): ...@@ -268,7 +277,7 @@ def _mp_discover_connected_devices(dwf):
'device_name': str(devicename.value.decode('UTF-8')), 'device_name': str(devicename.value.decode('UTF-8')),
'serial_number': str(serialnum.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(connected_devices)
# print(f"Discoverd {len(self.model.connected_devices)} devices.") # print(f"Discoverd {len(self.model.connected_devices)} devices.")
return connected_devices return connected_devices
......
...@@ -28,6 +28,7 @@ class AD2CaptDeviceSignals(QObject): ...@@ -28,6 +28,7 @@ class AD2CaptDeviceSignals(QObject):
# Acquisition Settings # Acquisition Settings
sample_rate_changed = Signal(int) sample_rate_changed = Signal(int)
streaming_rate_changed = Signal(int)
selected_ain_channel_changed = Signal(int) selected_ain_channel_changed = Signal(int)
duration_streaming_history_changed = Signal(int) duration_streaming_history_changed = Signal(int)
...@@ -120,6 +121,8 @@ class AD2CaptDeviceModel: ...@@ -120,6 +121,8 @@ class AD2CaptDeviceModel:
# Acquisition Settings # Acquisition Settings
self._sample_rate: int = self.ad2captdev_config.sample_rate.value 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._selected_ain_channel: int = 0
self._duration_streaming_history: float = 0 self._duration_streaming_history: float = 0
...@@ -286,8 +289,18 @@ class AD2CaptDeviceModel: ...@@ -286,8 +289,18 @@ class AD2CaptDeviceModel:
@sample_rate.setter @sample_rate.setter
def sample_rate(self, value): def sample_rate(self, value):
self._sample_rate = value self._sample_rate = value
self.signals.sample_rate_changed.emit(self._sample_rate)
self.ad2captdev_config.sample_rate.set(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 @property
def selected_ain_channel(self) -> int: def selected_ain_channel(self) -> int:
...@@ -299,6 +312,7 @@ class AD2CaptDeviceModel: ...@@ -299,6 +312,7 @@ class AD2CaptDeviceModel:
self._selected_ain_channel = int(value.value) self._selected_ain_channel = int(value.value)
else: else:
self._selected_ain_channel = int(value) 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) self.signals.selected_ain_channel_changed.emit(self.selected_ain_channel)
@property @property
......
import logging import logging
from collections import deque
import numpy as np import numpy as np
...@@ -31,6 +32,8 @@ class ControlWindow(QMainWindow): ...@@ -31,6 +32,8 @@ class ControlWindow(QMainWindow):
self._ui = Ui_AD2ControlWindow() self._ui = Ui_AD2ControlWindow()
self._ui.setupUi(self) self._ui.setupUi(self)
self._ui.btn_start_capture = PlayPushButton(self._ui.btn_start_capture)
# #
self.capt_info = WidgetCapturingInformation() self.capt_info = WidgetCapturingInformation()
...@@ -47,11 +50,11 @@ class ControlWindow(QMainWindow): ...@@ -47,11 +50,11 @@ class ControlWindow(QMainWindow):
# Timer for periodically updating the plot # Timer for periodically updating the plot
self.capture_update_timer = QTimer() 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.capture_update_timer.timeout.connect(self._on_capture_update_plot)
self.stream_update_timer = QTimer() 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_update_timer.timeout.connect(self._on_stream_update_timer_timeout)
self.stream_samples_frequency = 1000 self.stream_samples_frequency = 1000
...@@ -75,8 +78,13 @@ class ControlWindow(QMainWindow): ...@@ -75,8 +78,13 @@ class ControlWindow(QMainWindow):
self._ui.btn_start_capture.clicked.connect(self.on_btn_start_capture_clicked) 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.btn_stop.clicked.connect(self.on_btn_stop_clicked)
# self._ui.sb_acquisition_rate.valueChanged.connect(self.on_btn_stop_clicked) self._ui.cb_device_select.currentIndexChanged.connect(self._on_device_selected_changed)
self.model.ad2captdev_config.sample_rate.view.add_new_view(self._ui.sb_acquisition_rate) 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( self._ui.cb_duration_streaming_history.currentIndexChanged.connect(
...@@ -97,8 +105,8 @@ class ControlWindow(QMainWindow): ...@@ -97,8 +105,8 @@ class ControlWindow(QMainWindow):
self.model.signals.device_index_changed.connect(self._on_device_index_changed) self.model.signals.device_index_changed.connect(self._on_device_index_changed)
# Acquisition Settings # Acquisition Settings
self.model.signals.sample_rate_changed.connect(self._on_sample_rate_changed) self.model.signals.sample_rate_changed.connect(self._model_on_sample_rate_changed)
self.model.signals.selected_ain_channel_changed.connect(self._on_selected_ain_channel_changed) self.model.signals.selected_ain_channel_changed.connect(self._model_on_selected_ain_changed)
# Analog In Information # Analog In Information
self.model.signals.ain_channels_changed.connect(self._on_ain_channels_changed) self.model.signals.ain_channels_changed.connect(self._on_ain_channels_changed)
...@@ -170,6 +178,11 @@ class ControlWindow(QMainWindow): ...@@ -170,6 +178,11 @@ class ControlWindow(QMainWindow):
# ================================================================================================================== # ==================================================================================================================
# Slots for Model # 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): def _on_dwf_version_changed(self, dwf_version):
self.dev_info.dwf_version = dwf_version self.dev_info.dwf_version = dwf_version
# self.ad2_settings['DWF Version'] = dwf_version # self.ad2_settings['DWF Version'] = dwf_version
...@@ -213,16 +226,29 @@ class ControlWindow(QMainWindow): ...@@ -213,16 +226,29 @@ class ControlWindow(QMainWindow):
self.update_ad2_settings_list_view() self.update_ad2_settings_list_view()
def _on_device_index_changed(self, device_index): def _on_device_index_changed(self, device_index):
pass print(device_index)
# ============== Acquisition Settings # ============== 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.setRange(1, 1e9)
self._ui.sb_acquisition_rate.setValue(sample_rate) 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): def _on_selected_ain_channel_changed(self, channel):
self.dev_info.analog_in_channel = channel self.dev_info.analog_in_channel = channel
self._ui.cb_channel_select.setCurrentIndex(channel)
# ============== Analog In Information # ============== Analog In Information
def _on_ain_channels_changed(self, list_of_ad_ins): def _on_ain_channels_changed(self, list_of_ad_ins):
...@@ -319,19 +345,22 @@ class ControlWindow(QMainWindow): ...@@ -319,19 +345,22 @@ class ControlWindow(QMainWindow):
self.logger.debug(f"Start Recording: {start_recording}") self.logger.debug(f"Start Recording: {start_recording}")
if start_recording: if start_recording:
self._ui.btn_stop.setEnabled(True) 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") self._ui.btn_start_capture.setText("Pause Capture")
def _on_stop_recording_changed(self, stop_recording): def _on_stop_recording_changed(self, stop_recording):
self.logger.debug(f"Stop Recording: {stop_recording}") self.logger.debug(f"Stop Recording: {stop_recording}")
if stop_recording: if stop_recording:
self._ui.btn_stop.setEnabled(False) 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") self._ui.btn_start_capture.setText("Start Capture")
def _on_pause_recording_changed(self, pause_recording): def _on_pause_recording_changed(self, pause_recording):
self._ui.btn_stop.setEnabled(True) 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): def _on_reset_recording_changed(self, reset_recording):
pass pass
...@@ -363,7 +392,9 @@ class ControlWindow(QMainWindow): ...@@ -363,7 +392,9 @@ class ControlWindow(QMainWindow):
def _on_stream_update_timer_timeout(self): def _on_stream_update_timer_timeout(self):
self.scope_original.clear() self.scope_original.clear()
# print(self.ad2device.recorded_samples) # 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) self._ui.lcd_unconsumed_stream.display(self.model.unconsumed_stream_samples)
...@@ -398,7 +429,6 @@ class ControlWindow(QMainWindow): ...@@ -398,7 +429,6 @@ class ControlWindow(QMainWindow):
self.controller.stop_capture() self.controller.stop_capture()
self._ui.btn_start_capture.setText("Start Capture") self._ui.btn_start_capture.setText("Start Capture")
self._ui.btn_stop.setEnabled(False) self._ui.btn_stop.setEnabled(False)
self._ui.btn_start_capture.setStyleSheet(CSSPlayPushButton.style_play())
self.capture_update_timer.stop() self.capture_update_timer.stop()
self.scope_captured.clear() self.scope_captured.clear()
...@@ -409,6 +439,7 @@ class ControlWindow(QMainWindow): ...@@ -409,6 +439,7 @@ class ControlWindow(QMainWindow):
def _on_cb_duration_streaming_history_currentIndexChanged(self, index): def _on_cb_duration_streaming_history_currentIndexChanged(self, index):
self.model.duration_streaming_history = self._ui.cb_duration_streaming_history.currentData() 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))
# ================================================================================================================== # ==================================================================================================================
# #
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment