diff --git a/configs/config_mb_2023.py b/configs/config_mb_2023.py index 8bd970d8096ec3515ced1a1c9d11ea5e2aeabbc7..f3f566ba70a9fb3bf7797821b95578b28d48a232 100644 --- a/configs/config_mb_2023.py +++ b/configs/config_mb_2023.py @@ -17,14 +17,15 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2023_0_X', - 'voltage_max': 12., # Maximum voltage supported by the TX board [V] - 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2., # Shunt resistance in Ohms - 'interface_name': 'i2c', + 'voltage_max': 50., # Maximum voltage supported by the TX board [V] + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms + 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2023_0_X', 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V diff --git a/configs/config_mb_2023_3_mux_2024.py b/configs/config_mb_2023_3_mux_2024.py index 892582abf4abc29a21b94f4821f5f06f7f95f856..8373edcbe9830a0d05fbbf0a8ce3ee02cb18ccda 100644 --- a/configs/config_mb_2023_3_mux_2024.py +++ b/configs/config_mb_2023_3_mux_2024.py @@ -17,14 +17,15 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, - 'pwr': {'model': 'pwr_batt', 'voltage': 12.,'interface_name':'none'}, + 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2023_0_X', - 'voltage_max': 12., # Maximum voltage supported by the TX board [V] - 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2., # Shunt resistance in Ohms - 'interface_name': 'i2c', + 'voltage_max': 50., # Maximum voltage supported by the TX board [V] + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms + 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2023_0_X', 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V diff --git a/configs/config_mb_2023_4_mux_2023.py b/configs/config_mb_2023_4_mux_2023.py index fa30ccaadc748d016cd2307bff9678217e04259d..40665972ec78fcbb165cf92d2b3b5fb2fe617836 100644 --- a/configs/config_mb_2023_4_mux_2023.py +++ b/configs/config_mb_2023_4_mux_2023.py @@ -17,14 +17,15 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2023_0_X', - 'voltage_max': 12., # Maximum voltage supported by the TX board [V] - 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2., # Shunt resistance in Ohms - 'interface_name': 'i2c', + 'voltage_max': 50., # Maximum voltage supported by the TX board [V] + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms + 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2023_0_X', 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V diff --git a/configs/config_mb_2023_4_mux_2024.py b/configs/config_mb_2023_4_mux_2024.py index 19254ca112b0526895b64adb6afb23b1ace95ee0..f15f2af3127ea11b8469d20e109fbcc6120954d0 100644 --- a/configs/config_mb_2023_4_mux_2024.py +++ b/configs/config_mb_2023_4_mux_2024.py @@ -16,14 +16,15 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2023_0_X', - 'voltage_max': 12., # Maximum voltage supported by the TX board [V] - 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2., # Shunt resistance in Ohms - 'interface_name': 'i2c', + 'voltage_max': 50., # Maximum voltage supported by the TX board [V] + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms + 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2023_0_X', 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V diff --git a/configs/config_mb_2023__3_mux_2024_dps5005.py b/configs/config_mb_2023__3_mux_2024_dps5005.py index 26c0dddcc158167b2f6a7a700eaf2098bb410e3d..b4d7d2cce647f725fe30c95e665f02f1e0c10f8c 100644 --- a/configs/config_mb_2023__3_mux_2024_dps5005.py +++ b/configs/config_mb_2023__3_mux_2024_dps5005.py @@ -17,14 +17,15 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, - 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, + 'pwr': {'model': 'pwr_dps5005', 'voltage': 12., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2023_0_X', - 'voltage_max': 12., # Maximum voltage supported by the TX board [V] - 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2., # Shunt resistance in Ohms - 'interface_name': 'i2c', + 'voltage_max': 50., # Maximum voltage supported by the TX board [V] + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms + 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2023_0_X', 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V diff --git a/configs/config_mb_2024_0_2.py b/configs/config_mb_2024_0_2.py index f99c214d235e821f4b55fca27db02d6b5bff2760..c73ecf4176c1b9f23935fe196370fb741ae89477 100644 --- a/configs/config_mb_2024_0_2.py +++ b/configs/config_mb_2024_0_2.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__1_mux_2024.py b/configs/config_mb_2024_0_2__1_mux_2024.py index a9a91e4d052bb426c4f5c9e3765578b0a7f73a19..ecc683c7d09c56a11ac44cbd4327784e40da45c4 100644 --- a/configs/config_mb_2024_0_2__1_mux_2024.py +++ b/configs/config_mb_2024_0_2__1_mux_2024.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py index 86f5a3b59abe9c0d1e56d88463b892688749078c..60f5bfc061e71e10431b20ffb1dd670d37997604 100644 --- a/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py +++ b/configs/config_mb_2024_0_2__1_mux_2024_dps5005.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py index 6466bc801ceace9ab4c1cbf89f7b9877b9ee4969..a0f08b7995d9f7e94ea552d787bda027094792fa 100644 --- a/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py +++ b/configs/config_mb_2024_0_2__2_mux_2024_dps5005.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py index 5b8f4f56a4aff2271e1be00f89a8ae79b86b68bb..8fa5f2421b868ae8638be841186eea7b6972a7e8 100644 --- a/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py +++ b/configs/config_mb_2024_0_2__3_mux_2024_dps5005.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py index f2c4026afd073212525010563b4728104872633f..103f537ed1488796a68bce96b2721c1ccba3199d 100644 --- a/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py +++ b/configs/config_mb_2024_0_2__4_mux_2023__4_mux_2024_dps5005.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [mA] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py b/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py index 21acb17afeb6429861a6acd5eff1101881e3277e..abba800afd622de78efddc9ff8fb62855863ab22 100644 --- a/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py +++ b/configs/config_mb_2024_0_2__4_mux_2023_dps5005.py @@ -16,13 +16,14 @@ OHMPI_CONFIG = { 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.80/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', diff --git a/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py b/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py index 4fd7c4c0c8d55fe865591568382a533566ce3136..31c2538e8a5923f963f0f0fbce254307a2be17a4 100644 --- a/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py +++ b/configs/config_mb_2024_0_2__4_mux_2024_dps5005.py @@ -15,14 +15,14 @@ OHMPI_CONFIG = { 'id': ohmpi_id, # Unique identifier of the OhmPi board (string) 'settings': 'ohmpi_settings.json', # INSERT YOUR FAVORITE SETTINGS FILE HERE } - +r_shunt = 2. HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, 'pwr': {'model': 'pwr_dps5005', 'voltage': 3., 'interface_name': 'modbus'}, 'tx': {'model': 'mb_2024_0_2', 'voltage_max': 50., # Maximum voltage supported by the TX board [V] - 'current_max': 4800, # Maximum voltage read by the current ADC on the TX board [mA] - 'r_shunt': 2, # Shunt resistance in Ohms + 'current_max': 4.8/(50*r_shunt), # Maximum voltage read by the current ADC on the TX board [A] + 'r_shunt': r_shunt, # Shunt resistance in Ohms 'interface_name': 'i2c' }, 'rx': {'model': 'mb_2024_0_2', @@ -42,7 +42,7 @@ HARDWARE_CONFIG = { # 'mcp_1': '0x27', 'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'}, 'cabling': {(i+8, j): ('mux_02', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)}, - 'voltage_max': 12.}, + 'voltage_max': 50.}, 'mux_03': {'model': 'mux_2024_0_X', 'tca_address': None, @@ -53,7 +53,7 @@ HARDWARE_CONFIG = { # 'mcp_1': '0x27', 'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'}, 'cabling': {(i+24, j): ('mux_03', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)}, - 'voltage_max': 12.}, + 'voltage_max': 50.}, 'mux_05': {'model': 'mux_2024_0_X', 'tca_address': None, @@ -62,7 +62,7 @@ HARDWARE_CONFIG = { 'addr1': 'down', 'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'}, 'cabling': {(i+0, j): ('mux_05', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)}, - 'voltage_max': 12.}, + 'voltage_max': 50.}, 'mux_06': {'model': 'mux_2024_0_X', 'tca_address': None, @@ -71,11 +71,12 @@ HARDWARE_CONFIG = { 'addr1': 'down', 'roles': {'A': 'X', 'B': 'Y', 'M': 'XX', 'N': 'YY'}, 'cabling': {(i+16, j): ('mux_06', i) for j in ['A', 'B', 'M', 'N'] for i in range(1, 9)}, - 'voltage_max': 12.}, + 'voltage_max': 50.}, }, 'default': {'interface_name': 'i2c_ext', 'voltage_max': 100., - 'current_max': 3.} + 'current_max': 3. + } } } diff --git a/dev/test_mb_2024_4_mux_2024.py b/dev/test_mb_2024_4_mux_2024.py index 259ac9b7f747ce210ceae5c687d22ea5c7ed4b3e..bf541f13dba999db195c51e00fffd48860e8d044 100644 --- a/dev/test_mb_2024_4_mux_2024.py +++ b/dev/test_mb_2024_4_mux_2024.py @@ -40,32 +40,36 @@ if stand_alone: rx = rx_module.Rx(**HARDWARE_CONFIG['rx']) tx = tx_module.Tx(**HARDWARE_CONFIG['tx']) pwr = pwr_module.Pwr(**HARDWARE_CONFIG['pwr']) - mux_ids = ['mux_02', 'mux_05'] - for m,mux_id in enumerate(mux_ids): - mux_module = importlib.import_module( - f'ohmpi.hardware_components.{HARDWARE_CONFIG["mux"]["boards"][mux_id].pop("model")}') - - MUX_CONFIG = HARDWARE_CONFIG['mux']['boards'][mux_id] - - MUX_CONFIG.update({'ctl': ctl, 'connection': MUX_CONFIG.pop('connection', ctl.interfaces[ - MUX_CONFIG.pop('interface_name', 'i2c_ext')]), 'exec_logger': ctl.exec_logger, - 'soh_logger': ctl.soh_logger}) - MUX_CONFIG.update({'id': mux_id}) - mux = mux_module.Mux(**MUX_CONFIG) - - # tx.polarity = 1 - # time.sleep(1) - # tx.polarity = 0 - # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='on') - # time.sleep(1) - # voltage = rx.voltage - # current = tx.current - # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='off') - # print(f'Resistance: {voltage / current :.2f} ohm, voltage: {voltage:.2f} mV, current: {current:.2f} mA') - mux.reset() - mux.test({'A': [i+8*m for i in range(1, 9)], 'B': [i+8*m for i in range(1, 9)], - 'M': [i+8*m for i in range(1, 9)], 'N': [i+8*m for i in range(1, 9)]}, activation_time=.1) - mux.reset() + # mux_ids = ['mux_02', 'mux_05'] + # for m,mux_id in enumerate(mux_ids): + # mux_module = importlib.import_module( + # f'ohmpi.hardware_components.{HARDWARE_CONFIG["mux"]["boards"][mux_id].pop("model")}') + # + # MUX_CONFIG = HARDWARE_CONFIG['mux']['boards'][mux_id] + # + # MUX_CONFIG.update({'ctl': ctl, 'connection': MUX_CONFIG.pop('connection', ctl.interfaces[ + # MUX_CONFIG.pop('interface_name', 'i2c_ext')]), 'exec_logger': ctl.exec_logger, + # 'soh_logger': ctl.soh_logger}) + # MUX_CONFIG.update({'id': mux_id}) + # mux = mux_module.Mux(**MUX_CONFIG) + # + # # tx.polarity = 1 + # # time.sleep(1) + # # tx.polarity = 0 + # # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='on') + # # time.sleep(1) + # # voltage = rx.voltage + # # current = tx.current + # # mux.switch(elec_dict={'A': [1], 'B': [4], 'M': [2], 'N': [3]}, state='off') + # # print(f'Resistance: {voltage / current :.2f} ohm, voltage: {voltage:.2f} mV, current: {current:.2f} mA') + # mux.reset() + # mux.test({'A': [i+8*m for i in range(1, 9)], 'B': [i+8*m for i in range(1, 9)], + # 'M': [i+8*m for i in range(1, 9)], 'N': [i+8*m for i in range(1, 9)]}, activation_time=.1) + # mux.reset() + for pol in [1,0,-1,0]: + tx.polarity = pol + print(pol) + time.sleep(5) # mux as part of a OhmPiHardware system if part_of_hardware_system: @@ -105,14 +109,15 @@ if within_ohmpi: # k._hw.switch_mux([A, B, M, N], state='off') # print(f'OhmPiHardware Resistance: {k._hw.last_rho :.2f} ohm, dev. {k._hw.last_dev:.2f} %, rx bias: {k._hw.rx._bias:.2f} mV') # k._hw._plot_readings() - # k.load_sequence('sequences/9991_GRAD_16_s1_a1.txt') - # k.run_sequence(tx_volt=5., injection_duration=1., nb_stack=2, duty_cycle=0.5) + k.load_sequence('sequences/9991_GRAD_16_s1_a1.txt') + k.run_sequence(tx_volt=5, injection_duration=1., nb_stack=2, duty_cycle=0.5) print('using OhmPi') - d = k.run_measurement([A, B, M, N], injection_duration=1., nb_stack=2, duty_cycle=0.5) + # d = k.run_measurement([A, B, M, N], injection_duration=1., nb_stack=2, duty_cycle=0.5, tx_volt=5.) # print(d) - k._hw._plot_readings() + # k._hw._plot_readings() print(f'OhmPiHardware: Resistance: {k._hw.last_resistance() :.2f} ohm, dev. {k._hw.last_dev():.2f} %, sp: {k._hw.sp:.2f} mV, rx bias: {k._hw.rx._bias:.2f} mV') print(f'OhmPi: Resistance: {d["R [Ohm]"] :.2f} ohm, dev. {d["R_std [%]"]:.2f} %, rx bias: {k._hw.rx._bias:.2f} mV') # k._hw._plot_readings(save_fig=False) # plot_exec_log('ohmpi/logs/exec.log') change_config('../configs/config_default.py', verbose=False) + diff --git a/ohmpi/hardware_components/abstract_hardware_components.py b/ohmpi/hardware_components/abstract_hardware_components.py index 3ae488e1efd2f8a183580eeb3823d63231239879..be1e51e2c2712e249988d975d014503f8b1eacc7 100644 --- a/ohmpi/hardware_components/abstract_hardware_components.py +++ b/ohmpi/hardware_components/abstract_hardware_components.py @@ -55,6 +55,7 @@ class PwrAbstract(ABC): self._current_max = kwargs.pop('current_max', 0.) self._voltage_min = kwargs.pop('voltage_min', 0.) self._voltage_max = kwargs.pop('voltage_max', 0.) + self._switchable = False self.connection = kwargs.pop('connection', None) self._battery_voltage = np.nan @@ -93,6 +94,8 @@ class PwrAbstract(ABC): self._pwr_state = 'off' self.exec_logger.debug(f'{self.model} cannot be switched off') + def reload_settings(self): + pass @property @abstractmethod @@ -278,6 +281,7 @@ class TxAbstract(ABC): self.soh_logger = create_stdout_logger('soh_tx') self.connection = kwargs.pop('connection', None) self.pwr = kwargs.pop('pwr', None) + self._voltage = 0. self._polarity = 0 self._injection_duration = None self._gain = 1. @@ -302,6 +306,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): @@ -370,6 +385,18 @@ class TxAbstract(ABC): def tx_bat(self): pass + @property + def voltage(self): + """ Gets the voltage VAB in Volts + """ + return self._voltage + + @voltage.setter + def voltage(self, value): + assert value >= 0. + self._voltage = value + self.pwr.voltage = value + def voltage_pulse(self, voltage=0., length=None, polarity=1): """ Generates a square voltage pulse @@ -396,7 +423,9 @@ class TxAbstract(ABC): def pwr_state(self, state): if state == 'on': self._pwr_state = 'on' - self.exec_logger.debug(f'{self.model} cannot switch on power source') + if not self.pwr.switchable: + self.exec_logger.debug(f'{self.model} cannot switch on power source') + self.pwr.reload_settings() elif state == 'off': self._pwr_state = 'off' self.exec_logger.debug(f'{self.model} cannot switch off power source') diff --git a/ohmpi/hardware_components/mb_2023_0_X.py b/ohmpi/hardware_components/mb_2023_0_X.py index dff4eaa494fa791ed68e402665a40c09f5276d88..f9ae9368f2ec997d3fdf598b97a4644993e061de 100644 --- a/ohmpi/hardware_components/mb_2023_0_X.py +++ b/ohmpi/hardware_components/mb_2023_0_X.py @@ -78,7 +78,7 @@ class Tx(TxAbstract): self.exec_logger.event(f'{self.model}\ttx_init\tbegin\t{datetime.datetime.utcnow()}') assert isinstance(self.connection, I2C) kwargs.update({'pwr': kwargs.pop('pwr', SPECS['tx']['compatible_power_sources']['default'][0])}) - if (kwargs['pwr'] not in SPECS['tx']['compatible_power_sources']['default']): + if kwargs['pwr'] not in SPECS['tx']['compatible_power_sources']['default']: self.exec_logger.warning(f'Incompatible power source specified check config') assert kwargs['pwr'] in SPECS['tx'] self._activation_delay = kwargs['activation_delay'] @@ -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 - self.exec_logger.debug(f'Reading TX current: {iab} mA') + 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,7 +190,6 @@ class Tx(TxAbstract): else: return self.pwr.battery_voltage - 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..33fe7ee461234b44c7a711558b96b85f5dc0742f 100644 --- a/ohmpi/hardware_components/mb_2024_0_2.py +++ b/ohmpi/hardware_components/mb_2024_0_2.py @@ -21,17 +21,18 @@ SPECS = {'rx': {'model': {'default': os.path.basename(__file__).rstrip('.py')}, 'mcp_address': {'default': 0x27}, 'ads_address': {'default': 0x49}, 'voltage_min': {'default': 10.0}, + 'dg411_gain_ratio': {'default': 1/2}, # lowest resistor value over sum of resistor values 'vmn_hardware_offset': {'default': 2500.}, }, 'tx': {'model': {'default': os.path.basename(__file__).rstrip('.py')}, 'adc_voltage_min': {'default': 10.}, # Minimum voltage value used in vmin strategy 'adc_voltage_max': {'default': 4500.}, # Maximum voltage on ads1115 used to measure current - 'voltage_max': {'min': 0., 'default': 12., 'max': 12.}, # Maximum input voltage + 'voltage_max': {'min': 0., 'default': 12., 'max': 50.}, # Maximum input voltage 'data_rate': {'default': 860.}, '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 +87,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 @@ -144,7 +145,9 @@ class Rx(Rx_mb_2023): # ADS1115 for voltage measurement (MN) self._coef_p2 = 1. # Define default DG411 gain - self._dg411_gain = 1/2 + self._dg411_gain_ratio = kwargs['dg411_gain_ratio'] + self._dg411_gain = self._dg411_gain_ratio + # Define pins for DG411 self.pin_DG0 = self.mcp_board.get_pin(0) self.pin_DG0.direction = Direction.OUTPUT @@ -170,7 +173,7 @@ class Rx(Rx_mb_2023): if self.voltage < self._vmn_hardware_offset : self._dg411_gain = 1. else: - self._dg411_gain = 1/2 + self._dg411_gain = self._dg411_gain_ratio self.exec_logger.debug(f'Setting RX DG411 gain automatically to {self._dg411_gain}') @property @@ -184,7 +187,7 @@ class Rx(Rx_mb_2023): if self._dg411_gain == 1.: self.pin_DG1.value = False # closed gain 1 active self.pin_DG2.value = True # open gain 0.5 inactive - elif self._dg411_gain == 1/2: + elif self._dg411_gain == self._dg411_gain_ratio: self.pin_DG1.value = True # closed gain 1 active self.pin_DG2.value = False # open gain 0.5 inactive 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 dd2b0d8e85c638c40b3dd27feea931303ba13d1b..13fed777042690c38fc74104e46bbbd54028014f 100644 --- a/ohmpi/hardware_components/pwr_dps5005.py +++ b/ohmpi/hardware_components/pwr_dps5005.py @@ -11,10 +11,10 @@ SPECS = {'model': {'default': os.path.basename(__file__).rstrip('.py')}, 'voltage': {'default': 12., 'max': 50., 'min': 0.}, 'voltage_min': {'default': 0}, 'voltage_max': {'default': 0}, - 'current_max': {'default': 100.}, + 'current_max': {'default': 60.}, 'current_adjustable': {'default': False}, 'voltage_adjustable': {'default': True}, - 'pwr_latency': {'default': .3} + 'pwr_latency': {'default': .5} } # TODO: Complete this code... handle modbus connection @@ -54,14 +54,8 @@ class Pwr(PwrAbstract): def current(self, value, **kwargs): self.exec_logger.debug(f'Current cannot be set on {self.model}') - # def turn_off(self): - # self.connection.write_register(0x09, 0) - # self.exec_logger.debug(f'{self.model} is off') - # - # def turn_on(self): - # self.connection.write_register(0x09, 1) - # 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): @@ -103,3 +97,7 @@ class Pwr(PwrAbstract): self.connection.write_register(0x09, 0) self._pwr_state = 'off' self.exec_logger.debug(f'{self.model} is off') + + def reload_settings(self): + # self.voltage(self._voltage) + self.current_max(self._current_max) diff --git a/ohmpi/hardware_system.py b/ohmpi/hardware_system.py index 883412fb7371244dc5160fc61aa384c77d1ecb8b..4c817bacc10f4eb28ce23162319ebde91b98c8af 100644 --- a/ohmpi/hardware_system.py +++ b/ohmpi/hardware_system.py @@ -43,7 +43,7 @@ for k, v in rx_module.SPECS['rx'].items(): except Exception as e: print(f'Cannot set value {v} in RX_CONFIG[{k}]:\n{e}') -current_max = np.min([TX_CONFIG['voltage_max']/50/TX_CONFIG['r_shunt'], # TODO: replace 50 by a TX config +current_max = np.min([TX_CONFIG['current_max'], # TODO: replace 50 by a TX config np.min(np.hstack((np.inf, [MUX_CONFIG[i].pop('current_max', np.inf) for i in MUX_CONFIG.keys()])))]) voltage_max = np.min([TX_CONFIG['voltage_max'], np.min(np.hstack((np.inf, [MUX_CONFIG[i].pop('voltage_max', np.inf) for i in MUX_CONFIG.keys()])))]) @@ -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 @@ -317,94 +317,46 @@ class OhmPiHardware: sp = np.mean(mean_vmn[np.ix_(polarity == 1)] + mean_vmn[np.ix_(polarity == -1)]) / 2 return sp - # def _compute_tx_volt(self, pulse_duration=0.1, strategy='vmax', tx_volt=5., - # vab_max=voltage_max, vmn_min=voltage_min): - # """Estimates best Tx voltage based on different strategies. - # At first a half-cycle is made for a short duration with a fixed - # known voltage. This gives us Iab and Rab. We also measure Vmn. - # A constant c = vmn/iab is computed (only depends on geometric - # factor and ground resistivity, that doesn't change during a - # quadrupole). Then depending on the strategy, we compute which - # vab to inject to reach the minimum/maximum Iab current or - # min/max Vmn. - # This function also compute the polarity on Vmn (on which pin - # of the ADS1115 we need to measure Vmn to get the positive value). - # - # Parameters - # ---------- - # pulse_duration : float, optional - # Time in seconds for the pulse used to compute Rab. - # strategy : str, optional - # Either: - # - vmax : compute Vab to reach a maximum Iab without exceeding vab_max - # - vmin : compute Vab to reach at least vmn_min - # - constant : apply given Vab - # tx_volt : float, optional - # Voltage to apply for guessing the best voltage. 5 V applied - # by default. If strategy "constant" is chosen, constant voltage - # to applied is "tx_volt". - # vab_max : float, optional - # Maximum injection voltage to apply to tx (used by all strategies) - # vmn_min : float, optional - # Minimum voltage target for rx (used by vmin strategy) - # - # Returns - # ------- - # vab : float - # Proposed Vab according to the given strategy. - # polarity: - # Polarity of VMN relative to polarity of VAB - # rab : float - # Resistance between injection electrodes - # """ - # - # vab_max = np.abs(vab_max) - # vmn_min = np.abs(vmn_min) - # vab = np.min([np.abs(tx_volt), vab_max]) - # # self.tx.turn_on() - # switch_pwr_off, switch_tx_pwr_off = False, False #TODO: check if these should be moved in kwargs - # if self.tx.pwr_state == 'off': - # self.tx.pwr_state = 'on' - # switch_tx_pwr_off = True - # if self.tx.pwr.pwr_state == 'off': - # self.tx.pwr.pwr_state = 'on' - # switch_pwr_off = True - # if 1. / self.rx.sampling_rate > pulse_duration: - # sampling_rate = 1. / pulse_duration # TODO: check this... - # else: - # sampling_rate = self.tx.sampling_rate - # self._vab_pulse(vab=vab, duration=pulse_duration, sampling_rate=sampling_rate) # TODO: use a square wave pulse? - # vmn = np.mean(self.readings[:, 4]) - # iab = np.mean(self.readings[:, 3]) - # # if np.abs(vmn) is too small (smaller than voltage_min), strategy is not constant and vab < vab_max , - # # then we could call _compute_tx_volt with a tx_volt increased to np.min([vab_max, tx_volt*2.]) for example - # if strategy == 'vmax': - # # implement different strategies - # if vab < vab_max and iab < current_max: - # vab = vab * np.min([0.9 * vab_max / vab, 0.9 * current_max / iab]) # TODO: check if setting at 90% of max as a safety margin is OK - # self.tx.exec_logger.debug(f'vmax strategy: setting VAB to {vab} V.') - # elif strategy == 'vmin': - # if vab <= vab_max and iab < current_max: - # vab = vab * np.min([0.9 * vab_max / vab, vmn_min / np.abs(vmn), 0.9 * current_max / iab]) # TODO: check if setting at 90% of max as a safety margin is OK - # elif strategy != 'constant': - # self.tx.exec_logger.warning(f'Unknown strategy {strategy} for setting VAB! Using {vab} V') - # else: - # self.tx.exec_logger.debug(f'Constant strategy for setting VAB, using {vab} V') - # # self.tx.turn_off() - # if switch_pwr_off: - # self.tx.pwr.pwr_state = 'off' - # if switch_tx_pwr_off: - # self.tx.pwr_state = 'off' - # rab = (np.abs(vab) * 1000.) / iab - # self.exec_logger.debug(f'RAB = {rab:.2f} Ohms') - # if vmn < 0: - # polarity = -1 # TODO: check if we really need to return polarity - # else: - # polarity = 1 - # return vab, polarity, rab - - def _compute_tx_volt(self, pulse_duration=0.1, strategy='vmax', tx_volt=5., - vab_max=voltage_max, vmn_min=voltage_min, polarities=(1, -1), delay=0.050): + def _find_vab(self, vab, iab, vmn, p_max, vab_max, iab_max, vmn_max): + iab_mean = np.mean(iab) + iab_std = np.std(iab) + vmn_mean = np.mean(vmn) + vmn_std = np.std(vmn) + print(f'iab: ({iab_mean:.5f}, {iab_std:5f}), vmn: ({vmn_mean:.4f}, {vmn_std:.4f})') + # bounds on iab + iab_upper_bound = iab_mean + 2 * iab_std + iab_lower_bound = np.max([0.00001, iab_mean - 2 * iab_std]) + # bounds on vmn + vmn_upper_bound = vmn_mean + 2 * vmn_std + vmn_lower_bound = np.max([0.000001, vmn_mean - 2 * vmn_std]) + # bounds on rab + rab_lower_bound = np.max([0.1, np.abs(vab / iab_upper_bound)]) + rab_upper_bound = np.max([0.1, np.abs(vab / iab_lower_bound)]) + # bounds on r + r_lower_bound = np.max([0.1, np.abs(vmn_lower_bound / iab_upper_bound)]) + r_upper_bound = np.max([0.1, np.abs(vmn_upper_bound / iab_lower_bound)]) + # conditions for vab update + cond_vmn_max = rab_lower_bound / r_upper_bound * vmn_max + cond_p_max = np.sqrt(p_max * rab_lower_bound) + cond_iab_max = rab_lower_bound * iab_max + print(f'Rab: [{rab_lower_bound:.1f}, {rab_upper_bound:.1f}], R: [{r_lower_bound:.1f},{r_upper_bound:.1f}]') + print(f'{k}: [{vab_max:.1f}, {cond_vmn_max:.1f}, {cond_p_max:.1f}, {cond_iab_max:.1f}]') + new_vab = np.min([vab_max, cond_vmn_max, cond_p_max, cond_iab_max]) + if new_vab == vab_max: + print('Vab bounded by Vab max') + elif new_vab == cond_p_max: + print('Vab bounded by P max') + elif new_vab == cond_iab_max: + print('Vab bounded by Iab max') + else: + assert new_vab == cond_vmn_max + print('Vab bounded by Vmn max') + + return new_vab + + def _compute_tx_volt(self, pulse_duration=0.1, strategy='vmax', tx_volt=5., vab_max=voltage_max, + iab_max=current_max, vmn_max=5., vmn_min=voltage_min, polarities=(1, -1), delay=0.050): + # TODO: Optimise how to pass iab_max, vab_max, vmn_min """Estimates best Tx voltage based on different strategies. At first a half-cycle is made for a short duration with a fixed known voltage. This gives us Iab and Rab. We also measure Vmn. @@ -444,105 +396,64 @@ class OhmPiHardware: Resistance between injection electrodes """ - # TODO: Get those values from components - p_max = 2.5 - vmn_max = 5. - vab_max = 50. - - # define a sill - diff_vab_lim = 2.5 - n_steps = 4 - - # Set gain at min - self.rx.reset_gain() - - vab_max = np.abs(vab_max) - vmn_min = np.abs(vmn_min) - k = 0 - vab_list = np.zeros(n_steps + 1) * np.nan - vab = np.min([np.abs(tx_volt), vab_max]) - vab_list[k] = vab - # self.tx.turn_on() - switch_pwr_off, switch_tx_pwr_off = False, False # TODO: check if these should be moved in kwargs - if self.tx.pwr_state == 'off': - self.tx.pwr_state = 'on' - switch_tx_pwr_off = True - if self.tx.pwr.pwr_state == 'off': - self.tx.pwr.pwr_state = 'on' - switch_pwr_off = True - if 1. / self.rx.sampling_rate > pulse_duration: - sampling_rate = 1. / pulse_duration # TODO: check this... - else: - sampling_rate = self.rx.sampling_rate - current, voltage = 0., 0. if self.tx.pwr.voltage_adjustable: - self.tx.pwr.voltage = vab - if self.tx.pwr.pwr_state == 'off': - self.tx.pwr.pwr_state = 'on' - switch_pwr_off = True - diff_vab = np.inf - while (k < n_steps) and (diff_vab > diff_vab_lim): - vabs = [] - for pol in polarities: - # self.tx.polarity = pol - # set gains automatically - injection = Thread(target=self._inject, kwargs={'injection_duration': 0.2, 'polarity': pol}) - readings = Thread(target=self._read_values) - injection.start() - self.tx_sync.wait() - readings.start() - readings.join() - injection.join() - v = np.where((self.readings[:, 0] > delay) & (self.readings[:, 2] != 0))[0] # NOTE : discard data aquired in the first x ms - iab = self.readings[v, 3]/1000. - vmn = np.abs(self.readings[v, 4]/1000. * self.readings[v, 2]) - iab_mean = np.mean(iab) - iab_std = np.std(iab) - vmn_mean = np.mean(vmn) - vmn_std = np.std(vmn) - print(f'iab: ({iab_mean:.5f}, {iab_std:5f}), vmn: ({vmn_mean:.4f}, {vmn_std:.4f})') - # bounds on iab - iab_upper_bound = iab_mean + 2 * iab_std - iab_lower_bound = np.max([0.00001, iab_mean - 2 * iab_std]) - # bounds on vmn - vmn_upper_bound = vmn_mean + 2 * vmn_std - vmn_lower_bound = np.max([0.000001, vmn_mean - 2 * vmn_std]) - # ax.plot([vab[k]] * 2, [vmn_lower_bound, vmn_upper_bound], '-b') - # ax.plot([0, vab_max], [0, vmn_upper_bound * vab_max / vab[k]], '-r', alpha=(k + 1) / n_steps) - # ax.plot([0, vab_max], [0, vmn_lower_bound * vab_max / vab[k]], '-g', alpha=(k + 1) / n_steps) - # bounds on rab - print(f'rab_lb: {vab_list[k] / iab_upper_bound}') - rab_lower_bound = np.min([0.1, np.abs(vab_list[k] / iab_upper_bound)]) - rab_upper_bound = np.min([0.1, np.abs(vab_list[k] / iab_lower_bound)]) - # bounds on r - r_lower_bound = np.min([0.01, np.abs(vmn_lower_bound / iab_upper_bound)]) - r_upper_bound = np.min([0.01, np.abs(vmn_upper_bound / iab_lower_bound)]) - # conditions for vab update - cond_vmn_max = rab_lower_bound / r_upper_bound * vmn_max - cond_p_max = np.sqrt(p_max * rab_lower_bound) - new_vab = np.min([vab_max, cond_vmn_max, cond_p_max]) - diff_vab = np.abs(new_vab - vab_list[k]) - print(f'Rab: [{rab_lower_bound:.1f}, {rab_upper_bound:.1f}], R: [{r_lower_bound:.1f},{r_upper_bound:.1f}]') - print( - f'{k}: [{vab_max:.1f}, {cond_vmn_max:.1f}, {cond_p_max:.1f}], new_vab: {new_vab}, diff_vab: {diff_vab}\n') - if new_vab == vab_max: - print('Vab bounded by Vab max') - elif new_vab == cond_p_max: - print('Vab bounded by Pmax') - elif new_vab == cond_vmn_max: - print('Vab bounded by Vmn max') - else: - print('Next step') - vabs.append(new_vab) - if diff_vab < diff_vab_lim: - print('stopped on vab increase too small') - else: - print('stopped on maximum number of steps reached') - k = k + 1 - vab_list[k] = np.min(vabs) - vab_opt = vab_list[k] - print(f'Selected Vab: {vab_opt:.2f}') - + # Get those values from components + p_max = vab_max * iab_max + + # define a sill + diff_vab_lim = 2.5 + n_steps = 4 + + # Set gain at min + self.rx.reset_gain() + + vab_max = np.abs(vab_max) + vmn_min = np.abs(vmn_min) + k = 0 + vab_list = np.zeros(n_steps + 1) * np.nan + vab = np.min([np.abs(tx_volt), vab_max]) + vab_list[k] = vab + # self.tx.turn_on() + switch_pwr_off, switch_tx_pwr_off = False, False # TODO: check if these should be moved in kwargs + if self.pwr_state == 'off': + self.pwr_state = 'on' + switch_tx_pwr_off = True + self.tx.voltage = vab + if self.tx.pwr.pwr_state == 'off': + self.tx.pwr.pwr_state = 'on' + switch_pwr_off = True + if 1. / self.rx.sampling_rate > pulse_duration: + sampling_rate = 1. / pulse_duration # TODO: check this... + else: + sampling_rate = self.rx.sampling_rate + current, voltage = 0., 0. + diff_vab = np.inf + while (k < n_steps) and (diff_vab > diff_vab_lim): + vabs = [] + self._vab_pulses(vab_list[k], sampling_rate=self.rx.sampling_rate, durations=[0.2, 0.2], polarities=[1, -1]) + for pulse in range(2): + v = np.where((self.readings[:, 0] > delay) & (self.readings[:, 2] != 0) & (self.readings[:, 1]==pulse))[0] # NOTE : discard data aquired in the first x ms + iab = self.readings[v, 3]/1000. + vmn = np.abs(self.readings[v, 4]/1000. * self.readings[v, 2]) + new_vab = self._find_vab(vab_list[k], iab, vmn, p_max, vab_max, iab_max, vmn_max) + diff_vab = np.abs(new_vab - vab_list[k]) + vabs.append(new_vab) + print(f'new_vab: {new_vab}, diff_vab: {diff_vab}\n') + if diff_vab < diff_vab_lim: + print('stopped on vab increase too small') + else: + print('stopped on maximum number of steps reached') + k = k + 1 + vab_list[k] = np.min(vabs) + time.sleep(0.5) + if self.tx.pwr.voltage_adjustable: + self.tx.voltage = vab_list[k] + vab_opt = vab_list[k] + # print(f'Selected Vab: {vab_opt:.2f}') + # if switch_pwr_off: + # self.tx.pwr.pwr_state = 'off' + else: + vab_opt = tx_volt # if strategy == 'vmax': # # implement different strategies # if vab < vab_max and iab < current_max: @@ -566,7 +477,7 @@ class OhmPiHardware: # polarity = -1 # TODO: check if we really need to return polarity # else: # polarity = 1 - return vab_opt, None, None + return vab_opt def _plot_readings(self, save_fig=False): # Plot graphs @@ -631,10 +542,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}) @@ -652,9 +563,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 5599f10aa2c9378412dd83a66e85ce162171e7a4..b8fd249e6a55713569123f78bde7a0e0e4374b3a 100644 --- a/ohmpi/ohmpi.py +++ b/ohmpi/ohmpi.py @@ -517,7 +517,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=.5, strategy=strategy, vab_max=50., vmn_max=1.) # TODO: use tx_volt and vmn_max instead of hardcoded values 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'] @@ -536,7 +536,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, @@ -545,7 +545,7 @@ class OhmPi(object): "nbStack": nb_stack, "Tx [V]": tx_volt, "CPU temp [degC]": self._hw.ctl.cpu_temperature, - "Nb samples [-]": len(self._hw.readings), # TODO: use only samples after a delay in each pulse + "Nb samples [-]": len(self._hw.readings[x,2]), # TODO: use only samples after a delay in each pulse "fulldata": self._hw.readings[:, [0, -2, -1]], # "I_stack [mA]": i_stack_mean, "I_std [%]": I_std, @@ -699,26 +699,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) @@ -1023,11 +1024,11 @@ class OhmPi(object): pdir = os.path.dirname(__file__) # import resipy if available try: - from scipy.interpolate import griddata - import pandas as pd + from scipy.interpolate import griddata # noqa + import pandas as pd #noqa import sys sys.path.append(os.path.join(pdir, '../../resipy/src/')) - from resipy import Project + from resipy import Project # noqa except Exception as e: self.exec_logger.error('Cannot import ResIPy, scipy or Pandas, error: ' + str(e)) return []