From 397f47ca93f9fa750d955a84fcc49866a5dec6c7 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Thu, 29 Feb 2024 16:37:51 +0100 Subject: [PATCH 01/13] first version --- plugin_info.toml | 2 +- .../plugins_1D/daq_1Dviewer_BaoFadoua.py | 107 ++++++++++++++++++ .../hardware/mcc128.py | 34 ++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py create mode 100644 src/pymodaq_plugins_raspberry/hardware/mcc128.py diff --git a/plugin_info.toml b/plugin_info.toml index bf4cbf0..e594c90 100644 --- a/plugin_info.toml +++ b/plugin_info.toml @@ -13,7 +13,7 @@ license = 'MIT' [plugin-install] #packages required for your plugin: -packages-required = ['pymodaq>=4.0.0', 'picamera2'] +packages-required = ['pymodaq>=4.0.0', 'daqhats'] [features] # defines the plugin features contained into this plugin instruments = true # true if plugin contains instrument classes (else false, notice the lowercase for toml files) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py new file mode 100644 index 0000000..93ed17f --- /dev/null +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py @@ -0,0 +1,107 @@ +import numpy as np +from pymodaq.utils.daq_utils import ThreadCommand +from pymodaq.utils.data import DataFromPlugins, Axis, DataToExport +from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main +from pymodaq.utils.parameter import Parameter + +from pymodaq_plugins_raspberry.hardware.mcc128 import mcc128 + + +class DAQ_1DViewer_BaoFadoua(DAQ_Viewer_base): + """ Instrument plugin class for a 1D viewer. + + This object inherits all functionalities to communicate with PyMoDAQ’s DAQ_Viewer module through inheritance via + DAQ_Viewer_base. It makes a bridge between the DAQ_Viewer module and the Python wrapper of a particular instrument. + + Attributes: + ----------- + controller: object + The particular object that allow the communication with the hardware, in general a python wrapper around the + hardware library. + + + + """ + params = comon_parameters+[ + {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0} + + ] + + def ini_attributes(self): + self.controller: mcc128 = None + + def commit_settings(self, param: Parameter): + """Apply the consequences of a change of value in the detector settings + + Parameters + ---------- + param: Parameter + A given parameter (within detector_settings) whose value has been changed by the user + """ + ## TODO for your custom plugin + if param.name() == "nombre_points": + self.set_nb_points() + +# elif ... + ## + + def set_nb_points(self): + nb_points = self.settings['nombre_points'] + self.controller.npts = nb_points + + + def ini_detector(self, controller=None): + """Detector communication initialization + + Parameters + ---------- + controller: (object) + custom object of a PyMoDAQ plugin (Slave case). None if only one actuator/detector by controller + (Master case) + + Returns + ------- + info: str + initialized: bool + False if initialization failed otherwise True + """ + + self.ini_detector_init(old_controller=controller, + new_controller=mcc128()) + + info = "Whatever info you want to log" + initialized = True + return info, initialized + + def close(self): + pass + """Terminate the communication protocol""" + + + def grab_data(self, Naverage=1, **kwargs): + """Start a grab from the detector + + Parameters + ---------- + Naverage: int + Number of hardware averaging (if hardware averaging is possible, self.hardware_averaging should be set to + True in class preamble and you should code this implementation) + kwargs: dict + others optionals arguments + """ + + ##synchrone version (blocking function) + data, timing = self.controller.generateur(5) + xaxis = Axis('time', 'seconds', timing, 0 ) + self.dte_signal.emit(DataToExport('myplugin', + data=[DataFromPlugins(name='Mock1', data=[data], + dim='Data1D', labels=['grabed'], + axes=[xaxis])])) + + def stop(self): + """Stop the current grab hardware wise if necessary""" + return '' + + +if __name__ == '__main__': + main(__file__, init=False) diff --git a/src/pymodaq_plugins_raspberry/hardware/mcc128.py b/src/pymodaq_plugins_raspberry/hardware/mcc128.py new file mode 100644 index 0000000..b93cec5 --- /dev/null +++ b/src/pymodaq_plugins_raspberry/hardware/mcc128.py @@ -0,0 +1,34 @@ +import numpy as np +import numpy as py + + + + +class mcc128: + + def __init__(self): + self._npts: int = 1000 + + @property + def npts(self): + return self._npts + + @npts.setter + def npts(self, npt: int): + if not isinstance(npt, int): + raise TypeError("") + elif npt < 1: + raise ValueError("") + self._npts = npt + + def get_x_axis(self, nbre_point, freq_echatillonage ): + te = np.linspace(0, (nbre_point - 1) / freq_echatillonage, nbre_point) + return te + + def generateur(self, duree: float): + freq = self.npts / duree + ts = self.get_x_axis(self.npts, freq) + return np.sin(2 * np.pi * ts), ts + + + From f390539e9d103587a532757e230e5f66e3248f0e Mon Sep 17 00:00:00 2001 From: bkav456 Date: Thu, 29 Feb 2024 16:53:54 +0100 Subject: [PATCH 02/13] first plugin --- .../plugins_1D/daq_1Dviewer_BaoFadoua.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py index 93ed17f..aeda341 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py @@ -23,9 +23,10 @@ class DAQ_1DViewer_BaoFadoua(DAQ_Viewer_base): """ params = comon_parameters+[ - {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0} + {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0}, + {'title': 'Duree:', 'name': 'duree', 'type': 'float', 'value': 5, 'min': 0} - ] + ] def ini_attributes(self): self.controller: mcc128 = None @@ -91,7 +92,7 @@ def grab_data(self, Naverage=1, **kwargs): """ ##synchrone version (blocking function) - data, timing = self.controller.generateur(5) + data, timing = self.controller.generateur(self.settings['duree']) xaxis = Axis('time', 'seconds', timing, 0 ) self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=[data], From bab2184c7b8ca1543d9525f79c8109738096ffb2 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Tue, 5 Mar 2024 11:54:02 +0100 Subject: [PATCH 03/13] First version plugin mcc128 --- .../plugins_1D/daq_1Dviewer_daqhats.py | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py new file mode 100644 index 0000000..e575842 --- /dev/null +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -0,0 +1,128 @@ +import numpy as np +from pymodaq.utils.daq_utils import ThreadCommand +from pymodaq.utils.data import DataFromPlugins, Axis, DataToExport +from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main +from pymodaq.utils.parameter import Parameter + +from pymodaq_plugins_raspberry.hardware.mcc128 import mcc128 +from daqhats import mcc128 ,OptionFlags, AnalogInputMode, TriggerModes + + +class DAQ_1DViewer_daqhats(DAQ_Viewer_base): + """ Instrument plugin class for a 1D viewer. + + This object inherits all functionalities to communicate with PyMoDAQ’s DAQ_Viewer module through inheritance via + DAQ_Viewer_base. It makes a bridge between the DAQ_Viewer module and the Python wrapper of a particular instrument. + + Attributes: + ----------- + controller: object + The particular object that allow the communication with the hardware, in general a python wrapper around the + hardware library. + + + + """ + params = comon_parameters+[ + {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0, 'max' : 100000}, + {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0}, + {'title': 'Range', 'name': 'range', 'type': 'list', 'value':10 , 'limits':[10, 5, 2 ,1] }, + {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'DIFFERENTIAL', 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, + {'title': 'Single_End_Channel', 'name': 'channel_single', 'type': 'list', 'value': 'CH0H', 'limits': ['CHOH', 'CH1H', 'CH2H', 'CH3H', 'CH0L',\ + 'CH1L', 'CH2L', 'CH3L']}, + {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'NONE', 'limits': ['NONE', 'RISING_EDGE' ,'FALLING_EDGE', 'ACTIVE_HIGH', \ + 'ACTIVE_LOW']}, + {'title': 'Option' , 'name':'option', 'type': 'list', 'value': 'DEFAUT', 'limits': ['DEFAUT', 'NOSCALEDATA', 'NOCALIBRATEDATA']} + + + ] + + def ini_attributes(self): + self.controller: mcc128 = None + self.option = OptionFlags.DEFAULT + self.controller.a_in_mode_write(0) + self.controller.a_in_range_write(0) + + + + def commit_settings(self, param: Parameter): + """Apply the consequences of a change of value in the detector settings + + Parameters + ---------- + param: Parameter + A given parameter (within detector_settings) whose value has been changed by the user + """ + ## TODO for your custom plugin + if param.name() == "nombre_points": + self.set_nb_points() + +# elif ... + ## + + def scan_data(self): + self.controller.a_in_scan_start(1, self.settings['nombre_points'], self.settings['frequency'], self.option) + voltage = self.controller.a_in_scan_read(self.settings['nb_points'], 0) + self.controller.a_in_scan_stop() + self.controller.a_in_scan_cleanup() + return voltage + + + + def ini_detector(self, controller=None): + """Detector communication initialization + + Parameters + ---------- + controller: (object) + custom object of a PyMoDAQ plugin (Slave case). None if only one actuator/detector by controller + (Master case) + + Returns + ------- + info: str + initialized: bool + False if initialization failed otherwise True + """ + + self.ini_detector_init(old_controller=controller, + new_controller=mcc128(0)) + + + info = "Whatever info you want to log" + initialized = True + return info, initialized + + def close(self): + pass + """Terminate the communication protocol""" + + + def grab_data(self, Naverage=1, **kwargs): + """Start a grab from the detector + + Parameters + ---------- + Naverage: int + Number of hardware averaging (if hardware averaging is possible, self.hardware_averaging should be set to + True in class preamble and you should code this implementation) + kwargs: dict + others optionals arguments + """ + + ##synchrone version (blocking function) + data = self.scan_data() + xaxis = np.arange(0,(self.settings['nombre_points'])*1/self.settings['frequency'], 1/self.settings['frequency'] ) + + self.dte_signal.emit(DataToExport('myplugin', + data=[DataFromPlugins(name='Mock1', data=[data], + dim='Data1D', labels=['grabed'], + axes=[xaxis])])) + + def stop(self): + """Stop the current grab hardware wise if necessary""" + return '' + + +if __name__ == '__main__': + main(__file__, init=False) From b236b5fbd7cf3fc3affc337c19c3c31ea890fefa Mon Sep 17 00:00:00 2001 From: bkav456 Date: Tue, 5 Mar 2024 11:55:02 +0100 Subject: [PATCH 04/13] programme for mcc128 --- .../plugins_1D/daq_1Dviewer_BaoFadoua.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py index aeda341..0bfc76e 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py @@ -23,8 +23,17 @@ class DAQ_1DViewer_BaoFadoua(DAQ_Viewer_base): """ params = comon_parameters+[ - {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0}, - {'title': 'Duree:', 'name': 'duree', 'type': 'float', 'value': 5, 'min': 0} + {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0, 'max': 100000}, + {'title': 'Duree', 'name': 'duree', 'type': 'int', 'value': 5, 'min': 0}, + {'title': 'Range', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, + {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'DIFFERENTIAL', + 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, + {'title': 'Channel', 'name': 'channel', 'type': 'list', 'value': 0, 'limits': [0, 1, 2, 3, 4, 5, 6, 7]}, + {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'NONE',\ + 'limits': ['NONE', 'RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', \ + 'ACTIVE_LOW']}, + {'title': 'Option', 'name': 'option', 'type': 'list', 'value': 'DEFAUT',\ + 'limits': ['DEFAUT', 'NOSCALEDATA', 'NOCALIBRATEDATA']} ] @@ -47,8 +56,11 @@ def commit_settings(self, param: Parameter): ## def set_nb_points(self): - nb_points = self.settings['nombre_points'] - self.controller.npts = nb_points + self.controller.npts = self.settings['nombre_points'] + + + + def ini_detector(self, controller=None): From 1a2a7f3b3452692dbed4d272b84de080dac12177 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Tue, 5 Mar 2024 15:51:42 +0100 Subject: [PATCH 05/13] 2nd version --- .../plugins_1D/daq_1Dviewer_daqhats.py | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index e575842..377523b 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -24,10 +24,10 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): """ params = comon_parameters+[ - {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0, 'max' : 100000}, + {'title': 'Samples:', 'name': 'samples', 'type': 'int', 'value': 1000, 'min': 0, 'max' : 100000}, {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0}, {'title': 'Range', 'name': 'range', 'type': 'list', 'value':10 , 'limits':[10, 5, 2 ,1] }, - {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'DIFFERENTIAL', 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, + {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, {'title': 'Single_End_Channel', 'name': 'channel_single', 'type': 'list', 'value': 'CH0H', 'limits': ['CHOH', 'CH1H', 'CH2H', 'CH3H', 'CH0L',\ 'CH1L', 'CH2L', 'CH3L']}, {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'NONE', 'limits': ['NONE', 'RISING_EDGE' ,'FALLING_EDGE', 'ACTIVE_HIGH', \ @@ -40,8 +40,10 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): def ini_attributes(self): self.controller: mcc128 = None self.option = OptionFlags.DEFAULT - self.controller.a_in_mode_write(0) - self.controller.a_in_range_write(0) + #self.controller.a_in_mode_write(0) + #self.controller.a_in_range_write(0) + self.mode = 0 + self.range = 0 @@ -54,19 +56,37 @@ def commit_settings(self, param: Parameter): A given parameter (within detector_settings) whose value has been changed by the user """ ## TODO for your custom plugin - if param.name() == "nombre_points": - self.set_nb_points() + if param.name() == 'mode': + self.set_mode() -# elif ... + elif param.name() == 'range': + self.set_range() ## def scan_data(self): - self.controller.a_in_scan_start(1, self.settings['nombre_points'], self.settings['frequency'], self.option) - voltage = self.controller.a_in_scan_read(self.settings['nb_points'], 0) + self.controller.a_in_scan_start(1, self.settings['sample'], self.settings['frequency'], self.option) + voltage = self.controller.a_in_scan_read(self.settings['sample'], 0) self.controller.a_in_scan_stop() self.controller.a_in_scan_cleanup() return voltage + def set_mode(self): + if self.settings['mode'] == 'SINGLE_ENDED': + self.mode =0 + else: + self.mode =1 + self.controller.a_in_mode_write(self.mode) + + def set_range(self): + if self.settings['range'] == 10: + self.range = 0 + elif self.settings['range'] == 5: + self.range = 1 + elif self.settings['range'] == 2: + self.range = 2 + elif self.settings['range'] == 1: + self.range = 3 + self.controller.a_in_range_write(self.range) def ini_detector(self, controller=None): @@ -88,7 +108,6 @@ def ini_detector(self, controller=None): self.ini_detector_init(old_controller=controller, new_controller=mcc128(0)) - info = "Whatever info you want to log" initialized = True return info, initialized @@ -112,7 +131,7 @@ def grab_data(self, Naverage=1, **kwargs): ##synchrone version (blocking function) data = self.scan_data() - xaxis = np.arange(0,(self.settings['nombre_points'])*1/self.settings['frequency'], 1/self.settings['frequency'] ) + xaxis = np.arange(0,(self.settings['sample'])*1/self.settings['frequency'], 1/self.settings['frequency'] ) self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=[data], From 66a4cbb953cf3df202d0afde312a4633e7aff1b5 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Wed, 6 Mar 2024 00:24:27 +0100 Subject: [PATCH 06/13] 3rd version with the acquisition function and functions to setmode, range and to choose the channel --- .../plugins_1D/daq_1Dviewer_daqhats.py | 85 +++++++++++++++---- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 377523b..1efd1df 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -25,23 +25,20 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): """ params = comon_parameters+[ {'title': 'Samples:', 'name': 'samples', 'type': 'int', 'value': 1000, 'min': 0, 'max' : 100000}, - {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0}, + {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0 , 'max': 100000}, {'title': 'Range', 'name': 'range', 'type': 'list', 'value':10 , 'limits':[10, 5, 2 ,1] }, {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, {'title': 'Single_End_Channel', 'name': 'channel_single', 'type': 'list', 'value': 'CH0H', 'limits': ['CHOH', 'CH1H', 'CH2H', 'CH3H', 'CH0L',\ 'CH1L', 'CH2L', 'CH3L']}, {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'NONE', 'limits': ['NONE', 'RISING_EDGE' ,'FALLING_EDGE', 'ACTIVE_HIGH', \ - 'ACTIVE_LOW']}, - {'title': 'Option' , 'name':'option', 'type': 'list', 'value': 'DEFAUT', 'limits': ['DEFAUT', 'NOSCALEDATA', 'NOCALIBRATEDATA']} + 'ACTIVE_LOW']} ] def ini_attributes(self): - self.controller: mcc128 = None + self.controller: mcc128(0) = None self.option = OptionFlags.DEFAULT - #self.controller.a_in_mode_write(0) - #self.controller.a_in_range_write(0) self.mode = 0 self.range = 0 @@ -62,21 +59,42 @@ def commit_settings(self, param: Parameter): elif param.name() == 'range': self.set_range() ## - + ''' + /Start an acquisition + + The steps integred of the acquisition are: + *Start scan data : Set channels, total samples , sampling rate and option + *Read data from the buffer + *Stop scan and clean the buffer + ''' def scan_data(self): - self.controller.a_in_scan_start(1, self.settings['sample'], self.settings['frequency'], self.option) - voltage = self.controller.a_in_scan_read(self.settings['sample'], 0) + num_scan_sample = self.settings['samples'] + scan_freq = self.settings['frequency'] + channel_in = self.set_channel() + + self.controller.a_in_scan_start(channel_in, num_scan_sample, scan_freq, self.option) + voltage = self.controller.a_in_scan_read_numpy(num_scan_sample, 0.5) self.controller.a_in_scan_stop() self.controller.a_in_scan_cleanup() - return voltage - + return voltage.data + ''' + /Set the analog input mode: + *SINGLE-ENDED MODE : 8 inputs relative to ground + *DIFFERENTIAL MODE : 4 channels with positive and negative inputs + ''' def set_mode(self): if self.settings['mode'] == 'SINGLE_ENDED': - self.mode =0 - else: - self.mode =1 + self.mode = 0 + elif self.settings['mode'] == 'DIFFERENTIAL': + self.mode = 1 self.controller.a_in_mode_write(self.mode) - + ''' + /Set the range of the analog input: + * +/-10V range + * +/-5V range + * +/-2V range + * +/-1V range + ''' def set_range(self): if self.settings['range'] == 10: self.range = 0 @@ -89,6 +107,33 @@ def set_range(self): self.controller.a_in_range_write(self.range) + """ + /Choose the channel + """ + + def set_channel(self): + channel_mask = 0 + port = self.settings['channel'] + if port == 'CHOH': + channel_mask = 1 + elif port == 'CH1H': + channel_mask = 2 + elif port == 'CH2H': + channel_mask = 4 + elif port == 'CH3H': + channel_mask = 8 + elif port == 'CH0L': + channel_mask = 16 + elif port == 'CH1L': + channel_mask = 32 + elif port == 'CH2L': + channel_mask = 64 + elif port == 'CH3L': + channel_mask = 128 + + return channel_mask + + def ini_detector(self, controller=None): """Detector communication initialization @@ -130,11 +175,15 @@ def grab_data(self, Naverage=1, **kwargs): """ ##synchrone version (blocking function) - data = self.scan_data() - xaxis = np.arange(0,(self.settings['sample'])*1/self.settings['frequency'], 1/self.settings['frequency'] ) + + num_sample = self.settings['samples'] + freq = self.settings['frequency'] + + signal = self.scan_data() + xaxis = Axis('time', 'seconds', np.arange(0, num_sample / freq, 1 / freq), 0) self.dte_signal.emit(DataToExport('myplugin', - data=[DataFromPlugins(name='Mock1', data=[data], + data=[DataFromPlugins(name='Mock1', data=[signal], dim='Data1D', labels=['grabed'], axes=[xaxis])])) From c5e7bf4801c378371d4d206fbcee70ddb1d0c083 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Tue, 19 Mar 2024 11:44:21 +0100 Subject: [PATCH 07/13] ajouter trigger mode and multi channel --- .../plugins_1D/daq_1Dviewer_BaoFadoua.py | 24 +- .../plugins_1D/daq_1Dviewer_daqhats.py | 276 ++++++++++++------ .../hardware/file_brouillon.py | 31 ++ 3 files changed, 239 insertions(+), 92 deletions(-) create mode 100644 src/pymodaq_plugins_raspberry/hardware/file_brouillon.py diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py index 0bfc76e..ee1b6b9 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py @@ -61,8 +61,6 @@ def set_nb_points(self): - - def ini_detector(self, controller=None): """Detector communication initialization @@ -90,6 +88,16 @@ def close(self): pass """Terminate the communication protocol""" + def get_data(self, list_signal, samples, nb_channel_activated): + list_signal_arranged = [] + for k in range(nb_channel_activated): + list_signal_arranged.append([list_signal[k]]) + i = nb_channel_activated + while i <= len(list_signal) - nb_channel_activated: + for j in range(nb_channel_activated): + list_signal_arranged[j].append(list_signal[i + j]) + i = i + nb_channel_activated + return list_signal_arranged def grab_data(self, Naverage=1, **kwargs): """Start a grab from the detector @@ -104,10 +112,16 @@ def grab_data(self, Naverage=1, **kwargs): """ ##synchrone version (blocking function) - data, timing = self.controller.generateur(self.settings['duree']) - xaxis = Axis('time', 'seconds', timing, 0 ) + data = [5, 4, 3, 3, 45, 4, 6, 7, 8, 1, 2, 3, 4, 5, 2, 44, 33, 2, 1, 32] + #data, timing = self.controller.generateur(self.settings['duree']) + #data = data + np.random.random(len(data)) + xaxis = Axis('time', 'seconds',np.array([0,1,2,3,4,5,6,7,8,9]), 0 ) + + king = self.get_data(data, 10, 2) + + self.dte_signal.emit(DataToExport('myplugin', - data=[DataFromPlugins(name='Mock1', data=[data], + data=[DataFromPlugins(name='Mock1', data=[np.array([5,6,7,4,2,4,5,6,8,65])], dim='Data1D', labels=['grabed'], axes=[xaxis])])) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 1efd1df..0656cca 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -3,14 +3,13 @@ from pymodaq.utils.data import DataFromPlugins, Axis, DataToExport from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main from pymodaq.utils.parameter import Parameter - -from pymodaq_plugins_raspberry.hardware.mcc128 import mcc128 -from daqhats import mcc128 ,OptionFlags, AnalogInputMode, TriggerModes +from daqhats import mcc128, OptionFlags, AnalogInputMode, TriggerModes, AnalogInputRange +from pymodaq.utils.parameter.utils import iter_children class DAQ_1DViewer_daqhats(DAQ_Viewer_base): """ Instrument plugin class for a 1D viewer. - + This object inherits all functionalities to communicate with PyMoDAQ’s DAQ_Viewer module through inheritance via DAQ_Viewer_base. It makes a bridge between the DAQ_Viewer module and the Python wrapper of a particular instrument. @@ -19,30 +18,55 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): controller: object The particular object that allow the communication with the hardware, in general a python wrapper around the hardware library. - - """ - params = comon_parameters+[ - {'title': 'Samples:', 'name': 'samples', 'type': 'int', 'value': 1000, 'min': 0, 'max' : 100000}, - {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0 , 'max': 100000}, - {'title': 'Range', 'name': 'range', 'type': 'list', 'value':10 , 'limits':[10, 5, 2 ,1] }, - {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, - {'title': 'Single_End_Channel', 'name': 'channel_single', 'type': 'list', 'value': 'CH0H', 'limits': ['CHOH', 'CH1H', 'CH2H', 'CH3H', 'CH0L',\ - 'CH1L', 'CH2L', 'CH3L']}, - {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'NONE', 'limits': ['NONE', 'RISING_EDGE' ,'FALLING_EDGE', 'ACTIVE_HIGH', \ - 'ACTIVE_LOW']} - + params = comon_parameters + [ + {'title': 'Trigger Active', 'name': 'trigger_active', 'type': 'bool', 'value': False}, + {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'RISING_EDGE', + 'limits': ['RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', + 'ACTIVE_LOW']}, + {'title': 'External_clock', 'name': 'extclock', 'type': 'bool', 'value': False}, + {'title': 'Multichannel', 'name': 'multi', 'type': 'bool', 'value': False}, + {'title': 'Number of sample:', 'name': 'num_sample', 'type': 'int', 'value': 1000, 'min': 0, 'max': 100000}, + {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0}, + {'title': 'Range', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, + {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', + 'limits': ['SINGLE_ENDED', 'DIFFERENTIAL']}, + {'title': 'Channel _1', 'name': 'channel_single', 'type': 'list', 'value': 'CH0H', + 'limits': ['CH0H', 'CH1H', 'CH2H', 'CH3H', 'CH0L', + 'CH1L', 'CH2L', 'CH3L']}, + {'title': 'Channel_2_', 'name': 'channel_single_2', 'type': 'list', 'value': 'CH1H', + 'limits': ['CH0H', 'CH1H', 'CH2H', 'CH3H', 'CH0L', + 'CH1L', 'CH2L', 'CH3L']}, + {'title': "Channel", 'name': 'channel_active', 'type': 'group', 'children': [ + {'title': 'CH0H', 'name': 'CH0H', 'type': 'bool', 'value': False}, + {'title': 'CH1H', 'name': 'CH1H', 'type': 'bool', 'value': False}, + {'title': 'CH2H', 'name': 'CH2H', 'type': 'bool', 'value': False}, + {'title': 'CH3H', 'name': 'CH3H', 'type': 'bool', 'value': False}, + {'title': 'CH0L', 'name': 'CH0L', 'type': 'bool', 'value': False}, + {'title': 'CH1L', 'name': 'CH1L', 'type': 'bool', 'value': False}, + {'title': 'CH2L', 'name': 'CH2L', 'type': 'bool', 'value': False}, + {'title': 'CH3L', 'name': 'CH3L', 'type': 'bool', 'value': False} + ]} ] + """Initialize the attributes + + """ + + def __init__(self, parent=None, params_state=None): + super().__init__(parent, params_state) + self.num_channels = None def ini_attributes(self): self.controller: mcc128(0) = None - self.option = OptionFlags.DEFAULT + self.option = 0 self.mode = 0 self.range = 0 - - + self.input_channel_1 = 1 + self.input_channel_2 = 2 + self.channel_mask = 0 + self.num_channels = 0 def commit_settings(self, param: Parameter): """Apply the consequences of a change of value in the detector settings @@ -52,49 +76,33 @@ def commit_settings(self, param: Parameter): param: Parameter A given parameter (within detector_settings) whose value has been changed by the user """ - ## TODO for your custom plugin - if param.name() == 'mode': - self.set_mode() + if param.name() == 'mode': + self.set_mode() elif param.name() == 'range': self.set_range() - ## - ''' - /Start an acquisition - - The steps integred of the acquisition are: - *Start scan data : Set channels, total samples , sampling rate and option - *Read data from the buffer - *Stop scan and clean the buffer - ''' - def scan_data(self): - num_scan_sample = self.settings['samples'] - scan_freq = self.settings['frequency'] - channel_in = self.set_channel() - - self.controller.a_in_scan_start(channel_in, num_scan_sample, scan_freq, self.option) - voltage = self.controller.a_in_scan_read_numpy(num_scan_sample, 0.5) + elif param.name() == 'trigger_mode': + self.set_trigger() + # elif param.name() == 'channel_active': + # self.active_channel() + elif param.name() in iter_children(self.settings.child('channel_active'), []): + self.active_channel() + + def scan_data(self, totalsamples: int, scan_freq: int, name_channel: int): + + self.controller.a_in_scan_start(name_channel, totalsamples, scan_freq, self.option) + voltage = self.controller.a_in_scan_read_numpy(totalsamples, 0.5) self.controller.a_in_scan_stop() self.controller.a_in_scan_cleanup() return voltage.data - ''' - /Set the analog input mode: - *SINGLE-ENDED MODE : 8 inputs relative to ground - *DIFFERENTIAL MODE : 4 channels with positive and negative inputs - ''' - def set_mode(self): - if self.settings['mode'] == 'SINGLE_ENDED': - self.mode = 0 - elif self.settings['mode'] == 'DIFFERENTIAL': - self.mode = 1 - self.controller.a_in_mode_write(self.mode) - ''' - /Set the range of the analog input: - * +/-10V range - * +/-5V range - * +/-2V range - * +/-1V range - ''' + + """ This sets the analog input range to one of the value + +/- 10V + +/- 5V + +/- 2V + +/- 1V + """ + def set_range(self): if self.settings['range'] == 10: self.range = 0 @@ -106,34 +114,116 @@ def set_range(self): self.range = 3 self.controller.a_in_range_write(self.range) + # MODE + + def set_mode(self): + if self.settings['mode'] == 'SINGLE_ENDED': + self.mode = 0 + elif self.settings['mode'] == 'DIFFERENTIAL': + self.mode = 1 + self.controller.a_in_mode_write(self.mode) """ - /Choose the channel + This reads the sets the external trigger mode input of the card + There are 4 type available TRIGGER mode: + *RISING_EDGE: Star scan when the external trigger is from LOW to HIGH + *FALLING_EDGE: Star scan when the external trigger is from HIGH to LOW + *ACTIVE_HIGH: Start scan when the external trigger is HIGH + *ACTIVE_LOW: Start scan when the external trigger is LOW + """ - def set_channel(self): - channel_mask = 0 - port = self.settings['channel'] - if port == 'CHOH': - channel_mask = 1 - elif port == 'CH1H': - channel_mask = 2 - elif port == 'CH2H': - channel_mask = 4 - elif port == 'CH3H': - channel_mask = 8 - elif port == 'CH0L': - channel_mask = 16 - elif port == 'CH1L': - channel_mask = 32 - elif port == 'CH2L': - channel_mask = 64 - elif port == 'CH3L': - channel_mask = 128 - - return channel_mask + def set_trigger(self): + global Tmode + mode_trigger = self.settings['trigger_mode'] + if mode_trigger == 'RISING_EDGE': + Tmode = 0 + elif mode_trigger == 'FALLING_EDGE': + Tmode = 1 + elif mode_trigger == 'ACTIVE_HIGH': + Tmode = 2 + elif mode_trigger == 'ACTIVE_LOW': + Tmode = 3 + self.controller.trigger_mode(Tmode) + """ + + This function reads the states of channels on the interface and returns the bit mask of the active channels, + the number of activated channels, and a list of the names of these channels. + + ---------------------- + Return + + count: Bit mask of the channels activated + number_channels: Number of channels activated + name_channels: List of the activated channels + + """ + + def active_channel(self): + count = 0 + number_channels = 0 + name_channel = [] + # for param in self.settings.child(): + # if param.name() == 'channel_active': + if self.settings['channel_active', 'CH0H']: + count = count + 1 + number_channels += 1 + name_channel.append('CH0H') + if self.settings['channel_active', 'CH1H']: + count = count + 2 + number_channels += 1 + name_channel.append('CH1H') + if self.settings['channel_active', 'CH2H']: + count = count + 4 + number_channels += 1 + name_channel.append('CH2H') + if self.settings['channel_active', 'CH3H']: + count = count + 8 + number_channels += 1 + name_channel.append('CH3H') + if self.settings['channel_active', 'CH0L']: + count = count + 16 + number_channels += 1 + name_channel.append('CH0L') + if self.settings['channel_active', 'CH1L']: + count = count + 32 + number_channels += 1 + name_channel.append('CH1L') + if self.settings['channel_active', 'CH2L']: + count = count + 64 + number_channels += 1 + name_channel.append('CH2L') + if self.settings['channel_active', 'CH3L']: + count = count + 128 + number_channels += 1 + name_channel.append('CH3L') + return count, number_channels, name_channel + + """ + This used to convert the initial list of data which is returned by the function "self.scan_data" into + a list of arrays in which each array corresponds to the data of each active channel + + Parameter: + + list_signal_non_arranged (list): the list of data which is returned by the function "self.scan_data" + nb_channel_activated (int): the number of active channels + + Return: + list_signal_arranged (list): the list of arranged data + """ + def get_data(self, list_signal_non_arranged, nb_channel_activated): + list_signal_arranged = [] + for k in range(nb_channel_activated): + list_signal_arranged.append(np.array(list_signal_non_arranged[k])) + i = nb_channel_activated + while i <= len(list_signal_non_arranged) - nb_channel_activated: + for j in range(nb_channel_activated): + list_signal_arranged[j] = np.append(list_signal_arranged[j], list_signal_non_arranged[i + j]) + i = i + nb_channel_activated + return list_signal_arranged + def ini_detector(self, controller=None): """Detector communication initialization @@ -161,8 +251,8 @@ def close(self): pass """Terminate the communication protocol""" - def grab_data(self, Naverage=1, **kwargs): + """Start a grab from the detector Parameters @@ -174,18 +264,30 @@ def grab_data(self, Naverage=1, **kwargs): others optionals arguments """ - ##synchrone version (blocking function) + self.option = 0 + + if self.settings['trigger_active']: + self.option += 8 - num_sample = self.settings['samples'] + if self.settings['extclock']: + self.option += 4 + + self.channel_mask, self.num_channels, label = self.active_channel() + + num_sample = self.settings['num_sample'] freq = self.settings['frequency'] - signal = self.scan_data() - xaxis = Axis('time', 'seconds', np.arange(0, num_sample / freq, 1 / freq), 0) + # get and store the list of acquired data into signal + signal = self.scan_data(num_sample, freq, self.channel_mask) + # arrange the data of 'signal' + # 'data_signal' is a list of array in which each array corresponds to the acquired data of each active channel + data_signal = self.get_data(signal, self.num_channels) + + xaxis = Axis('time', 'seconds', np.arange(0, num_sample * 1 / freq, 1 / freq), 0) - self.dte_signal.emit(DataToExport('myplugin', - data=[DataFromPlugins(name='Mock1', data=[signal], - dim='Data1D', labels=['grabed'], - axes=[xaxis])])) + self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=data_signal, + dim='Data1D', labels=label, + axes=[xaxis])])) def stop(self): """Stop the current grab hardware wise if necessary""" diff --git a/src/pymodaq_plugins_raspberry/hardware/file_brouillon.py b/src/pymodaq_plugins_raspberry/hardware/file_brouillon.py new file mode 100644 index 0000000..85edd0d --- /dev/null +++ b/src/pymodaq_plugins_raspberry/hardware/file_brouillon.py @@ -0,0 +1,31 @@ +# Initializing an empty list + +import numpy as np + +list_of_lists = [] + +data = [5,4,3,3,45,4,6,7,8,1,2,3,4,5,2,44,33,2,1,32] +# Appending lists to create a list of lists +list_of_lists.append([1, 2, 3]) +list_of_lists.append([4, 5, 6]) +list_of_lists.append([7, 8, 9]) + +king = np.array(list_of_lists) + +# Displaying the resulting list of lists +print(np.array(list_of_lists)) + + +def get_data(list_signal, samples, nb_channel_activated): + list_signal_arranged = [] + for k in range(nb_channel_activated): + list_signal_arranged.append(np.array([list_signal[k]])) + i = nb_channel_activated + while i <= len(list_signal) - nb_channel_activated: + for j in range(nb_channel_activated): + list_signal_arranged[j] = np.append(list_signal_arranged[j], list_signal[i + j]) + i = i + nb_channel_activated + return list_signal_arranged + +gun = get_data(data, 10, 2) +print(gun) \ No newline at end of file From a17daee77ea0df6a1012bd93bd87ad44fb0d132a Mon Sep 17 00:00:00 2001 From: bkav456 Date: Wed, 20 Mar 2024 14:52:28 +0100 Subject: [PATCH 08/13] update using trigger with multi channels --- .../plugins_1D/daq_1Dviewer_daqhats.py | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 0656cca..01a633b 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -26,18 +26,11 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): 'limits': ['RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', 'ACTIVE_LOW']}, {'title': 'External_clock', 'name': 'extclock', 'type': 'bool', 'value': False}, - {'title': 'Multichannel', 'name': 'multi', 'type': 'bool', 'value': False}, - {'title': 'Number of sample:', 'name': 'num_sample', 'type': 'int', 'value': 1000, 'min': 0, 'max': 100000}, - {'title': 'Frequency :', 'name': 'frequency', 'type': 'int', 'value': 100, 'min': 0}, + {'title': 'Number of samples:', 'name': 'num_sample', 'type': 'int', 'value': 1000, 'min': 0}, + {'title': 'Sampling rate :', 'name': 'frequency', 'type': 'int', 'value': 10000, 'min': 0, 'max': 100000}, {'title': 'Range', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', 'limits': ['SINGLE_ENDED', 'DIFFERENTIAL']}, - {'title': 'Channel _1', 'name': 'channel_single', 'type': 'list', 'value': 'CH0H', - 'limits': ['CH0H', 'CH1H', 'CH2H', 'CH3H', 'CH0L', - 'CH1L', 'CH2L', 'CH3L']}, - {'title': 'Channel_2_', 'name': 'channel_single_2', 'type': 'list', 'value': 'CH1H', - 'limits': ['CH0H', 'CH1H', 'CH2H', 'CH3H', 'CH0L', - 'CH1L', 'CH2L', 'CH3L']}, {'title': "Channel", 'name': 'channel_active', 'type': 'group', 'children': [ {'title': 'CH0H', 'name': 'CH0H', 'type': 'bool', 'value': False}, {'title': 'CH1H', 'name': 'CH1H', 'type': 'bool', 'value': False}, @@ -67,6 +60,7 @@ def ini_attributes(self): self.input_channel_2 = 2 self.channel_mask = 0 self.num_channels = 0 + self.data_signal = [] def commit_settings(self, param: Parameter): """Apply the consequences of a change of value in the detector settings @@ -83,8 +77,6 @@ def commit_settings(self, param: Parameter): self.set_range() elif param.name() == 'trigger_mode': self.set_trigger() - # elif param.name() == 'channel_active': - # self.active_channel() elif param.name() in iter_children(self.settings.child('channel_active'), []): self.active_channel() @@ -96,7 +88,8 @@ def scan_data(self, totalsamples: int, scan_freq: int, name_channel: int): self.controller.a_in_scan_cleanup() return voltage.data - """ This sets the analog input range to one of the value + # RANGE + """ This sets the analog input range to one of these values +/- 10V +/- 5V +/- 2V @@ -125,11 +118,12 @@ def set_mode(self): """ This reads the sets the external trigger mode input of the card + There are 4 type available TRIGGER mode: - *RISING_EDGE: Star scan when the external trigger is from LOW to HIGH - *FALLING_EDGE: Star scan when the external trigger is from HIGH to LOW - *ACTIVE_HIGH: Start scan when the external trigger is HIGH - *ACTIVE_LOW: Start scan when the external trigger is LOW + *RISING_EDGE: + *FALLING_EDGE: + *ACTIVE_HIGH: + *ACTIVE_LOW: """ @@ -146,7 +140,7 @@ def set_trigger(self): Tmode = 3 self.controller.trigger_mode(Tmode) - + # Active channel """ This function reads the states of channels on the interface and returns the bit mask of the active channels, @@ -202,26 +196,19 @@ def active_channel(self): return count, number_channels, name_channel """ - This used to convert the initial list of data which is returned by the function "self.scan_data" into - a list of arrays in which each array corresponds to the data of each active channel - - Parameter: - - list_signal_non_arranged (list): the list of data which is returned by the function "self.scan_data" - nb_channel_activated (int): the number of active channels - Return: - list_signal_arranged (list): the list of arranged data """ + def get_data(self, list_signal_non_arranged, nb_channel_activated): list_signal_arranged = [] - for k in range(nb_channel_activated): - list_signal_arranged.append(np.array(list_signal_non_arranged[k])) - i = nb_channel_activated - while i <= len(list_signal_non_arranged) - nb_channel_activated: - for j in range(nb_channel_activated): - list_signal_arranged[j] = np.append(list_signal_arranged[j], list_signal_non_arranged[i + j]) - i = i + nb_channel_activated + if len(list_signal_non_arranged) != 0: + for k in range(nb_channel_activated): + list_signal_arranged.append(np.array(list_signal_non_arranged[k])) + i = nb_channel_activated + while i <= len(list_signal_non_arranged) - nb_channel_activated: + for j in range(nb_channel_activated): + list_signal_arranged[j] = np.append(list_signal_arranged[j],list_signal_non_arranged[i + j]) + i = i + nb_channel_activated return list_signal_arranged def ini_detector(self, controller=None): @@ -242,6 +229,19 @@ def ini_detector(self, controller=None): self.ini_detector_init(old_controller=controller, new_controller=mcc128(0)) + + self.option = 0 + self.channel_mask =1 + + self.settings.child('channel_active', 'CH0H').setValue(True) + + self.data_signal = self.scan_data(self.settings['num_sample'], self.settings['frequency'],self.channel_mask) + xaxis = Axis('time', 'seconds', np.arange(0, self.settings['num_sample'] * 1 / self.settings['frequency'], 1 / self.settings['frequency']), 0) + + self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=self.data_signal, + dim='Data1D', labels=['CH0H'], + axes=[xaxis])])) + info = "Whatever info you want to log" initialized = True @@ -266,26 +266,25 @@ def grab_data(self, Naverage=1, **kwargs): self.option = 0 - if self.settings['trigger_active']: + if self.settings['trigger_active'] == True: self.option += 8 - if self.settings['extclock']: + if self.settings['extclock'] == True: self.option += 4 self.channel_mask, self.num_channels, label = self.active_channel() num_sample = self.settings['num_sample'] freq = self.settings['frequency'] - - # get and store the list of acquired data into signal + signal = self.scan_data(num_sample, freq, self.channel_mask) - # arrange the data of 'signal' - # 'data_signal' is a list of array in which each array corresponds to the acquired data of each active channel - data_signal = self.get_data(signal, self.num_channels) + + if len(signal) != 0: + self.data_signal = self.get_data(signal, self.num_channels) xaxis = Axis('time', 'seconds', np.arange(0, num_sample * 1 / freq, 1 / freq), 0) - self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=data_signal, + self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=self.data_signal, dim='Data1D', labels=label, axes=[xaxis])])) From 499cb811d3181d667d362b8a3acc631667b6d527 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Sun, 21 Apr 2024 20:53:56 +0200 Subject: [PATCH 09/13] Code nettoye --- .../plugins_1D/daq_1Dviewer_daqhats.py | 274 +++++++++++------- 1 file changed, 163 insertions(+), 111 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 01a633b..5629a0d 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -25,13 +25,14 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'RISING_EDGE', 'limits': ['RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', 'ACTIVE_LOW']}, - {'title': 'External_clock', 'name': 'extclock', 'type': 'bool', 'value': False}, + {'title': 'External_clock', 'name': 'extclock_mode', 'type': 'bool', 'value': False}, + {'title': 'External sampling rate', 'name': 'extclock_rate', 'type': 'int', 'value': 0}, {'title': 'Number of samples:', 'name': 'num_sample', 'type': 'int', 'value': 1000, 'min': 0}, - {'title': 'Sampling rate :', 'name': 'frequency', 'type': 'int', 'value': 10000, 'min': 0, 'max': 100000}, + {'title': 'Sampling rate :', 'name': 'sampling_rate', 'type': 'int', 'value': 10000, 'min': 0, 'max': 100000}, {'title': 'Range', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', 'limits': ['SINGLE_ENDED', 'DIFFERENTIAL']}, - {'title': "Channel", 'name': 'channel_active', 'type': 'group', 'children': [ + {'title': "Channel", 'name': 'channel_on', 'type': 'group', 'children': [ {'title': 'CH0H', 'name': 'CH0H', 'type': 'bool', 'value': False}, {'title': 'CH1H', 'name': 'CH1H', 'type': 'bool', 'value': False}, {'title': 'CH2H', 'name': 'CH2H', 'type': 'bool', 'value': False}, @@ -43,26 +44,23 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): ]} ] - """Initialize the attributes - - """ def __init__(self, parent=None, params_state=None): super().__init__(parent, params_state) self.num_channels = None def ini_attributes(self): - self.controller: mcc128(0) = None + self.controller: mcc128 = None self.option = 0 self.mode = 0 self.range = 0 - self.input_channel_1 = 1 - self.input_channel_2 = 2 self.channel_mask = 0 self.num_channels = 0 self.data_signal = [] + self.list_channel_names = [] def commit_settings(self, param: Parameter): + """Apply the consequences of a change of value in the detector settings Parameters @@ -77,57 +75,94 @@ def commit_settings(self, param: Parameter): self.set_range() elif param.name() == 'trigger_mode': self.set_trigger() - elif param.name() in iter_children(self.settings.child('channel_active'), []): + elif param.name() in iter_children(self.settings.child('channel_on'), []): self.active_channel() + elif param.name() == 'sampling_rate': + sample_rate_real = self.controller.a_in_scan_actual_rate(self.num_channels, param.value()) + param.setValue(sample_rate_real) + + def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): - def scan_data(self, totalsamples: int, scan_freq: int, name_channel: int): + """ + This start a hardware-paced analog input channel scan . Then this function reads and return the data from the + buffer.The aggregate sampling rate of all activated channels can't exceed 100kS/s + + ================= ================ + Channels activate Scan rate (kS/s) + ================= ================ + 1 100 + 2 50 + 3 33,33 + 4 25 + 5 20 + 6 16,67 + 7 14,29 + 8 12,50 + ============== ================ - self.controller.a_in_scan_start(name_channel, totalsamples, scan_freq, self.option) + Parameters + ---------- + totalsamples: int + The numbers of samples which we want to aquire + scan_rate: int + The sampling rate of each channel + name_channel: int + The bit mask of the channels activated + + Returns: list + The list of data scanned + """ + + self.controller.a_in_scan_start(name_channel, totalsamples, scan_rate, self.option) voltage = self.controller.a_in_scan_read_numpy(totalsamples, 0.5) self.controller.a_in_scan_stop() self.controller.a_in_scan_cleanup() return voltage.data - # RANGE - """ This sets the analog input range to one of these values - +/- 10V - +/- 5V - +/- 2V - +/- 1V - """ - def set_range(self): + + """ This sets the analog input range to one of these values: + +/- 10V + +/- 5V + +/- 2V + +/- 1V + """ + if self.settings['range'] == 10: - self.range = 0 + self.range = AnalogInputRange['BIP_10V'].value elif self.settings['range'] == 5: - self.range = 1 + self.range = AnalogInputRange['BIP_5V'].value elif self.settings['range'] == 2: - self.range = 2 + self.range = AnalogInputRange['BIP_2V'].value elif self.settings['range'] == 1: - self.range = 3 + self.range = AnalogInputRange['BIP_1V'].value self.controller.a_in_range_write(self.range) - # MODE - def set_mode(self): + + """ This sets the analog input mode to one of two values + * Single ended + * Differential + """ + if self.settings['mode'] == 'SINGLE_ENDED': - self.mode = 0 + self.mode = AnalogInputMode.SE.value elif self.settings['mode'] == 'DIFFERENTIAL': - self.mode = 1 + self.mode = AnalogInputMode.DIFF.value self.controller.a_in_mode_write(self.mode) - """ - This reads the sets the external trigger mode input of the card - - There are 4 type available TRIGGER mode: - *RISING_EDGE: - *FALLING_EDGE: - *ACTIVE_HIGH: - *ACTIVE_LOW: - - """ - def set_trigger(self): + + """ + This reads the sets the external trigger mode input of the card + There are 4 type available TRIGGER mode: + *RISING_EDGE: Start the scan when the trigger signal transition from LOW to HIGH + *FALLING_EDGE: Start the scan when the trigger signal transition from HIGH to LOW + *ACTIVE_HIGH: Start the scan when the trigger signal is HIGH + *ACTIVE_LOW: Start the scan when the trigger signal is LOW + + """ + global Tmode mode_trigger = self.settings['trigger_mode'] if mode_trigger == 'RISING_EDGE': @@ -140,66 +175,73 @@ def set_trigger(self): Tmode = 3 self.controller.trigger_mode(Tmode) - # Active channel - """ + def active_channel(self): - This function reads the states of channels on the interface and returns the bit mask of the active channels, - the number of activated channels, and a list of the names of these channels. - - ---------------------- - Return - - count: Bit mask of the channels activated - number_channels: Number of channels activated - name_channels: List of the activated channels - - """ + """ + This function reads the states of channels on the interface and sets the bit mask of the active channels, + the number of activated channels, and a list of the names of these channels. - def active_channel(self): - count = 0 - number_channels = 0 - name_channel = [] - # for param in self.settings.child(): - # if param.name() == 'channel_active': - if self.settings['channel_active', 'CH0H']: - count = count + 1 + """ + + bit_mask = 0 # the bit mask of the active channels + number_channels = 0 # the number of activated channels + name_channels = [] # the list of the names of these channels + if self.settings['channel_on', 'CH0H']: + bit_mask = bit_mask + 1 number_channels += 1 - name_channel.append('CH0H') - if self.settings['channel_active', 'CH1H']: - count = count + 2 + name_channels.append('CH0H') + if self.settings['channel_on', 'CH1H']: + bit_mask = bit_mask + 2 number_channels += 1 - name_channel.append('CH1H') - if self.settings['channel_active', 'CH2H']: - count = count + 4 + name_channels.append('CH1H') + if self.settings['channel_on', 'CH2H']: + bit_mask = bit_mask + 4 number_channels += 1 - name_channel.append('CH2H') - if self.settings['channel_active', 'CH3H']: - count = count + 8 + name_channels.append('CH2H') + if self.settings['channel_on', 'CH3H']: + bit_mask = bit_mask + 8 number_channels += 1 - name_channel.append('CH3H') - if self.settings['channel_active', 'CH0L']: - count = count + 16 + name_channels.append('CH3H') + if self.settings['channel_on', 'CH0L']: + bit_mask = bit_mask + 16 number_channels += 1 - name_channel.append('CH0L') - if self.settings['channel_active', 'CH1L']: - count = count + 32 + name_channels.append('CH0L') + if self.settings['channel_on', 'CH1L']: + bit_mask = bit_mask + 32 number_channels += 1 - name_channel.append('CH1L') - if self.settings['channel_active', 'CH2L']: - count = count + 64 + name_channels.append('CH1L') + if self.settings['channel_on', 'CH2L']: + bit_mask = bit_mask + 64 number_channels += 1 - name_channel.append('CH2L') - if self.settings['channel_active', 'CH3L']: - count = count + 128 + name_channels.append('CH2L') + if self.settings['channel_on', 'CH3L']: + bit_mask = bit_mask + 128 number_channels += 1 - name_channel.append('CH3L') - return count, number_channels, name_channel - - """ - - """ + name_channels.append('CH3L') + self.channel_mask, self.num_channels, self.label = bit_mask, number_channels, name_channels def get_data(self, list_signal_non_arranged, nb_channel_activated): + """ + + This methode arranges the list of data received from activated channels. It converts this list of data into a list + of numpy arrays. The order of each array corresponds to the order of each activated channel on the interface (from CH0H to CH3L) + + Example: When you activate 2 channels CHOH and CH2L, this function will return a list of 2 arrays: the first one is + data of channel CH0H and the second one is data of channel CH2L + + Parameters + ---------- + list_signal_non_arranged : list + List of data obtained by function scan_data() + nb_channel_activated : int + The quantity of activated channels + + Returns + ------- + list_signal_arranged : list of numpy array + list of data of each channel arranged + + """ list_signal_arranged = [] if len(list_signal_non_arranged) != 0: for k in range(nb_channel_activated): @@ -207,7 +249,7 @@ def get_data(self, list_signal_non_arranged, nb_channel_activated): i = nb_channel_activated while i <= len(list_signal_non_arranged) - nb_channel_activated: for j in range(nb_channel_activated): - list_signal_arranged[j] = np.append(list_signal_arranged[j],list_signal_non_arranged[i + j]) + list_signal_arranged[j] = np.append(list_signal_arranged[j], list_signal_non_arranged[i + j]) i = i + nb_channel_activated return list_signal_arranged @@ -229,21 +271,22 @@ def ini_detector(self, controller=None): self.ini_detector_init(old_controller=controller, new_controller=mcc128(0)) - + self.option = 0 - self.channel_mask =1 - - self.settings.child('channel_active', 'CH0H').setValue(True) - - self.data_signal = self.scan_data(self.settings['num_sample'], self.settings['frequency'],self.channel_mask) - xaxis = Axis('time', 'seconds', np.arange(0, self.settings['num_sample'] * 1 / self.settings['frequency'], 1 / self.settings['frequency']), 0) + self.channel_mask = 1 + + self.settings.child('channel_on', 'CH0H').setValue(True) + + self.data_signal = self.scan_data(self.settings['num_sample'], self.settings['sampling_rate'], + self.channel_mask) + xaxis = Axis('time', 'seconds', np.arange(0, self.settings['num_sample'] * 1 / self.settings['sampling_rate'], + 1 / self.settings['sampling_rate']), 0) self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=self.data_signal, dim='Data1D', labels=['CH0H'], axes=[xaxis])])) - - info = "Whatever info you want to log" + info = "" initialized = True return info, initialized @@ -264,28 +307,37 @@ def grab_data(self, Naverage=1, **kwargs): others optionals arguments """ + num_sample = self.settings['num_sample'] + freq = self.settings['sampling_rate'] + self.option = 0 + # Set up mode Trigger if self.settings['trigger_active'] == True: - self.option += 8 - - if self.settings['extclock'] == True: - self.option += 4 - - self.channel_mask, self.num_channels, label = self.active_channel() + self.option += OptionFlags['EXTTRIGGER'].value + + # Set up mode External clock + if self.settings['extclock_mode'] == True: + self.option += OptionFlags['EXTCLOCK'].value + external_spl_rate = self.settings['extclock_rate'] + if external_spl_rate == 0: + raise ValueError("Sampling rate cannot be zero") + else: + xaxis = Axis('time', 'seconds', np.arange(0, num_sample * 1 / external_spl_rate, 1 / external_spl_rate), + 0) # Redefine the x-axis when the external clock is used + else: + xaxis = Axis('time', 'seconds', np.arange(0, num_sample * 1 / freq, 1 / freq), 0) + + self.channel_mask, self.num_channels, self.list_channel_names = self.active_channel() - num_sample = self.settings['num_sample'] - freq = self.settings['frequency'] - signal = self.scan_data(num_sample, freq, self.channel_mask) - - if len(signal) != 0: - self.data_signal = self.get_data(signal, self.num_channels) - xaxis = Axis('time', 'seconds', np.arange(0, num_sample * 1 / freq, 1 / freq), 0) + if len(signal) != 0: # Condition to avoid empty data error + self.data_signal = self.get_data(signal, self.num_channels) self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=self.data_signal, - dim='Data1D', labels=label, + dim='Data1D', + labels=self.list_channel_names, axes=[xaxis])])) def stop(self): From 0a76456680d61da01f70e6080ec9fbc95c6b0da6 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Fri, 26 Apr 2024 00:59:12 +0200 Subject: [PATCH 10/13] Delete the unnecessary files and update the docstring --- plugin_info.toml | 2 + .../plugins_1D/daq_1Dviewer_BaoFadoua.py | 134 ------------------ .../plugins_1D/daq_1Dviewer_daqhats.py | 33 ++--- .../hardware/file_brouillon.py | 31 ---- .../hardware/mcc128.py | 34 ----- 5 files changed, 17 insertions(+), 217 deletions(-) delete mode 100644 src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py delete mode 100644 src/pymodaq_plugins_raspberry/hardware/file_brouillon.py delete mode 100644 src/pymodaq_plugins_raspberry/hardware/mcc128.py diff --git a/plugin_info.toml b/plugin_info.toml index e594c90..1f5d923 100644 --- a/plugin_info.toml +++ b/plugin_info.toml @@ -14,6 +14,8 @@ license = 'MIT' [plugin-install] #packages required for your plugin: packages-required = ['pymodaq>=4.0.0', 'daqhats'] +packages-required = ['pymodaq>=4.0.0', 'picamera2'] + [features] # defines the plugin features contained into this plugin instruments = true # true if plugin contains instrument classes (else false, notice the lowercase for toml files) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py deleted file mode 100644 index ee1b6b9..0000000 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_BaoFadoua.py +++ /dev/null @@ -1,134 +0,0 @@ -import numpy as np -from pymodaq.utils.daq_utils import ThreadCommand -from pymodaq.utils.data import DataFromPlugins, Axis, DataToExport -from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main -from pymodaq.utils.parameter import Parameter - -from pymodaq_plugins_raspberry.hardware.mcc128 import mcc128 - - -class DAQ_1DViewer_BaoFadoua(DAQ_Viewer_base): - """ Instrument plugin class for a 1D viewer. - - This object inherits all functionalities to communicate with PyMoDAQ’s DAQ_Viewer module through inheritance via - DAQ_Viewer_base. It makes a bridge between the DAQ_Viewer module and the Python wrapper of a particular instrument. - - Attributes: - ----------- - controller: object - The particular object that allow the communication with the hardware, in general a python wrapper around the - hardware library. - - - - """ - params = comon_parameters+[ - {'title': 'Nombre de points:', 'name': 'nombre_points', 'type': 'int', 'value': 1000, 'min': 0, 'max': 100000}, - {'title': 'Duree', 'name': 'duree', 'type': 'int', 'value': 5, 'min': 0}, - {'title': 'Range', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, - {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'DIFFERENTIAL', - 'limits': ['SINGLE_END', 'DIFFERENTIAL']}, - {'title': 'Channel', 'name': 'channel', 'type': 'list', 'value': 0, 'limits': [0, 1, 2, 3, 4, 5, 6, 7]}, - {'title': 'Trigger Mode', 'name': 'trigger_mode', 'type': 'list', 'value': 'NONE',\ - 'limits': ['NONE', 'RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', \ - 'ACTIVE_LOW']}, - {'title': 'Option', 'name': 'option', 'type': 'list', 'value': 'DEFAUT',\ - 'limits': ['DEFAUT', 'NOSCALEDATA', 'NOCALIBRATEDATA']} - - ] - - def ini_attributes(self): - self.controller: mcc128 = None - - def commit_settings(self, param: Parameter): - """Apply the consequences of a change of value in the detector settings - - Parameters - ---------- - param: Parameter - A given parameter (within detector_settings) whose value has been changed by the user - """ - ## TODO for your custom plugin - if param.name() == "nombre_points": - self.set_nb_points() - -# elif ... - ## - - def set_nb_points(self): - self.controller.npts = self.settings['nombre_points'] - - - - - def ini_detector(self, controller=None): - """Detector communication initialization - - Parameters - ---------- - controller: (object) - custom object of a PyMoDAQ plugin (Slave case). None if only one actuator/detector by controller - (Master case) - - Returns - ------- - info: str - initialized: bool - False if initialization failed otherwise True - """ - - self.ini_detector_init(old_controller=controller, - new_controller=mcc128()) - - info = "Whatever info you want to log" - initialized = True - return info, initialized - - def close(self): - pass - """Terminate the communication protocol""" - - def get_data(self, list_signal, samples, nb_channel_activated): - list_signal_arranged = [] - for k in range(nb_channel_activated): - list_signal_arranged.append([list_signal[k]]) - i = nb_channel_activated - while i <= len(list_signal) - nb_channel_activated: - for j in range(nb_channel_activated): - list_signal_arranged[j].append(list_signal[i + j]) - i = i + nb_channel_activated - return list_signal_arranged - - def grab_data(self, Naverage=1, **kwargs): - """Start a grab from the detector - - Parameters - ---------- - Naverage: int - Number of hardware averaging (if hardware averaging is possible, self.hardware_averaging should be set to - True in class preamble and you should code this implementation) - kwargs: dict - others optionals arguments - """ - - ##synchrone version (blocking function) - data = [5, 4, 3, 3, 45, 4, 6, 7, 8, 1, 2, 3, 4, 5, 2, 44, 33, 2, 1, 32] - #data, timing = self.controller.generateur(self.settings['duree']) - #data = data + np.random.random(len(data)) - xaxis = Axis('time', 'seconds',np.array([0,1,2,3,4,5,6,7,8,9]), 0 ) - - king = self.get_data(data, 10, 2) - - - self.dte_signal.emit(DataToExport('myplugin', - data=[DataFromPlugins(name='Mock1', data=[np.array([5,6,7,4,2,4,5,6,8,65])], - dim='Data1D', labels=['grabed'], - axes=[xaxis])])) - - def stop(self): - """Stop the current grab hardware wise if necessary""" - return '' - - -if __name__ == '__main__': - main(__file__, init=False) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 5629a0d..0b4e64f 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -26,10 +26,10 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): 'limits': ['RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', 'ACTIVE_LOW']}, {'title': 'External_clock', 'name': 'extclock_mode', 'type': 'bool', 'value': False}, - {'title': 'External sampling rate', 'name': 'extclock_rate', 'type': 'int', 'value': 0}, + {'title': 'External sampling rate(Hz)', 'name': 'extclock_rate', 'type': 'int', 'value': 0}, {'title': 'Number of samples:', 'name': 'num_sample', 'type': 'int', 'value': 1000, 'min': 0}, - {'title': 'Sampling rate :', 'name': 'sampling_rate', 'type': 'int', 'value': 10000, 'min': 0, 'max': 100000}, - {'title': 'Range', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, + {'title': 'Sampling rate(Hz) :', 'name': 'sampling_rate', 'type': 'int', 'value': 10000, 'min': 0, 'max': 100000}, + {'title': 'Range(V)', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, {'title': 'Mode', 'name': 'mode', 'type': 'list', 'value': 'SINGLE_END', 'limits': ['SINGLE_ENDED', 'DIFFERENTIAL']}, {'title': "Channel", 'name': 'channel_on', 'type': 'group', 'children': [ @@ -60,9 +60,7 @@ def ini_attributes(self): self.list_channel_names = [] def commit_settings(self, param: Parameter): - """Apply the consequences of a change of value in the detector settings - Parameters ---------- param: Parameter @@ -83,10 +81,10 @@ def commit_settings(self, param: Parameter): def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): - """ - This start a hardware-paced analog input channel scan . Then this function reads and return the data from the - buffer.The aggregate sampling rate of all activated channels can't exceed 100kS/s + """This starts a hardware-paced analog input channel scan . Then this function reads and returns the data from the + buffer. + The aggregate sampling rate of all activated channels can't exceed 100kS/s ================= ================ Channels activate Scan rate (kS/s) ================= ================ @@ -101,7 +99,7 @@ def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): ============== ================ Parameters - ---------- + ----------- totalsamples: int The numbers of samples which we want to aquire scan_rate: int @@ -109,7 +107,9 @@ def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): name_channel: int The bit mask of the channels activated - Returns: list + Returns + ------- + voltage.data : list The list of data scanned """ @@ -153,8 +153,8 @@ def set_mode(self): def set_trigger(self): - """ - This reads the sets the external trigger mode input of the card + """Read and Set the external trigger mode input of the card + There are 4 type available TRIGGER mode: *RISING_EDGE: Start the scan when the trigger signal transition from LOW to HIGH *FALLING_EDGE: Start the scan when the trigger signal transition from HIGH to LOW @@ -177,8 +177,7 @@ def set_trigger(self): def active_channel(self): - """ - This function reads the states of channels on the interface and sets the bit mask of the active channels, + """This function reads the states of channels on the interface and sets the bit mask of the active channels, the number of activated channels, and a list of the names of these channels. """ @@ -221,11 +220,10 @@ def active_channel(self): self.channel_mask, self.num_channels, self.label = bit_mask, number_channels, name_channels def get_data(self, list_signal_non_arranged, nb_channel_activated): - """ + """ Arrange the list of data received from activated channels This methode arranges the list of data received from activated channels. It converts this list of data into a list of numpy arrays. The order of each array corresponds to the order of each activated channel on the interface (from CH0H to CH3L) - Example: When you activate 2 channels CHOH and CH2L, this function will return a list of 2 arrays: the first one is data of channel CH0H and the second one is data of channel CH2L @@ -240,7 +238,6 @@ def get_data(self, list_signal_non_arranged, nb_channel_activated): ------- list_signal_arranged : list of numpy array list of data of each channel arranged - """ list_signal_arranged = [] if len(list_signal_non_arranged) != 0: @@ -335,7 +332,7 @@ def grab_data(self, Naverage=1, **kwargs): if len(signal) != 0: # Condition to avoid empty data error self.data_signal = self.get_data(signal, self.num_channels) - self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=self.data_signal, + self.dte_signal.emit(DataToExport('mcc128_plugin', data=[DataFromPlugins(name='mcc128', data=self.data_signal, dim='Data1D', labels=self.list_channel_names, axes=[xaxis])])) diff --git a/src/pymodaq_plugins_raspberry/hardware/file_brouillon.py b/src/pymodaq_plugins_raspberry/hardware/file_brouillon.py deleted file mode 100644 index 85edd0d..0000000 --- a/src/pymodaq_plugins_raspberry/hardware/file_brouillon.py +++ /dev/null @@ -1,31 +0,0 @@ -# Initializing an empty list - -import numpy as np - -list_of_lists = [] - -data = [5,4,3,3,45,4,6,7,8,1,2,3,4,5,2,44,33,2,1,32] -# Appending lists to create a list of lists -list_of_lists.append([1, 2, 3]) -list_of_lists.append([4, 5, 6]) -list_of_lists.append([7, 8, 9]) - -king = np.array(list_of_lists) - -# Displaying the resulting list of lists -print(np.array(list_of_lists)) - - -def get_data(list_signal, samples, nb_channel_activated): - list_signal_arranged = [] - for k in range(nb_channel_activated): - list_signal_arranged.append(np.array([list_signal[k]])) - i = nb_channel_activated - while i <= len(list_signal) - nb_channel_activated: - for j in range(nb_channel_activated): - list_signal_arranged[j] = np.append(list_signal_arranged[j], list_signal[i + j]) - i = i + nb_channel_activated - return list_signal_arranged - -gun = get_data(data, 10, 2) -print(gun) \ No newline at end of file diff --git a/src/pymodaq_plugins_raspberry/hardware/mcc128.py b/src/pymodaq_plugins_raspberry/hardware/mcc128.py deleted file mode 100644 index b93cec5..0000000 --- a/src/pymodaq_plugins_raspberry/hardware/mcc128.py +++ /dev/null @@ -1,34 +0,0 @@ -import numpy as np -import numpy as py - - - - -class mcc128: - - def __init__(self): - self._npts: int = 1000 - - @property - def npts(self): - return self._npts - - @npts.setter - def npts(self, npt: int): - if not isinstance(npt, int): - raise TypeError("") - elif npt < 1: - raise ValueError("") - self._npts = npt - - def get_x_axis(self, nbre_point, freq_echatillonage ): - te = np.linspace(0, (nbre_point - 1) / freq_echatillonage, nbre_point) - return te - - def generateur(self, duree: float): - freq = self.npts / duree - ts = self.get_x_axis(self.npts, freq) - return np.sin(2 * np.pi * ts), ts - - - From 48dd2fa0d1c5faf1b7a0015fefb2cf2e53e8de3a Mon Sep 17 00:00:00 2001 From: bkav456 Date: Sat, 27 Apr 2024 19:14:37 +0200 Subject: [PATCH 11/13] Delete the unnecessary files and update the docstring --- .../daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 0b4e64f..9443a46 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -26,7 +26,7 @@ class DAQ_1DViewer_daqhats(DAQ_Viewer_base): 'limits': ['RISING_EDGE', 'FALLING_EDGE', 'ACTIVE_HIGH', 'ACTIVE_LOW']}, {'title': 'External_clock', 'name': 'extclock_mode', 'type': 'bool', 'value': False}, - {'title': 'External sampling rate(Hz)', 'name': 'extclock_rate', 'type': 'int', 'value': 0}, + {'title': 'External sampling rate(Hz)', 'name': 'extclock_rate', 'type': 'int', 'value': 0, 'visible': False}, {'title': 'Number of samples:', 'name': 'num_sample', 'type': 'int', 'value': 1000, 'min': 0}, {'title': 'Sampling rate(Hz) :', 'name': 'sampling_rate', 'type': 'int', 'value': 10000, 'min': 0, 'max': 100000}, {'title': 'Range(V)', 'name': 'range', 'type': 'list', 'value': 10, 'limits': [10, 5, 2, 1]}, @@ -78,6 +78,8 @@ def commit_settings(self, param: Parameter): elif param.name() == 'sampling_rate': sample_rate_real = self.controller.a_in_scan_actual_rate(self.num_channels, param.value()) param.setValue(sample_rate_real) + elif param.name() == 'extclock_mode': + self.settings.child('extclock_rate').setOpts(visible = param.value()) def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): From 83a945381ae04c7f725d08f83c92ff4b6c77674d Mon Sep 17 00:00:00 2001 From: bkav456 Date: Sat, 27 Apr 2024 19:19:23 +0200 Subject: [PATCH 12/13] Delete the unnecessary files and update the docstring --- .../plugins_1D/daq_1Dviewer_daqhats.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index 9443a46..c4c9038 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -271,20 +271,6 @@ def ini_detector(self, controller=None): self.ini_detector_init(old_controller=controller, new_controller=mcc128(0)) - self.option = 0 - self.channel_mask = 1 - - self.settings.child('channel_on', 'CH0H').setValue(True) - - self.data_signal = self.scan_data(self.settings['num_sample'], self.settings['sampling_rate'], - self.channel_mask) - xaxis = Axis('time', 'seconds', np.arange(0, self.settings['num_sample'] * 1 / self.settings['sampling_rate'], - 1 / self.settings['sampling_rate']), 0) - - self.dte_signal.emit(DataToExport('myplugin', data=[DataFromPlugins(name='Mock1', data=self.data_signal, - dim='Data1D', labels=['CH0H'], - axes=[xaxis])])) - info = "" initialized = True return info, initialized From 0877acb5bbf94cafa08a058d07bf3ff3e98401c8 Mon Sep 17 00:00:00 2001 From: bkav456 Date: Mon, 29 Apr 2024 23:56:28 +0200 Subject: [PATCH 13/13] remove the empty lines and correct file plugin_info.toml --- plugin_info.toml | 3 +-- .../plugins_1D/daq_1Dviewer_daqhats.py | 19 +++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/plugin_info.toml b/plugin_info.toml index 1f5d923..c37de7a 100644 --- a/plugin_info.toml +++ b/plugin_info.toml @@ -13,8 +13,7 @@ license = 'MIT' [plugin-install] #packages required for your plugin: -packages-required = ['pymodaq>=4.0.0', 'daqhats'] -packages-required = ['pymodaq>=4.0.0', 'picamera2'] +packages-required = ['pymodaq>=4.0.0', 'daqhats', 'picamera2'] [features] # defines the plugin features contained into this plugin diff --git a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py index c4c9038..a85aa15 100644 --- a/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py +++ b/src/pymodaq_plugins_raspberry/daq_viewer_plugins/plugins_1D/daq_1Dviewer_daqhats.py @@ -53,6 +53,7 @@ def ini_attributes(self): self.controller: mcc128 = None self.option = 0 self.mode = 0 + self.trigger_mode = 0 self.range = 0 self.channel_mask = 0 self.num_channels = 0 @@ -82,7 +83,6 @@ def commit_settings(self, param: Parameter): self.settings.child('extclock_rate').setOpts(visible = param.value()) def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): - """This starts a hardware-paced analog input channel scan . Then this function reads and returns the data from the buffer. @@ -122,7 +122,6 @@ def scan_data(self, totalsamples: int, scan_rate: int, name_channel: int): return voltage.data def set_range(self): - """ This sets the analog input range to one of these values: +/- 10V +/- 5V @@ -141,7 +140,6 @@ def set_range(self): self.controller.a_in_range_write(self.range) def set_mode(self): - """ This sets the analog input mode to one of two values * Single ended * Differential @@ -154,7 +152,6 @@ def set_mode(self): self.controller.a_in_mode_write(self.mode) def set_trigger(self): - """Read and Set the external trigger mode input of the card There are 4 type available TRIGGER mode: @@ -165,20 +162,19 @@ def set_trigger(self): """ - global Tmode mode_trigger = self.settings['trigger_mode'] if mode_trigger == 'RISING_EDGE': - Tmode = 0 + self.trigger_mode = TriggerModes.RISING_EDGE elif mode_trigger == 'FALLING_EDGE': - Tmode = 1 + self.trigger_mode = TriggerModes.FALLING_EDGE elif mode_trigger == 'ACTIVE_HIGH': - Tmode = 2 + self.trigger_mode = TriggerModes.ACTIVE_HIGH elif mode_trigger == 'ACTIVE_LOW': - Tmode = 3 - self.controller.trigger_mode(Tmode) + self.trigger_mode = TriggerModes.ACTIVE_LOW + self.controller.trigger_mode(self.trigger_mode) - def active_channel(self): + def active_channel(self): """This function reads the states of channels on the interface and sets the bit mask of the active channels, the number of activated channels, and a list of the names of these channels. @@ -280,7 +276,6 @@ def close(self): """Terminate the communication protocol""" def grab_data(self, Naverage=1, **kwargs): - """Start a grab from the detector Parameters