Skip to content

Commit 30609e1

Browse files
bug fix
1 parent 1b4534e commit 30609e1

1 file changed

Lines changed: 48 additions & 152 deletions

File tree

Lines changed: 48 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,56 @@
1-
'''
2-
===============================================================================
3-
PROGRAM: Keithley 6517B I-V Sweep Measurement
4-
5-
PURPOSE: Perform a voltage sweep and measure current to generate an I-V
6-
curve using a Keithley 6517B.
7-
8-
DESCRIPTION: This script automates an I-V sweep measurement using a Keithley
9-
6517B electrometer. It prompts the user for sweep parameters
10-
(start/stop voltage, steps, delay), performs a zero-check
11-
correction, executes the voltage sweep while measuring current,
12-
saves the data to a CSV file, and displays a plot of the
13-
resulting I-V curve.
14-
15-
AUTHOR: Prathamesh Deshmukh
16-
GUIDED BY: Dr. Sudip Mukherjee
17-
INSTITUTE: UGC-DAE Consortium for Scientific Research, Mumbai Centre
18-
19-
VERSION: 5.1
20-
LAST EDITED: 04/10/2025
21-
===============================================================================
22-
'''
1+
#-------------------------------------------------------------------------------
2+
# Name: Keithley 6517B electrometer
3+
# Purpose: Current Measurement Backend
4+
# Author: Prathamesh K Deshmukh
5+
# Created: 03-03-2024
6+
# Updates: V1.3 (Fixed DataFrame saving bug)
7+
#-------------------------------------------------------------------------------
238

249
import time
25-
import csv
2610
import numpy as np
27-
import matplotlib.pyplot as plt
28-
from datetime import datetime
29-
30-
try:
31-
from pymeasure.instruments.keithley import Keithley6517B
32-
from pyvisa.errors import VisaIOError
33-
except ImportError:
34-
print("Error: Required packages not found.")
35-
print("Please install them by running: pip install numpy matplotlib pymeasure")
36-
exit()
37-
38-
# --- 1. USER CONFIGURATION ---
39-
# The VISA address is fixed as it was in V5.
40-
VISA_ADDRESS = "GPIB1::27::INSTR"
41-
42-
def get_sweep_parameters():
43-
"""Gets I-V sweep parameters from the user."""
44-
print("--- I-V Sweep Configuration ---")
45-
start_v = float(input("Enter Start Voltage (V): "))
46-
stop_v = float(input("Enter Stop Voltage (V): "))
47-
steps = int(input("Enter Number of Steps: "))
48-
delay = float(input("Enter Settling Delay between points (s): "))
49-
filename = input("Enter the filename to save data (e.g., SampleA_IV.csv): ")
50-
51-
if not filename.lower().endswith('.csv'):
52-
filename += '.csv'
53-
return start_v, stop_v, steps, delay, filename
54-
55-
def plot_results(data):
56-
"""Plots the I-V curve from the collected data."""
57-
if not data:
58-
print("\nNo data to plot.")
59-
return
60-
61-
voltages = [float(row[1]) for row in data]
62-
currents = [float(row[2]) for row in data]
63-
64-
plt.figure(figsize=(8, 6))
65-
plt.plot(voltages, currents, 'o-', label='I-V Data', color='#003f5c')
66-
plt.title('I-V Measurement Curve', fontsize=16)
67-
plt.xlabel('Applied Voltage (V)', fontsize=12)
68-
plt.ylabel('Measured Current (A)', fontsize=12)
69-
plt.grid(True, which="both", ls="--", alpha=0.6)
70-
plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
71-
plt.legend()
72-
plt.tight_layout()
73-
print("\nDisplaying I-V plot...")
74-
plt.show()
11+
import pandas as pd
12+
import pyvisa
13+
from pymeasure.instruments.keithley import Keithley6517B
7514

76-
# --- Main Execution ---
77-
keithley = None
78-
results = []
15+
I = []
16+
t = []
7917

8018
try:
81-
# Get sweep parameters from the user
82-
start_v, stop_v, steps, delay, filename = get_sweep_parameters()
83-
voltage_sweep = np.linspace(start_v, stop_v, steps)
19+
# Initialize Instrument
20+
keithley = Keithley6517B("GPIB0::27::INSTR")
21+
time.sleep(0.5)
22+
23+
# Setup Measurement
24+
keithley.measure_current()
25+
time.sleep(0.5)
26+
27+
print("Starting measurement... Press Ctrl+C to stop.")
28+
start_time = time.time()
29+
30+
while True:
31+
elapsed_time = time.time() - start_time
32+
current = keithley.current # Read current in Amps
33+
34+
# Store data in lists
35+
t.append(elapsed_time)
36+
I.append(current)
37+
38+
print("Time: " + str(elapsed_time) + "\t\t\t|\t\t\t Current: " + str(current) + " A")
39+
time.sleep(2)
40+
41+
except KeyboardInterrupt:
42+
# Graceful Exit on Ctrl+C
43+
print("\nMeasurement stopped by User.")
44+
45+
# --- FIX: Define data_df before using it ---
46+
data_df = pd.DataFrame({"Timestamp": t, "Current (A)": I})
47+
data_df.to_csv("demo_data.dat", index=False)
48+
print(f"Data saved to file: demo_data.dat")
49+
50+
# Shutdown Sequence
51+
time.sleep(0.5)
52+
keithley.shutdown() # Ramps current to 0 and disables output
53+
print("Keithley closed.")
8454

85-
# --- 2. CONNECT TO INSTRUMENT (V5 Logic) ---
86-
print(f"\nAttempting to connect to instrument at: {VISA_ADDRESS}")
87-
keithley = Keithley6517B(VISA_ADDRESS)
88-
print(f"Successfully connected to: {keithley.id}")
89-
90-
# --- 3. CONFIGURE MEASUREMENT (V5 Logic) ---
91-
print("\nConfiguring instrument for measurement...")
92-
keithley.reset()
93-
# Set the function to resistance to ensure the ammeter is configured for zero correction.
94-
keithley.measure_resistance()
95-
96-
# --- 4. PERFORM ZERO CHECK & CORRECTION (Exact V5 Logic) ---
97-
print("\nStarting zero correction procedure...")
98-
time.sleep(5)
99-
print("Step 1: Enabling Zero Check mode...")
100-
keithley.write(':SYSTem:ZCHeck ON')
101-
time.sleep(5)
102-
print("Step 2: Acquiring zero correction value...")
103-
#keithley.write(':SYSTem:ZCORrect:ACQuire')
104-
time.sleep(5)
105-
print("Step 3: Disabling Zero Check mode...")
106-
keithley.write(':SYSTem:ZCHeck OFF')
107-
time.sleep(5)
108-
print("Step 4: Enabling Zero Correction...")
109-
keithley.write(':SYSTem:ZCORrect ON')
110-
time.sleep(5)
111-
print("Zero Correction Complete.")
112-
113-
# --- 5. SETUP AND PERFORM I-V SWEEP ---
114-
print(f"\nStarting I-V sweep from {start_v}V to {stop_v}V...")
115-
keithley.current_nplc = 1 # Set integration rate for noise reduction
116-
117-
keithley.enable_source()
118-
119-
with open(filename, 'w', newline='') as f:
120-
writer = csv.writer(f)
121-
writer.writerow([f"# Measurement Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"])
122-
writer.writerow([f"# Sweep Parameters: Start={start_v}V, Stop={stop_v}V, Steps={steps}, Delay={delay}s"])
123-
writer.writerow(["Timestamp (s)", "Applied Voltage (V)", "Measured Current (A)", "Resistance (Ohm)"])
124-
125-
start_time = time.time()
126-
for i, voltage in enumerate(voltage_sweep):
127-
keithley.source_voltage = voltage
128-
time.sleep(delay)
129-
resistance = keithley.resistance
130-
timestamp = time.time() - start_time
131-
#resistance = keithley.resistance
132-
current = voltage/resistance if resistance != 0 else float('inf')
133-
134-
print(f"Step {i+1}/{steps}: V={voltage:.3f} V, I={current:.4e} A, R={resistance:.4e} Ω")
135-
136-
data_point = [f"{timestamp:.3f}", f"{voltage:.4e}", f"{current:.4e}", f"{resistance:.4e}"]
137-
results.append(data_point)
138-
writer.writerow(data_point)
139-
140-
print("\n--- I-V Sweep Complete ---")
141-
print(f"Data saved successfully to '{filename}'")
142-
143-
except VisaIOError:
144-
print(f"\n[VISA Connection Error]")
145-
print(f"Could not connect to the instrument at '{VISA_ADDRESS}'.")
146-
print("Please check the address, cable connections, and if the instrument is on.")
147-
except ValueError:
148-
print("\n[Input Error] Please enter valid numbers for the sweep parameters.")
14955
except Exception as e:
150-
print(f"\n[An Unexpected Error Occurred] Details: {e}")
151-
152-
finally:
153-
# --- 7. SAFELY SHUT DOWN (V5 Logic) ---
154-
if keithley:
155-
print("\nShutting down instrument...")
156-
keithley.shutdown()
157-
print("Voltage source OFF and instrument is safe.")
158-
159-
# --- 8. PLOT RESULTS ---
160-
plot_results(results)
56+
print(f"Error with Keithley: {e}")

0 commit comments

Comments
 (0)