working iv curve
This commit is contained in:
+1
-6
@@ -36,9 +36,4 @@ Thumbs.db # Windows
|
||||
# ======================
|
||||
# Measurement data
|
||||
# ======================
|
||||
# Uncomment if you don't want raw data files in the repo
|
||||
# *.csv
|
||||
# *.dat
|
||||
# *.hdf5
|
||||
# *.h5
|
||||
|
||||
data/
|
||||
Vendored
BIN
Binary file not shown.
@@ -9,7 +9,7 @@ Created on Wed Oct 05 14:27:45 2022
|
||||
# Function to output voltage in Volts
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
def Voltage(Keithley):
|
||||
Keithley.read_termination = '\n'
|
||||
Keithley.write("X\n")
|
||||
Voltage_string = Keithley.read()
|
||||
Voltage = float(Voltage_string[4:])
|
||||
return Voltage
|
||||
|
||||
@@ -15,22 +15,29 @@ import os.path
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import pyvisa
|
||||
from pathlib import Path
|
||||
rm = pyvisa.ResourceManager()
|
||||
|
||||
import SIM900_commands as SIM900_comm
|
||||
import SIM928_commands as SIM928_comm
|
||||
import Keithley196_commands as Keithley_comm
|
||||
|
||||
Keithley_address = 'GPIB0::6::INSTR'
|
||||
SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3002::SOCKET'#'ASRL1::INSTR'
|
||||
Keithley_address = 'TCPIP0::Prologix-00-21-69-01-4e-fb.psi.ch::1234::SOCKET'
|
||||
# Keithley_address = 'GPIB0::6::INSTR'
|
||||
SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3001::SOCKET'#'ASRL1::INSTR'
|
||||
|
||||
Keithley = rm.open_resource(Keithley_address)
|
||||
SIM900 = rm.open_resource(SIM900_address)
|
||||
SIM928_port = 1
|
||||
|
||||
# Initialise Keithley
|
||||
Keithley.clear()
|
||||
Keithley.timeout = 5000
|
||||
Keithley.read_termination = '\n'
|
||||
Keithley.write("T5X\n") # Ensures the Keithley reads when it is triggered by "X" write
|
||||
Keithley_comm.Set_Mode(Keithley, "DC V")
|
||||
Keithley_comm.Set_Range(Keithley, "Auto")
|
||||
Keithley.read() # Throwaway
|
||||
|
||||
# Initialise SIM900
|
||||
SIM900_comm.flush_main(SIM900)
|
||||
@@ -97,6 +104,7 @@ def measure_V(time_average=10, time_interval=0.2):
|
||||
# Currently doesn't read the voltage that was set, due to issues with querying through mainframe
|
||||
# Errors caluclated incorrectly
|
||||
def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_name='no_name', contact_1 = '', contact_2 = '', light = 'Dark', temp=777, amplifier='SR570', gain=10**3, number_of_loops=0):
|
||||
Keithley.clear()
|
||||
print('Measurement started: %s'\
|
||||
%(datetime.datetime.now().strftime("%Hh%Mm%Ss")))
|
||||
V_scan_list = np.linspace(V_start, V_end, int(abs(V_start-V_end)/step_size)+1)
|
||||
@@ -106,7 +114,7 @@ def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_nam
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
|
||||
# open a file to write data to
|
||||
date_today = datetime.date.today() #date for making a directory
|
||||
file_path = "C:/Jamie/IV-Data/" + str(date_today) + "/"
|
||||
file_path = Path(__file__).parent / "data" / str(date_today)
|
||||
if not os.path.exists(file_path):#make the directory if it is not there
|
||||
os.mkdir(file_path)
|
||||
time_start = datetime.datetime.now().strftime("%Hh%Mm%Ss")
|
||||
@@ -129,10 +137,11 @@ def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_nam
|
||||
# A loop over all currents
|
||||
|
||||
i=0
|
||||
set_voltage(V_scan_list[0])
|
||||
time.sleep(5) #wait 3 sec to avoid large noise on first measurement
|
||||
# set_voltage(V_scan_list[0])
|
||||
# time.sleep(5) #wait 3 sec to avoid large noise on first measurement
|
||||
|
||||
for V_scan_item in V_scan_list:
|
||||
|
||||
time_start_iteration= datetime.datetime.now()
|
||||
i = i+1
|
||||
set_voltage(V_scan_item)
|
||||
@@ -191,7 +200,7 @@ def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_nam
|
||||
return
|
||||
|
||||
# V_start, step size, V_end, time average, sample name, contact 1, contact 2, light, temperature, amplifier, amplifier gain
|
||||
#V_scan(-1.0, 0.05, 1.0, 1.0, "test", "contact1", "contact2", "MIR", 300, "SR570", 10**(7)) #amplifier sensitivity = 1/gain
|
||||
V_scan(-1.0, 0.05, 1.0, .1, "test", "test1", "test1", "MIR", 300, "SR570", 10**(7)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(-1.0, 0.1, 1.0, 1.0, "SHADWELL", "posContactC", "negContactF", "MIR", 18, "SR570", 10**(8)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.1, 1.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.2, -2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Program to do I-V measurements
|
||||
# Using SIM928 voltage source within SIM900 mainframe
|
||||
# Using Keithley196 for voltage measurement
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import os.path
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import pyvisa
|
||||
from pathlib import Path
|
||||
rm = pyvisa.ResourceManager()
|
||||
|
||||
import SIM900_commands as SIM900_comm
|
||||
import SIM928_commands as SIM928_comm
|
||||
import Keithley196_commands as Keithley_comm
|
||||
|
||||
Keithley_address = 'TCPIP0::Prologix-00-21-69-01-4e-fb.psi.ch::1234::SOCKET'
|
||||
# Keithley_address = 'GPIB0::6::INSTR'
|
||||
SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3001::SOCKET'#'ASRL1::INSTR'
|
||||
|
||||
Keithley = rm.open_resource(Keithley_address)
|
||||
SIM900 = rm.open_resource(SIM900_address)
|
||||
SIM928_port = 1
|
||||
|
||||
# Initialise Keithley
|
||||
Keithley.clear()
|
||||
Keithley.timeout = 5000
|
||||
Keithley.read_termination = '\n'
|
||||
Keithley.write("T5X\n") # Ensures the Keithley reads when it is triggered by "X" write
|
||||
Keithley_comm.Set_Mode(Keithley, "DC V")
|
||||
Keithley_comm.Set_Range(Keithley, "Auto")
|
||||
Keithley.read() # Throwaway
|
||||
|
||||
# Initialise SIM900
|
||||
SIM900_comm.flush_main(SIM900)
|
||||
SIM900_comm.reset(SIM900)
|
||||
SIM900_comm.flush_port(SIM900, SIM928_port)
|
||||
@@ -6,9 +6,11 @@ readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
"datetime>=5.5",
|
||||
"ipykernel>=6.31.0",
|
||||
"jupyter>=1.1.1",
|
||||
"matplotlib>=3.9.4",
|
||||
"numpy>=2.0.2",
|
||||
"pyvisa>=1.14.1",
|
||||
"pyvisa-py>=0.7.2",
|
||||
"scipy>=1.13.1",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "7e9d23ea",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# -*- coding: utf-8 -*-\n",
|
||||
"\"\"\"\n",
|
||||
"Created on Mon Oct 10 16:05:44 2022\n",
|
||||
"\n",
|
||||
"@author: gac-x01dc\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"# Program to do I-V measurements\n",
|
||||
"# Using SIM928 voltage source within SIM900 mainframe\n",
|
||||
"# Using Keithley196 for voltage measurement\n",
|
||||
"\n",
|
||||
"import time\n",
|
||||
"import datetime\n",
|
||||
"import os.path\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import pyvisa\n",
|
||||
"from pathlib import Path\n",
|
||||
"rm = pyvisa.ResourceManager()\n",
|
||||
"\n",
|
||||
"import SIM900_commands as SIM900_comm\n",
|
||||
"import SIM928_commands as SIM928_comm\n",
|
||||
"import Keithley196_commands as Keithley_comm\n",
|
||||
"\n",
|
||||
"Keithley_address = 'TCPIP0::Prologix-00-21-69-01-4e-fb.psi.ch::1234::SOCKET'\n",
|
||||
"# Keithley_address = 'GPIB0::6::INSTR'\n",
|
||||
"SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3001::SOCKET'#'ASRL1::INSTR'\n",
|
||||
"\n",
|
||||
"Keithley = rm.open_resource(Keithley_address)\n",
|
||||
"SIM900 = rm.open_resource(SIM900_address)\n",
|
||||
"SIM928_port = 1\n",
|
||||
"\n",
|
||||
"# Initialise Keithley\n",
|
||||
"Keithley.clear()\n",
|
||||
"Keithley.timeout = 5000\n",
|
||||
"Keithley.read_termination = '\\n'\n",
|
||||
"Keithley.write(\"T5X\\n\") # Ensures the Keithley reads when it is triggered by \"X\" write\n",
|
||||
"Keithley_comm.Set_Mode(Keithley, \"DC V\")\n",
|
||||
"Keithley_comm.Set_Range(Keithley, \"Auto\")\n",
|
||||
"Keithley.read() # Throwaway\n",
|
||||
"\n",
|
||||
"# Initialise SIM900\n",
|
||||
"SIM900_comm.flush_main(SIM900)\n",
|
||||
"SIM900_comm.reset(SIM900)\n",
|
||||
"SIM900_comm.flush_port(SIM900, SIM928_port)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "91371dcc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"V_value = -0.2\n",
|
||||
"SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.set_voltage(V_value)) # get voltage \n",
|
||||
"\n",
|
||||
"SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state(\"on\"))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5236610b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "9298c70d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"-0.2001732"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# time.sleep(0.1)\n",
|
||||
"Keithley_comm.Voltage(Keithley)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "19bb6089",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "automated-iv-curves",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.13"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Generated
+40
@@ -171,6 +171,8 @@ source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "datetime", version = "5.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "datetime", version = "6.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
{ name = "ipykernel", version = "6.31.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "ipykernel", version = "7.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
{ name = "jupyter" },
|
||||
{ name = "matplotlib", version = "3.9.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
@@ -179,6 +181,8 @@ dependencies = [
|
||||
{ name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "pyvisa", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "pyvisa", version = "1.16.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
{ name = "pyvisa-py", version = "0.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "pyvisa-py", version = "0.8.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
{ name = "scipy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
@@ -187,10 +191,12 @@ dependencies = [
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "datetime", specifier = ">=5.5" },
|
||||
{ name = "ipykernel", specifier = ">=6.31.0" },
|
||||
{ name = "jupyter", specifier = ">=1.1.1" },
|
||||
{ name = "matplotlib", specifier = ">=3.9.4" },
|
||||
{ name = "numpy", specifier = ">=2.0.2" },
|
||||
{ name = "pyvisa", specifier = ">=1.14.1" },
|
||||
{ name = "pyvisa-py", specifier = ">=0.7.2" },
|
||||
{ name = "scipy", specifier = ">=1.13.1" },
|
||||
]
|
||||
|
||||
@@ -3023,6 +3029,40 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/a9/776da4f397003cca093659524c3526590522f81b642936838428c11274e6/pyvisa-1.16.2-py3-none-any.whl", hash = "sha256:54f034adafd3e8d1858d57cdafec64e920444f4b84b31c9fd17487fbad0a197a", size = 181413, upload-time = "2026-02-27T12:14:07.301Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyvisa-py"
|
||||
version = "0.7.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.10'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "pyvisa", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.10'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/14/fffb2de1baaa3dd6e30940a9882d742365baffa3ba4dade0260ddaee6390/PyVISA-py-0.7.2.tar.gz", hash = "sha256:4c5f5b867858457dbebfff92a42fba2d8b046d28defbbec2a09e3c1f0850e851", size = 95701, upload-time = "2024-03-07T12:05:31.696Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/7b/9c9cbb09596d00a3a5b009559e9b859ac459d01611fea6b3b655f74dc323/PyVISA_py-0.7.2-py3-none-any.whl", hash = "sha256:c53b941a5ee6547aadc5321f930c924dd5c4434891bc512fcafcdd5a4a8d110d", size = 75570, upload-time = "2024-03-07T12:05:29.72Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyvisa-py"
|
||||
version = "0.8.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.14'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14'",
|
||||
"python_full_version == '3.10.*'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "pyvisa", version = "1.16.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
{ name = "typing-extensions", marker = "python_full_version >= '3.10'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/55/8d/0f1af2b39feca8868d0692a2c5d0c47f4ad559a051fb678c441fe1e99536/pyvisa_py-0.8.1.tar.gz", hash = "sha256:db53d3219d971d16b8f7c764a93e08475875063635b9ad8ea3c988439833ccdd", size = 102061, upload-time = "2025-09-04T20:48:21.639Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/0b/06ccf917ce30d78d75e452d0afc89236b1d384b776c5c33d75c8cc55fbe7/pyvisa_py-0.8.1-py3-none-any.whl", hash = "sha256:31208a2933c1793b4e829ba5f07d265b83f280668df440ee7ee6ac505dea4ee9", size = 82206, upload-time = "2025-09-04T20:48:20.13Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pywin32"
|
||||
version = "311"
|
||||
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed Oct 05 14:27:45 2022
|
||||
|
||||
@author: Jamie
|
||||
"""
|
||||
# Function for controlling Keithly-196 for electrical measurements
|
||||
|
||||
# Function to output voltage in Volts
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
def Voltage(Keithley):
|
||||
Keithley.write("X\n")
|
||||
Voltage_string = Keithley.read()
|
||||
Voltage = float(Voltage_string[4:])
|
||||
return Voltage
|
||||
|
||||
# Function to set measurement mode
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
# mode is the measurement mode
|
||||
def Set_Mode(Keithley, mode):
|
||||
if mode == "DC V":
|
||||
mode_number = 0
|
||||
elif mode == "AC V":
|
||||
mode_number = 1
|
||||
elif mode == "Ohm":
|
||||
mode_number = 2
|
||||
elif mode == "DC I":
|
||||
mode_number = 3
|
||||
elif mode == "DC I":
|
||||
mode_number = 4
|
||||
elif mode == "AC I":
|
||||
mode_number = 5
|
||||
elif mode == "ACV dB":
|
||||
mode_number = 6
|
||||
elif mode == "Offset comp Ohm":
|
||||
mode_number = 7
|
||||
Keithley.write("F"+str(mode_number))
|
||||
|
||||
# Function to set voltage range
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
# range_name is the number of the range setting (numbers in V)
|
||||
def Set_Range(Keithley, range_name):
|
||||
if range_name == "Auto":
|
||||
range_number = 0
|
||||
elif range_name == "0.3":
|
||||
range_number = 1
|
||||
elif range_name == "3":
|
||||
range_number = 2
|
||||
elif range_name == "30":
|
||||
range_number = 3
|
||||
elif range_name == "300":
|
||||
range_number = 4
|
||||
Keithley.write("R"+str(range_number)+"X")
|
||||
Executable
+230
@@ -0,0 +1,230 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 10 16:05:44 2022
|
||||
|
||||
@author: gac-x01dc
|
||||
"""
|
||||
|
||||
# Program to do I-V measurements
|
||||
# Using SIM928 voltage source within SIM900 mainframe
|
||||
# Using Keithley196 for voltage measurement
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import os.path
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import pyvisa
|
||||
from pathlib import Path
|
||||
rm = pyvisa.ResourceManager()
|
||||
|
||||
import SIM900_commands as SIM900_comm
|
||||
import SIM928_commands as SIM928_comm
|
||||
import Keithley196_commands as Keithley_comm
|
||||
|
||||
Keithley_address = 'TCPIP0::Prologix-00-21-69-01-4e-fb.psi.ch::1234::SOCKET'
|
||||
# Keithley_address = 'GPIB0::6::INSTR'
|
||||
SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3001::SOCKET'#'ASRL1::INSTR'
|
||||
|
||||
Keithley = rm.open_resource(Keithley_address)
|
||||
SIM900 = rm.open_resource(SIM900_address)
|
||||
SIM928_port = 1
|
||||
|
||||
# Initialise Keithley
|
||||
Keithley.clear()
|
||||
Keithley.timeout = 5000
|
||||
Keithley.read_termination = '\n'
|
||||
Keithley.write("T5X\n") # Ensures the Keithley reads when it is triggered by "X" write
|
||||
Keithley_comm.Set_Mode(Keithley, "DC V")
|
||||
Keithley_comm.Set_Range(Keithley, "Auto")
|
||||
Keithley.read() # Throwaway
|
||||
|
||||
# Initialise SIM900
|
||||
SIM900_comm.flush_main(SIM900)
|
||||
SIM900_comm.reset(SIM900)
|
||||
SIM900_comm.flush_port(SIM900, SIM928_port)
|
||||
|
||||
# Function to read the voltage set by a voltage source
|
||||
def read_source_V():
|
||||
count = 0
|
||||
voltage = SIM900_comm.send_query(SIM900, SIM928_port, SIM928_comm.read_voltage(), 128) # get voltage
|
||||
print("returned data: "+voltage)
|
||||
while (count<10) and (type(voltage)!= float):
|
||||
try:
|
||||
voltage = float(voltage)
|
||||
except:
|
||||
print('no float')
|
||||
voltage = SIM900_comm.send_query(SIM900, SIM928_port, SIM928_comm.read_voltage(), 128) # get voltage
|
||||
print("returned data: "+voltage)
|
||||
count = count + 1
|
||||
return voltage
|
||||
|
||||
#print(read_source_V())
|
||||
|
||||
# Function to set voltage of SIM928
|
||||
def set_voltage(V_value=1e-3):
|
||||
if V_value > 20:
|
||||
print ('Voltage setting too high (>10V), it is set to 10V')
|
||||
V_value = 20
|
||||
elif V_value < -20:
|
||||
print ('Voltage setting too high (<-10V), it is set to -10V')
|
||||
V_value = -20
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.set_voltage(V_value)) # get voltage
|
||||
time.sleep(1)
|
||||
# count = 0
|
||||
# while (count<10) and (read_source_V()!= V_value):
|
||||
# print('Setting voltage again')
|
||||
# time.sleep(1) #wait 1 second
|
||||
# SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.set_voltage(V_value)) # get voltage
|
||||
# count = count + 1
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("on"))
|
||||
print('Voltage set to ' + str(V_value))
|
||||
# return read_source_V()
|
||||
|
||||
# Function to measure the current from the Keithley voltmeter
|
||||
# time_average is the averaging time, time_interval is the time between points
|
||||
# Could also use "Filter (P)" command to set the Keithley's internal averaging time
|
||||
def measure_V(time_average=10, time_interval=0.2):
|
||||
N_points = time_average/time_interval + 1
|
||||
V_list = []
|
||||
i = 1
|
||||
Keithley_comm.Set_Range(Keithley, "Auto") #set auto range
|
||||
time.sleep(time_interval)
|
||||
while i < N_points:
|
||||
V_list.append(Keithley_comm.Voltage(Keithley)) #read the voltage
|
||||
time.sleep(time_interval)
|
||||
i = i+1
|
||||
V_avg_ = np.mean(V_list, dtype=np.float32)
|
||||
V_std_ = np.std(V_list, dtype=np.float32)
|
||||
V_err_ = V_std_/(N_points)**(1/2)
|
||||
return [V_list, V_avg_, V_err_]
|
||||
|
||||
|
||||
# Function to do I-V measurements
|
||||
# Currently doesn't read the voltage that was set, due to issues with querying through mainframe
|
||||
# Errors caluclated incorrectly
|
||||
def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_name='no_name', contact_1 = '', contact_2 = '', light = 'Dark', temp=777, amplifier='SR570', gain=10**3, number_of_loops=0):
|
||||
Keithley.clear()
|
||||
print('Measurement started: %s'\
|
||||
%(datetime.datetime.now().strftime("%Hh%Mm%Ss")))
|
||||
V_scan_list = np.linspace(V_start, V_end, int(abs(V_start-V_end)/step_size)+1)
|
||||
for n_l in range(number_of_loops):
|
||||
V_scan_list = np.append(V_scan_list,np.linspace(V_end, V_start, (abs(V_start-V_end)/step_size)+1))
|
||||
print(V_scan_list)
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
|
||||
# open a file to write data to
|
||||
date_today = datetime.date.today() #date for making a directory
|
||||
file_path = Path(__file__).parent / "data" / str(date_today)
|
||||
if not os.path.exists(file_path):#make the directory if it is not there
|
||||
os.mkdir(file_path)
|
||||
time_start = datetime.datetime.now().strftime("%Hh%Mm%Ss")
|
||||
filename_root = "%s_%s_%s_%s_%s_scan_at_%sK_%s" % \
|
||||
(time_start, sample_name, contact_1, contact_2, light, temp, amplifier)
|
||||
filename = filename_root + "_averaging%ss.txt" % (time_average)
|
||||
plotname = filename_root + "_averaging%ss.png" % (time_average)
|
||||
filename2 = filename_root + "_raw.txt"
|
||||
full_name = os.path.join(file_path, filename)
|
||||
full_plotname = os.path.join(file_path, plotname)
|
||||
full_name2 = os.path.join(file_path, filename2)
|
||||
#data_file=open(str(full_name),'w')
|
||||
with open(str(full_name),'w') as data_file, open(str(full_name2),'w') as raw_V_file:
|
||||
data_file.write("Time\tVoltage_source[V]\tVoltage_meas[V]\tVoltage_meas_err[V]\tGain[V/A]\n")
|
||||
raw_V_file.write("Voltage_source[V]\tVoltage_meas[V]\n")
|
||||
# just for ploting here
|
||||
V_plot_list = []
|
||||
V_err_plot_list = []
|
||||
V_scan_plot_list = []
|
||||
# A loop over all currents
|
||||
|
||||
i=0
|
||||
# set_voltage(V_scan_list[0])
|
||||
# time.sleep(5) #wait 3 sec to avoid large noise on first measurement
|
||||
|
||||
for V_scan_item in V_scan_list:
|
||||
|
||||
time_start_iteration= datetime.datetime.now()
|
||||
i = i+1
|
||||
set_voltage(V_scan_item)
|
||||
time.sleep(2) #wait 5 sec for signal to settle
|
||||
# measure+read+write the data
|
||||
V_source = V_scan_item
|
||||
# V_source = read_source_V()
|
||||
[V_list, V_avg, V_err] = measure_V(time_average=time_average, time_interval=0.2)
|
||||
time_now = datetime.datetime.now()
|
||||
data_string = "%s\t %s\t %.5e\t %.5e\t %s\n"\
|
||||
%(time_now, V_source, V_avg, V_err, gain)
|
||||
data_file.write(str(data_string))
|
||||
raw_V_file.write("%s\t %s\n" %(V_source, V_list))
|
||||
V_plot_list.append(V_avg)
|
||||
V_err_plot_list.append(V_err)
|
||||
V_scan_plot_list.append(V_source)
|
||||
|
||||
#make plot
|
||||
plt.close()
|
||||
plt.plot(V_scan_plot_list, V_plot_list,'+')
|
||||
plt.title(str(sample_name))
|
||||
plt.xlabel('Source Voltage / V')
|
||||
plt.ylabel('Measured voltage / V')
|
||||
plt.draw()
|
||||
plt.pause(0.1)
|
||||
plt.show(block=False)
|
||||
iteration_time = datetime.datetime.now()-time_start_iteration
|
||||
remaining_time = iteration_time.total_seconds()*(len(V_scan_list)-i)
|
||||
print(time.strftime('remaining time: %H:%M:%S',\
|
||||
time.gmtime(remaining_time)))
|
||||
|
||||
I_list = [V_plot_list[i]/gain for i in range(len(V_plot_list))]
|
||||
I_err_list = [V_err_plot_list[i]/gain for i in range(len(V_plot_list))]
|
||||
plt.close()
|
||||
plt.figure()
|
||||
plt.errorbar(V_scan_plot_list, I_list, yerr=I_err_list, fmt='+')
|
||||
plt.title(str(sample_name))
|
||||
plt.xlabel('Source Voltage / V')
|
||||
plt.ylabel('I / A')
|
||||
plt.tight_layout()
|
||||
plt.grid()
|
||||
|
||||
plt.savefig(full_plotname)
|
||||
plt.draw()
|
||||
plt.pause(0.001)
|
||||
plt.show(block=False)
|
||||
plt.close()
|
||||
|
||||
data_file.close()
|
||||
raw_V_file.close()
|
||||
set_voltage(0)
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
|
||||
print('Source turned off')
|
||||
print('Measurement finished: %s'\
|
||||
%(datetime.datetime.now().strftime("%Hh%Mm%Ss")))
|
||||
return
|
||||
|
||||
# V_start, step size, V_end, time average, sample name, contact 1, contact 2, light, temperature, amplifier, amplifier gain
|
||||
V_scan(-1.0, 0.05, 1.0, .1, "test", "test1", "test1", "MIR", 300, "SR570", 10**(7)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(-1.0, 0.1, 1.0, 1.0, "SHADWELL", "posContactC", "negContactF", "MIR", 18, "SR570", 10**(8)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.1, 1.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.2, -2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.2, 2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.3, -3.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.3, 3.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.5, -5.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.5, 5.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
|
||||
"""
|
||||
# Set up the plot
|
||||
plt.ion() # Enable interactive mode
|
||||
figure, ax = plt.subplots(figsize=(10, 6)) # Create a figure and an axes
|
||||
ax.set_title("Live Number Update")
|
||||
|
||||
# Loop to update the number and plot every second
|
||||
for _ in range(9999): # Limiting to 10 iterations for demonstration
|
||||
number = Keithley_comm.Voltage(Keithley)
|
||||
# Create a new plot for the current number
|
||||
figure, ax = plt.subplots(figsize=(10, 6))
|
||||
ax.text(0.5, 0.5, str(number), fontsize=100, ha='center') # Display the number in the center
|
||||
ax.set_title(f"Number: {number}")
|
||||
ax.axis('off') # Turn off the axis
|
||||
|
||||
plt.show() # Show the plot
|
||||
time.sleep(2) # Pause for a second
|
||||
"""
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 10 12:41:44 2022
|
||||
|
||||
@author: gac-x01dc
|
||||
"""
|
||||
|
||||
# Sends a command to the instrument
|
||||
# SIM900 is the VISA resource for the SIM900
|
||||
# port_number is the port number of the instrument to be controlled
|
||||
# instrument_command is the command to be sent
|
||||
def send_command(SIM900, port_number, instrument_command):
|
||||
SIM900_command = "SNDT "+str(port_number)+", \""+instrument_command+"\""
|
||||
SIM900.write(SIM900_command)
|
||||
|
||||
# Send a query to the instrument and get a response - CURRENTLY BROKEN
|
||||
# SIM900 is the VISA resource for the SIM900
|
||||
# port_number is the port number of the instrument to be controlled
|
||||
# instrument_query is the query to be sent
|
||||
# response_bytes is the maximum number of bytes in the response
|
||||
def send_query(SIM900, port_number, instrument_query, response_bytes=7):
|
||||
send_command(SIM900, port_number, instrument_query)
|
||||
SIM900_command = "GETN? "+str(port_number)+", " + str(response_bytes)
|
||||
full_response = SIM900.query(SIM900_command)
|
||||
print("full_response="+full_response)
|
||||
response = full_response[5:]
|
||||
print("response="+response)
|
||||
return(response)
|
||||
|
||||
# Flushes input & output buffers of specified port
|
||||
def flush_port(SIM900, port_number):
|
||||
SIM900_command = "FLSH "+str(port_number)
|
||||
SIM900.write(SIM900_command)
|
||||
|
||||
# Flushes output queue of mainframe
|
||||
def flush_main(SIM900):
|
||||
SIM900_command = "FLOQ"
|
||||
SIM900.write(SIM900_command)
|
||||
|
||||
# Resets all ports
|
||||
def reset(SIM900):
|
||||
SIM900_command = "SRST"
|
||||
SIM900.write(SIM900_command)
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 10 15:39:12 2022
|
||||
|
||||
@author: gac-x01dc
|
||||
"""
|
||||
|
||||
# Program containing functions with commands for SIM928 voltage source
|
||||
|
||||
# Turns source on/off
|
||||
def V_source_state(on_off = 'off'):
|
||||
command = 'EXON ' + on_off
|
||||
return(command)
|
||||
|
||||
# Set voltage of SIM928
|
||||
def set_voltage(V_value=1e-3):
|
||||
if abs(V_value) < 1e-3:
|
||||
print ('Voltage too low (<|3 mV|), it is set to 0 mV')
|
||||
V_value = 0
|
||||
elif abs(V_value) > 39:
|
||||
print ('Voltage setting too high (>39V), it is set to 39V')
|
||||
V_value = 40e-3
|
||||
V_value = round(V_value,3) # rounding to mV, otherwise the source does not set the voltage because it lacks the precision
|
||||
command = 'VOLT ' + str(V_value) # set voltage
|
||||
return(command)
|
||||
|
||||
# Read voltage set by voltage source
|
||||
def read_voltage():
|
||||
command = 'VOLT?'
|
||||
return(command)
|
||||
Reference in New Issue
Block a user