04-24-2025 05:50 PM
I'm using MultiSim Power Pro Edition, Application Version: 14.3.0 (14.30.49153)
My intent to run multiple simulations under python, I can successfully connect and run the simulator. I have not been successful in changing a resistor value. How can I programmatically change a resistor value between runs of DoACSweep()?
Below I am sharing what I have tried, and a simplified test program.
I have tried using RLCValue(), I can read the resistors value using this call, but I have not been able to set it.
circuit.RLCValue(old_resistor_name, new_value)
# FATAL ERROR: TypeError: RLCValue() takes from 1 to 2 positional arguments but 3 were given
I have also tried to use ReplaceComponent:
circuit.ReplaceComponent(old_resistor_name, # component name
'', # section name
1, # source database
'Basic', # source group
'RESISTOR', # source family
'1k', # source name
'', # model name
)
# causes a crash with: Process finished with exit code -1073740940 (0xC0000374)
Here is simple example I created to experiment changing a resistor value:
import win32com.client
import os
def replace_resistor(circuit, old_resistor_name, new_value):
"""Replace a resistor with a new resistor of a different value"""
current_value = circuit.RLCValue(old_resistor_name) # this works!
print(f"Current value of {old_resistor_name}: {current_value} ohms")
# Replace the resistor with a new one of the specified value
print(f"Replacing resistor...")
# circuit.ReplaceComponent(old_resistor_name, # component name
# '', # section name
# 1, # source database
# 'Basic', # source group
# 'RESISTOR', # source family
# '1k', # source name
# '', # model name
# )
# causes a crash with: Process finished with exit code -1073740940 (0xC0000374)
circuit.RLCValue(old_resistor_name, new_value)
# FATAL ERROR: TypeError: RLCValue() takes from 1 to 2 positional arguments but 3 were given
# Verify the new value
new_value = circuit.RLCValue(old_resistor_name)
print(f"New value of {old_resistor_name}: {new_value} ohms")
def main():
# Create Multisim instance
multisim = win32com.client.Dispatch("MultisimInterface.MultisimApp")
multisim.Connect()
try:
# Open circuit file
circuit_path = os.path.abspath("Ibanez_MT10_Mostortion_Schematic.ms14")
circuit = multisim.OpenFile(circuit_path)
print("Circuit file opened successfully")
# Replace the resistor
replace_resistor(circuit, "GAIN12", 1000.0)
except Exception as e:
print(f"Error: {str(e)}")
finally:
# Clean up
multisim.Disconnect()
print("Disconnected from Multisim")
if __name__ == "__main__":
main()
Here is the output:
Circuit file opened successfully
Current value of GAIN12: 90000.0 ohms
Replacing resistor...
Error: RLCValue() takes from 1 to 2 positional arguments but 3 were given
Disconnected from Multisim
Thank for any suggestions. I'm open to taking a different approach.
04-24-2025 08:02 PM
I solved my own problem using AI to figure out the low-level COM interface. If there is a better solution, I would love to know it and get rid of the "magic" solution. But for now, it works. This code is a method of a class, self.circuit is the object returned by:
self.circuit = self.multisim.OpenFile(circuit_path)
def set_resistor_value(self, resistor_name, value):
"""Set the value of a resistor in the circuit using direct COM invocation.
Args:
resistor_name (str): The name of the resistor to set
value (float): The new resistance value in ohms
"""
try:
# Get the _oleobj_ from the circuit object
oleobj = self.circuit._oleobj_
# DISPID for RLCValue is 28
DISPID_RLCVALUE = 28
# Flags for COM invoke
DISPATCH_PROPERTYPUT = 0x4
# print(f"Attempting to set {resistor_name} to {value} ohms...")
# Make the COM call to set the resistor value
res = oleobj.InvokeTypes(
DISPID_RLCVALUE, # dispid
0, # lcid (locale id)
DISPATCH_PROPERTYPUT, # wFlags - PROPERTYPUT for setting a property
(24, 0), # retType - VT_VOID
((8, 1), (5, 1)), # argTypes - tuple of tuples: ((type1, flags1), (type2, flags2))
resistor_name, # arg1 - resistor name
value # arg2 - new value
)
except Exception as e:
print(f"Error setting resistor value: {str(e)}")
print(f"Last error message: {self.circuit.LastErrorMessage}")
raise