Multisim and Ultiboard

cancel
Showing results for 
Search instead for 
Did you mean: 

Change a resistor value with the API, Python

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. 

 

 

0 Kudos
Message 1 of 2
(58 Views)

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
0 Kudos
Message 2 of 2
(44 Views)