diff --git a/ohmpi/hardware_components/abstract_hardware_components.py b/ohmpi/hardware_components/abstract_hardware_components.py index a02ff276795068297edd0314c51f20cb59bf120e..149322c6f0ee4ee7ae14a05ecf4d67bcb01ca9d6 100644 --- a/ohmpi/hardware_components/abstract_hardware_components.py +++ b/ohmpi/hardware_components/abstract_hardware_components.py @@ -304,6 +304,17 @@ class TxAbstract(ABC): self._gain = value self.exec_logger.debug(f'Setting TX gain to {value}') + @property + @abstractmethod + def current(self): + """ Gets the current IAB in Amps + """ + pass + + @current.setter + @abstractmethod + def current(self, value): + pass @abstractmethod def current_pulse(self, **kwargs): diff --git a/ohmpi/hardware_components/mb_2023_0_X.py b/ohmpi/hardware_components/mb_2023_0_X.py index dff4eaa494fa791ed68e402665a40c09f5276d88..80fb8617e1d0025fae6b0928277615f87de5f1d2 100644 --- a/ohmpi/hardware_components/mb_2023_0_X.py +++ b/ohmpi/hardware_components/mb_2023_0_X.py @@ -95,7 +95,7 @@ class Tx(TxAbstract): self._ads_current = ads.ADS1115(self.connection, gain=self._adc_gain, data_rate=self._ads_current_data_rate, address=self._ads_current_address) self._ads_current.mode = Mode.CONTINUOUS - self.r_shunt = kwargs['r_shunt'] + self._r_shunt = kwargs['r_shunt'] self.adc_voltage_min = kwargs['adc_voltage_min'] self.adc_voltage_max = kwargs['adc_voltage_max'] @@ -138,13 +138,13 @@ class Tx(TxAbstract): def current(self): """ Gets the current IAB in Amps """ - iab = AnalogIn(self._ads_current, ads.P0).voltage * 1000. / (50 * self.r_shunt) # measure current + iab = AnalogIn(self._ads_current, ads.P0).voltage * 1000. / (50 * self._r_shunt) # measure current self.exec_logger.debug(f'Reading TX current: {iab} mA') return iab @ current.setter def current(self, value): - assert self.adc_voltage_min / (50 * self.r_shunt) <= value <= self.adc_voltage_max / (50 * self.r_shunt) + assert self.adc_voltage_min / (50 * self._r_shunt) <= value <= self.adc_voltage_max / (50 * self._r_shunt) self.exec_logger.warning(f'Current pulse is not implemented for the {self.model} board') def gain_auto(self): @@ -190,6 +190,17 @@ class Tx(TxAbstract): else: return self.pwr.battery_voltage + @property + def voltage(self): + """ Gets the voltage VAB in Volts + """ + vab = self.current * self._r_shunt + self.exec_logger.debug(f'Reading TX current: {vab} mv') + return vab + + @voltage.setter + def voltage(self, value): + self.pwr.voltage = value def voltage_pulse(self, voltage=None, length=None, polarity=1): """ Generates a square voltage pulse diff --git a/ohmpi/hardware_components/mb_2024_0_2.py b/ohmpi/hardware_components/mb_2024_0_2.py index 0cef544ec18787d829ace411cc3379a3658f6d3b..9f480990231441d37dab20c59840b60a7eb051b6 100644 --- a/ohmpi/hardware_components/mb_2024_0_2.py +++ b/ohmpi/hardware_components/mb_2024_0_2.py @@ -31,7 +31,7 @@ SPECS = {'rx': {'model': {'default': os.path.basename(__file__).rstrip('.py')}, 'mcp_address': {'default': 0x21}, 'ads_address': {'default': 0x48}, 'compatible_power_sources': {'default': ['pwr_batt', 'dps5005']}, - 'r_shunt': {'min': 0., 'default': 2.}, + 'r_shunt': {'min': 0.001, 'default': 2.}, 'activation_delay': {'default': 0.010}, # Max turn on time of OMRON G5LE-1 5VDC relays 'release_delay': {'default': 0.005}, # Max turn off time of OMRON G5LE-1 5VDC relays = 1ms 'pwr_latency': {'default': 4.} @@ -86,10 +86,10 @@ class Tx(Tx_mb_2023): self.pin6 = self.mcp_board.get_pin(6) self.pin6.direction = Direction.OUTPUT self.pin6.value = False - self.pin2 = self.mcp_board.get_pin(2) # dsp - + self.pin2 = self.mcp_board.get_pin(2) # dps - self.pin2.direction = Direction.OUTPUT self.pin2.value = False - self.pin3 = self.mcp_board.get_pin(3) # dsp - + self.pin3 = self.mcp_board.get_pin(3) # dps - self.pin3.direction = Direction.OUTPUT self.pin3.value = False diff --git a/ohmpi/hardware_components/mux_2024_0_X.py b/ohmpi/hardware_components/mux_2024_0_X.py index 49c528a19e38c54c56733da2ffa476d46051429f..9334bb032b00518b450fb29598773437feeeb992 100644 --- a/ohmpi/hardware_components/mux_2024_0_X.py +++ b/ohmpi/hardware_components/mux_2024_0_X.py @@ -72,9 +72,9 @@ class Mux(MuxAbstract): self._roles = kwargs.pop('roles', None) if self._roles is None: self._roles = {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'} # NOTE: defaults to 4-roles - if np.alltrue([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['4_roles'].keys())])]): + if np.all([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['4_roles'].keys())])]): self._mode = '4_roles' - elif np.alltrue([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['2_roles'].keys())])]): + elif np.all([j in self._roles.values() for j in set([i[1] for i in list(inner_cabling['2_roles'].keys())])]): self._mode = '2_roles' else: self.exec_logger.error(f'Invalid role assignment for {self.model}: {self._roles} !') diff --git a/ohmpi/hardware_components/pwr_dps5005.py b/ohmpi/hardware_components/pwr_dps5005.py index a43bdc6a56c15889214814f1beb6d33470a80e73..009bca71bde2d62f6d7fd6f6e1307aa76dc88d3f 100644 --- a/ohmpi/hardware_components/pwr_dps5005.py +++ b/ohmpi/hardware_components/pwr_dps5005.py @@ -63,6 +63,9 @@ class Pwr(PwrAbstract): # self.exec_logger.debug(f'{self.model} is on') # time.sleep(.3) + def _retrieve_voltage(self): + self._voltage = self.connection.read_register(0x0002, 2) + @property def voltage(self): # return PwrAbstract.voltage.fget(self) diff --git a/ohmpi/hardware_system.py b/ohmpi/hardware_system.py index 321c27a279937f630399c3ca0eba26b89ed837a2..c7a3b5268530558cf43a74bdb4661700579ef07e 100644 --- a/ohmpi/hardware_system.py +++ b/ohmpi/hardware_system.py @@ -191,7 +191,7 @@ class OhmPiHardware: self.exec_logger.event(f'OhmPiHardware\ttx_rx_gain_auto\tbegin\t{datetime.datetime.utcnow()}') current, voltage = 0., 0. if self.tx.pwr.voltage_adjustable: - self.tx.pwr.voltage = vab + self.tx.voltage = vab if self.tx.pwr.pwr_state == 'off': self.tx.pwr.pwr_state = 'on' switch_pwr_off = True @@ -265,7 +265,8 @@ class OhmPiHardware: while self.tx_sync.is_set(): lap = datetime.datetime.utcnow() - r = [elapsed_seconds(self._start_time), self._pulse, self.tx.polarity, self.tx.current, self.rx.voltage] + r = [elapsed_seconds(self._start_time), self._pulse, self.tx.polarity, self.tx.current, self.rx.voltage, + self.tx.voltage] if self.tx_sync.is_set(): sample += 1 _readings.append(r) @@ -469,7 +470,7 @@ class OhmPiHardware: if self.pwr_state == 'off': self.pwr_state = 'on' switch_tx_pwr_off = True - self.tx.pwr.voltage = vab + self.tx.voltage = vab if self.tx.pwr.pwr_state == 'off': self.tx.pwr.pwr_state = 'on' switch_pwr_off = True @@ -539,7 +540,7 @@ class OhmPiHardware: vab_list[k] = np.min(vabs) time.sleep(0.5) if self.tx.pwr.voltage_adjustable: - self.tx.pwr.voltage = vab_list[k] + self.tx.voltage = vab_list[k] vab_opt = vab_list[k] print(f'Selected Vab: {vab_opt:.2f}') if switch_pwr_off: @@ -634,10 +635,10 @@ class OhmPiHardware: if sampling_rate is None: sampling_rate = RX_CONFIG['sampling_rate'] if self.tx.pwr.voltage_adjustable: - if self.tx.pwr.voltage != vab: - self.tx.pwr.voltage = vab + if self.tx.voltage != vab: + self.tx.voltage = vab else: - vab = self.tx.pwr.voltage + vab = self.tx.voltage # reads current and voltage during the pulse injection = Thread(target=self._inject, kwargs={'injection_duration': duration, 'polarity': polarity}) readings = Thread(target=self._read_values, kwargs={'sampling_rate': sampling_rate, 'append': append}) @@ -655,9 +656,9 @@ class OhmPiHardware: n_pulses = len(durations) self.exec_logger.debug(f'n_pulses: {n_pulses}') if self.tx.pwr.voltage_adjustable: - self.tx.pwr.voltage = vab + self.tx.voltage = vab else: - vab = self.tx.pwr.voltage + vab = self.tx.voltage if self.tx.pwr.pwr_state == 'off': self.tx.pwr.pwr_state = 'on' switch_pwr_off = True diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py index c98da101fdc4f8b5256da35d44bdf7c18f52fd2c..768d74eab60d882e75f82f1e87d49480c61c3d19 100644 --- a/ohmpi/ohmpi.py +++ b/ohmpi/ohmpi.py @@ -500,7 +500,7 @@ class OhmPi(object): bypass_check = kwargs['bypass_check'] if 'bypass_check' in kwargs.keys() else False d = {} if self.switch_mux_on(quad, bypass_check=bypass_check, cmd_id=cmd_id): - # tx_volt,_ ,_ = self._hw._compute_tx_volt(tx_volt=tx_volt, strategy=strategy) + tx_volt,_ ,_ = self._hw._compute_tx_volt(tx_volt=tx_volt, strategy=strategy) self._hw.vab_square_wave(tx_volt, cycle_duration=injection_duration*2/duty_cycle, cycles=nb_stack, duty_cycle=duty_cycle) if 'delay' in kwargs.keys(): delay = kwargs['delay'] @@ -519,7 +519,7 @@ class OhmPi(object): "B": quad[1], "M": quad[2], "N": quad[3], - "inj time [ms]": injection_duration, # NOTE: check this + "inj time [ms]": injection_duration * 1000., # NOTE: check this "Vmn [mV]": Vmn, "I [mA]": I, "R [Ohm]": R, @@ -675,26 +675,27 @@ class OhmPi(object): if self.on_pi: acquired_data = self.run_measurement(quad=quad, **kwargs) else: # for testing, generate random data - sum_vmn = np.random.rand(1)[0] * 1000. - sum_i = np.random.rand(1)[0] * 100. - cmd_id = np.random.randint(1000) - acquired_data = { - "time": datetime.now().isoformat(), - "A": quad[0], - "B": quad[1], - "M": quad[2], - "N": quad[3], - "inj time [ms]": self.settings['injection_duration'] * 1000., - "Vmn [mV]": sum_vmn, - "I [mA]": sum_i, - "R [ohm]": sum_vmn / sum_i, - "Ps [mV]": np.random.randn(1)[0] * 100., - "nbStack": self.settings['nb_stack'], - "Tx [V]": np.random.randn(1)[0] * 5., - "CPU temp [degC]": np.random.randn(1)[0] * 50., - "Nb samples [-]": self.nb_samples, - } - self.data_logger.info(acquired_data) + # sum_vmn = np.random.rand(1)[0] * 1000. + # sum_i = np.random.rand(1)[0] * 100. + # cmd_id = np.random.randint(1000) + # acquired_data = { + # "time": datetime.now().isoformat(), + # "A": quad[0], + # "B": quad[1], + # "M": quad[2], + # "N": quad[3], + # "inj time [ms]": self.settings['injection_duration'] * 1000., + # "Vmn [mV]": sum_vmn, + # "I [mA]": sum_i, + # "R [ohm]": sum_vmn / sum_i, + # "Ps [mV]": np.random.randn(1)[0] * 100., + # "nbStack": self.settings['nb_stack'], + # "Tx [V]": np.random.randn(1)[0] * 5., + # "CPU temp [degC]": np.random.randn(1)[0] * 50., + # "Nb samples [-]": self.nb_samples, + # } + pass + self.data_logger.info(acquired_data) # # switch mux off # self.switch_mux_off(quad) @@ -991,7 +992,7 @@ class OhmPi(object): import pandas as pd #noqa import sys sys.path.append(os.path.join(pdir, '../../resipy/src/')) - from resipy import Project #noqa + from resipy import Project # noqa except Exception as e: self.exec_logger.error('Cannot import ResIPy, scipy or Pandas, error: ' + str(e)) return []