hitl_tester.modules.bms.dmm
Provides controls for the Rigol DM3068 DMM.
(c) 2020-2024 TurnAround Factor, Inc.
#
CUI DISTRIBUTION CONTROL
Controlled by: DLA J68 R&D SBIP
CUI Category: Small Business Research and Technology
Distribution/Dissemination Controls: PROTECTED BY SBIR DATA RIGHTS
POC: GOV SBIP Program Manager Denise Price, 571-767-0111
Distribution authorized to U.S. Government Agencies only, to protect information not owned by the
U.S. Government and protected by a contractor’s ‘limited rights’ statement, or received with the understanding that
it is not routinely transmitted outside the U.S. Government (determination made September 14, 2024). Other requests
for this document shall be referred to ACOR DLA Logistics Operations (J-68), 8725 John J. Kingman Rd., Suite 4317,
Fort Belvoir, VA 22060-6221
#
SBIR DATA RIGHTS
Contract No.:SP4701-23-C-0083
Contractor Name: TurnAround Factor, Inc.
Contractor Address: 10365 Wood Park Ct. Suite 313 / Ashland, VA 23005
Expiration of SBIR Data Rights Period: September 24, 2029
The Government's rights to use, modify, reproduce, release, perform, display, or disclose technical data or computer
software marked with this legend are restricted during the period shown as provided in paragraph (b)(4) of the Rights
in Noncommercial Technical Data and Computer Software--Small Business Innovative Research (SBIR) Program clause
contained in the above identified contract. No restrictions apply after the expiration date shown above. Any
reproduction of technical data, computer software, or portions thereof marked with this legend must also reproduce
the markings.
1""" 2Provides controls for the Rigol DM3068 DMM. 3 4# (c) 2020-2024 TurnAround Factor, Inc. 5# 6# CUI DISTRIBUTION CONTROL 7# Controlled by: DLA J68 R&D SBIP 8# CUI Category: Small Business Research and Technology 9# Distribution/Dissemination Controls: PROTECTED BY SBIR DATA RIGHTS 10# POC: GOV SBIP Program Manager Denise Price, 571-767-0111 11# Distribution authorized to U.S. Government Agencies only, to protect information not owned by the 12# U.S. Government and protected by a contractor’s ‘limited rights’ statement, or received with the understanding that 13# it is not routinely transmitted outside the U.S. Government (determination made September 14, 2024). Other requests 14# for this document shall be referred to ACOR DLA Logistics Operations (J-68), 8725 John J. Kingman Rd., Suite 4317, 15# Fort Belvoir, VA 22060-6221 16# 17# SBIR DATA RIGHTS 18# Contract No.:SP4701-23-C-0083 19# Contractor Name: TurnAround Factor, Inc. 20# Contractor Address: 10365 Wood Park Ct. Suite 313 / Ashland, VA 23005 21# Expiration of SBIR Data Rights Period: September 24, 2029 22# The Government's rights to use, modify, reproduce, release, perform, display, or disclose technical data or computer 23# software marked with this legend are restricted during the period shown as provided in paragraph (b)(4) of the Rights 24# in Noncommercial Technical Data and Computer Software--Small Business Innovative Research (SBIR) Program clause 25# contained in the above identified contract. No restrictions apply after the expiration date shown above. Any 26# reproduction of technical data, computer software, or portions thereof marked with this legend must also reproduce 27# the markings. 28""" 29 30from __future__ import annotations 31 32import time 33from time import sleep 34 35from hitl_tester.modules.bms_types import SafeResource, DMMImpedance 36 37 38class Dmm: 39 """Rigol DM3068 DMM command wrapper.""" 40 41 def __init__(self, resource: SafeResource): 42 """ 43 Initialize the DM3068 wrapper with a specific PyVISA resource. 44 This class does NOT open the resource, you have to open it for yourself! 45 """ 46 self.resource = resource 47 self.voltage_range = 20 # The maximum voltage that can be measured 48 self.impedance_config = DMMImpedance(1, 1) 49 self.reset() 50 51 def configure_voltage_normal(self): 52 """The voltage settings for normal measurements.""" 53 self.resource.write("ZERO:AUTO ON") # Only take the zero reading at the start. Speeds up measurement 54 self.resource.write(f"CONF:VOLT:DC {self.voltage_range}") # Range(V) = 0.2, 2, 20, 200, 1000, AUTO 55 self.resource.write("VOLT:DC:NPLC 10") # NPLC = 0.006, 0.02, 0.2, 1, 10, 100. 1PLC is equal to 0.02s 56 57 def configure_voltage_trigger( 58 self, timestamps: bool = False, sample_count: int = 2000 59 ): # pylint: disable=unused-argument 60 """Set up trigger parameters.""" 61 self.resource.write("ZERO:AUTO ONCE") # Only take the zero reading at the start. Speeds up measurement 62 self.resource.write(f"CONF:VOLT:DC {self.voltage_range},MAX") # 20V range, with the fastest integration time 63 self.resource.write("TRIG:SOUR IMM") # Software trigger 64 self.resource.write("TRIG:COUN 1") # Only 1 group 65 self.resource.write("TRIG:DEL 0") # No delay in-between measurements 66 self.resource.write(f"SAMP:COUN {sample_count}") # Amount of samples 67 self.resource.write("*ESE 1") # Enable status bit (helps determine when operation completed) 68 69 def send_trigger(self): 70 """Send a software trigger.""" 71 72 self.resource.write("INIT") # Run scans 73 self.resource.write("*OPC") # Set status bit to 1 when operation completes 74 75 def read_internal_memory(self) -> list[float]: 76 """Return measured data from internal memory.""" 77 78 # Wait until operation completes 79 while int(self.resource.query("*ESR?")) & 1 != 1: 80 time.sleep(0.1) 81 82 result = self.resource.query("FETC?") 83 return list(map(float, result.split(","))) 84 85 @property 86 def volts(self) -> float: 87 """Measures DC voltage.""" 88 return float(self.resource.query("MEAS:VOLT:DC?")) 89 90 @property 91 def amps_ac(self) -> float: 92 """Measures AC current.""" 93 return float(self.resource.query("MEAS:CURR:AC?")) 94 95 def reset(self): 96 """Resets the instrument.""" 97 self.resource.write("*CLS") # Reset any errors 98 self.resource.write("*RST") # Put the system in a known state 99 sleep(2) # This instrument needs time to reset for some reason 100 self.resource.write("CMDSET AGILENT") 101 self.configure_voltage_normal()
class
Dmm:
39class Dmm: 40 """Rigol DM3068 DMM command wrapper.""" 41 42 def __init__(self, resource: SafeResource): 43 """ 44 Initialize the DM3068 wrapper with a specific PyVISA resource. 45 This class does NOT open the resource, you have to open it for yourself! 46 """ 47 self.resource = resource 48 self.voltage_range = 20 # The maximum voltage that can be measured 49 self.impedance_config = DMMImpedance(1, 1) 50 self.reset() 51 52 def configure_voltage_normal(self): 53 """The voltage settings for normal measurements.""" 54 self.resource.write("ZERO:AUTO ON") # Only take the zero reading at the start. Speeds up measurement 55 self.resource.write(f"CONF:VOLT:DC {self.voltage_range}") # Range(V) = 0.2, 2, 20, 200, 1000, AUTO 56 self.resource.write("VOLT:DC:NPLC 10") # NPLC = 0.006, 0.02, 0.2, 1, 10, 100. 1PLC is equal to 0.02s 57 58 def configure_voltage_trigger( 59 self, timestamps: bool = False, sample_count: int = 2000 60 ): # pylint: disable=unused-argument 61 """Set up trigger parameters.""" 62 self.resource.write("ZERO:AUTO ONCE") # Only take the zero reading at the start. Speeds up measurement 63 self.resource.write(f"CONF:VOLT:DC {self.voltage_range},MAX") # 20V range, with the fastest integration time 64 self.resource.write("TRIG:SOUR IMM") # Software trigger 65 self.resource.write("TRIG:COUN 1") # Only 1 group 66 self.resource.write("TRIG:DEL 0") # No delay in-between measurements 67 self.resource.write(f"SAMP:COUN {sample_count}") # Amount of samples 68 self.resource.write("*ESE 1") # Enable status bit (helps determine when operation completed) 69 70 def send_trigger(self): 71 """Send a software trigger.""" 72 73 self.resource.write("INIT") # Run scans 74 self.resource.write("*OPC") # Set status bit to 1 when operation completes 75 76 def read_internal_memory(self) -> list[float]: 77 """Return measured data from internal memory.""" 78 79 # Wait until operation completes 80 while int(self.resource.query("*ESR?")) & 1 != 1: 81 time.sleep(0.1) 82 83 result = self.resource.query("FETC?") 84 return list(map(float, result.split(","))) 85 86 @property 87 def volts(self) -> float: 88 """Measures DC voltage.""" 89 return float(self.resource.query("MEAS:VOLT:DC?")) 90 91 @property 92 def amps_ac(self) -> float: 93 """Measures AC current.""" 94 return float(self.resource.query("MEAS:CURR:AC?")) 95 96 def reset(self): 97 """Resets the instrument.""" 98 self.resource.write("*CLS") # Reset any errors 99 self.resource.write("*RST") # Put the system in a known state 100 sleep(2) # This instrument needs time to reset for some reason 101 self.resource.write("CMDSET AGILENT") 102 self.configure_voltage_normal()
Rigol DM3068 DMM command wrapper.
Dmm(resource: hitl_tester.modules.bms_types.SafeResource)
42 def __init__(self, resource: SafeResource): 43 """ 44 Initialize the DM3068 wrapper with a specific PyVISA resource. 45 This class does NOT open the resource, you have to open it for yourself! 46 """ 47 self.resource = resource 48 self.voltage_range = 20 # The maximum voltage that can be measured 49 self.impedance_config = DMMImpedance(1, 1) 50 self.reset()
Initialize the DM3068 wrapper with a specific PyVISA resource. This class does NOT open the resource, you have to open it for yourself!
def
configure_voltage_normal(self):
52 def configure_voltage_normal(self): 53 """The voltage settings for normal measurements.""" 54 self.resource.write("ZERO:AUTO ON") # Only take the zero reading at the start. Speeds up measurement 55 self.resource.write(f"CONF:VOLT:DC {self.voltage_range}") # Range(V) = 0.2, 2, 20, 200, 1000, AUTO 56 self.resource.write("VOLT:DC:NPLC 10") # NPLC = 0.006, 0.02, 0.2, 1, 10, 100. 1PLC is equal to 0.02s
The voltage settings for normal measurements.
def
configure_voltage_trigger(self, timestamps: bool = False, sample_count: int = 2000):
58 def configure_voltage_trigger( 59 self, timestamps: bool = False, sample_count: int = 2000 60 ): # pylint: disable=unused-argument 61 """Set up trigger parameters.""" 62 self.resource.write("ZERO:AUTO ONCE") # Only take the zero reading at the start. Speeds up measurement 63 self.resource.write(f"CONF:VOLT:DC {self.voltage_range},MAX") # 20V range, with the fastest integration time 64 self.resource.write("TRIG:SOUR IMM") # Software trigger 65 self.resource.write("TRIG:COUN 1") # Only 1 group 66 self.resource.write("TRIG:DEL 0") # No delay in-between measurements 67 self.resource.write(f"SAMP:COUN {sample_count}") # Amount of samples 68 self.resource.write("*ESE 1") # Enable status bit (helps determine when operation completed)
Set up trigger parameters.
def
send_trigger(self):
70 def send_trigger(self): 71 """Send a software trigger.""" 72 73 self.resource.write("INIT") # Run scans 74 self.resource.write("*OPC") # Set status bit to 1 when operation completes
Send a software trigger.
def
read_internal_memory(self) -> list[float]:
76 def read_internal_memory(self) -> list[float]: 77 """Return measured data from internal memory.""" 78 79 # Wait until operation completes 80 while int(self.resource.query("*ESR?")) & 1 != 1: 81 time.sleep(0.1) 82 83 result = self.resource.query("FETC?") 84 return list(map(float, result.split(",")))
Return measured data from internal memory.
volts: float
86 @property 87 def volts(self) -> float: 88 """Measures DC voltage.""" 89 return float(self.resource.query("MEAS:VOLT:DC?"))
Measures DC voltage.
amps_ac: float
91 @property 92 def amps_ac(self) -> float: 93 """Measures AC current.""" 94 return float(self.resource.query("MEAS:CURR:AC?"))
Measures AC current.
def
reset(self):
96 def reset(self): 97 """Resets the instrument.""" 98 self.resource.write("*CLS") # Reset any errors 99 self.resource.write("*RST") # Put the system in a known state 100 sleep(2) # This instrument needs time to reset for some reason 101 self.resource.write("CMDSET AGILENT") 102 self.configure_voltage_normal()
Resets the instrument.