Skip to content

Commit

Permalink
Merge pull request #103 from Code-Craftsman-Christian/main
Browse files Browse the repository at this point in the history
enhance NGU compatibility
  • Loading branch information
afischer-sweepme authored Dec 23, 2024
2 parents a061435 + 18fed84 commit 15aef43
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/SMU-Rohde&Schwarz_NGx/license.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ find those in the corresponding folders or contact the maintainer.

MIT License

Copyright (c) 2022-2023 SweepMe! GmbH (sweep-me.net)
Copyright (c) 2022-2024 SweepMe! GmbH (sweep-me.net)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
99 changes: 74 additions & 25 deletions src/SMU-Rohde&Schwarz_NGx/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# MIT License
#
# Copyright (c) 2022-2023 SweepMe! GmbH (sweep-me.net)
# Copyright (c) 2022-2024 SweepMe! GmbH (sweep-me.net)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -25,9 +25,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# SweepMe! device class
# Type: SMU
# Device: Rohde&Schwarz NGx
# SweepMe! driver
# * Module: SMU
# * Instrument: Rohde&Schwarz NGx

import time

Expand Down Expand Up @@ -63,14 +63,9 @@ def __init__(self):
self.port_types = ["COM", "USBTMC", "GPIB", "TCPIP"]

self.port_properties = {"timeout": 1,
# "delay": 0.05,
# "Exception": False,
}

# self.commands = {
# "Voltage in V" : "VOLT",
# "Current in A" : "CURR",
# }
self.model = None

def set_GUIparameter(self):

Expand All @@ -81,7 +76,7 @@ def set_GUIparameter(self):
"Compliance": 5.0,
"Range": ["Auto", "10 µA", "1 mA", "10 mA", "100 mA", "3 A", "10 A"],
"RangeVoltage": ["Auto", "20 V", "6 V"],
"Speed": ["Fast", "Medium", "Slow"],
"Speed": ["Very fast", "Fast", "Medium", "Slow", "Very slow"],
# "4wire": False,
}

Expand All @@ -104,15 +99,28 @@ def connect(self):
self.port.port.write_termination = '\n'
self.port.port.read_termination = '\n'

# we do identification in connect as knowing the model is essential for further communication, e.g. because
# commands like set_channel do not work for NGU series
identifier = self.get_identification()
#print("Identifier:", identifier) # can be used to check the instrument

if identifier.find("NGU") > 0:
self.model = "NGU"

def initialize(self):
# identifier = self.get_identification()
# print("Identifier:", identifier) # can be used to check the instrument

self.reset_instrument()

def configure(self):

# Range
self.set_voltage_range(self.voltage_range)
self.set_current_range(self.current_range)

# Channel
self.set_channel(self.channel)

# Source
if self.source.startswith("Voltage"):
self.set_current_limit(self.protection)
self.set_voltage(0.0)
Expand All @@ -121,12 +129,35 @@ def configure(self):
self.set_voltage_limit(self.protection)
self.set_current(0.0)
self.set_voltage(self.protection)
if self.speed == "Fast":
self.set_nplc(0.1)
if self.speed == "Medium":
self.set_nplc(1)
if self.speed == "Slow":
self.set_nplc(10)

# Speed
# Possible NPLC settings for model NGU are 0, 5, 10, 50 and 100
# TODO: the entire Speed section needs a revision as the NPLC settings are only known for the NGU series
if self.speed == "Very fast":
if self.model == "NGU":
self.set_nplc(0)
else:
self.set_nplc(0) # TODO: check whether other models support 0
elif self.speed == "Fast":
if self.model == "NGU":
self.set_nplc(5)
else:
self.set_nplc(0.1) # TODO: check whether other models support 0.1
elif self.speed == "Medium":
if self.model == "NGU":
self.set_nplc(10)
else:
self.set_nplc(1) # TODO: check whether other models support 1
elif self.speed == "Slow":
if self.model == "NGU":
self.set_nplc(50)
else:
self.set_nplc(10) # TODO: check whether other models support 10
elif self.speed == "Very slow":
if self.model == "NGU":
self.set_nplc(100)
else:
self.set_nplc(10) # TODO: check whether other models support 10

def unconfigure(self):

Expand Down Expand Up @@ -182,6 +213,7 @@ def get_identification(self):
"""
self.port.write("*IDN?")
answer = self.port.read()

return answer

def get_options(self):
Expand All @@ -192,6 +224,7 @@ def get_options(self):
"""
self.port.write("*OPT?")
answer = self.port.read()

return answer

def reset_instrument(self):
Expand All @@ -201,6 +234,7 @@ def reset_instrument(self):
None
"""
self.port.write("*RST")


def set_voltage_limit(self, protection):
"""
Expand All @@ -212,6 +246,7 @@ def set_voltage_limit(self, protection):
None
"""
self.port.write("ALIM 1") # To make sure that the safety limits are on beforehand.

self.port.write("VOLT:ALIM %1.3f" % float(protection))

def get_voltage_limit(self):
Expand All @@ -222,6 +257,7 @@ def get_voltage_limit(self):
"""
self.port.write("VOLT:ALIM?")
answer = self.port.read()

return answer

def set_current_limit(self, protection):
Expand All @@ -234,8 +270,9 @@ def set_current_limit(self, protection):
None
"""
self.port.write("ALIM 1")

self.port.write("CURR:ALIM %1.4f" % float(protection))

def get_current_limit(self):
"""
This function gets the current limit of the instrument.
Expand All @@ -244,19 +281,26 @@ def get_current_limit(self):
"""
self.port.write("CURR:ALIM?")
answer = self.port.read()

return answer

def set_channel(self, channel):
"""
This function selects a channel as the active channel of the instrument. Then the channel does not need to be
specified anymore with other commands.
It seems that this commands does not work with the NGU series
Args:
channel: int
Returns:
None
"""
self.port.write("INST:OUT%i" % int(channel))

# set channel is often used in the driver to change the activated driver before further commands are sent.
# This is why the model is checked here, because the NGU model does not seem to understand the INST:OUT command.
if self.model != "NGU":
self.port.write("INST:OUT%i" % int(channel))

def set_voltage(self, voltage):
"""
Expand All @@ -268,7 +312,7 @@ def set_voltage(self, voltage):
None
"""
self.port.write("VOLT %1.3f" % float(voltage))

def get_voltage(self):
"""
This function measures the voltage difference of the terminals for a selected channel.
Expand All @@ -277,6 +321,7 @@ def get_voltage(self):
"""
self.port.write("MEAS:VOLT?")
answer = float(self.port.read())

return answer

def set_current(self, current):
Expand All @@ -289,7 +334,7 @@ def set_current(self, current):
None
"""
self.port.write("CURR %1.4f" % float(current))

def get_current(self):
"""
This function measures the current through the terminals for a selected channel.
Expand All @@ -298,6 +343,7 @@ def get_current(self):
"""
self.port.write("MEAS:CURR?")
answer = float(self.port.read())

return answer

def set_output_on(self):
Expand Down Expand Up @@ -350,6 +396,7 @@ def read_data(self):
"""
self.port.write("READ?")
voltage, current = self.port.read().split(",")

return float(voltage), float(current)

def set_voltage_range(self, voltage_range):
Expand All @@ -364,10 +411,13 @@ def set_voltage_range(self, voltage_range):
"""
if voltage_range == "20 V":
self.port.write("SENS:VOLT:RANG 20")

elif voltage_range == "6 V":
self.port.write("SENS:VOLT:RANG 6")

elif voltage_range == "Auto":
self.port.write("SENS:VOLT:RANG:AUTO 1")

else:
raise Exception("The input voltage range is not valid.")

Expand Down Expand Up @@ -397,7 +447,7 @@ def set_current_range(self, current_range):
self.port.write("SENS:CURR:RANG:AUTO 1")
else:
raise Exception("The input current range is not valid.")

def set_nplc(self, nplc):
"""
This function sets the number of power line cycles value. high NPLC means slow integration/speed and vice versa.
Expand All @@ -408,7 +458,6 @@ def set_nplc(self, nplc):
"""
self.port.write("NPLC %0.1f" % nplc)


if __name__ == "__main__":

ngx = Device()
Expand Down

0 comments on commit 15aef43

Please sign in to comment.