from KeithleyV15 import SMU26xx
from setupElab import eLabFTW
import matplotlib.pyplot as plt
import time
import datetime
import csv
import numpy as np
from voetsch import VT4002

"""
EXAMPLE: characteristic curve of a diode

Schematic:

    --------------
    |            |
  -----         -|-
  | A | SMU     \|/
  -----         -|-
    |            |
    --------------

"""


""" ******* Connect to eLab ******** """
# Connect to eLab and create an experiment
exp_title = "Diode Measurements"
exp_description = "I-V Measurement"
exp_date = datetime.datetime.now().strftime("%Y_%m_%d")
#
elab = eLabFTW()
elab.set_experiment(exp_title, exp_date,  exp_description)
# you can add an extra tag for your group, e.g., #SS22S3 or #WS23S1
elab.add_tag(exp_title,"#WS22S1_I-V")
elab.add_tag(exp_title,"#WS22S1_Graf_Tsch_Ret")


""" ******* Connect to the Sourcemeter ******** """
# initialize the Sourcemeter and connect to it
# you may need to change the IP address depending on which sourcemeter you are using
sm = SMU26xx("TCPIP0::129.27.158.13::inst0::INSTR")

# get one channel of the Sourcemeter (we only need one for this measurement)
smu = sm.get_channel(sm.CHANNEL_A)

time_for_name = datetime.datetime.now().strftime("%Y_%m_%d_%H%M%S")


""" ******* Connect to the climate chamber ******** """
# define connection parameters
ip_address = "129.27.158.42"
username = "simpacuser"   # fill in the username on the front of the climate chamber
password = "u1s2e3r4"   # fill in the password on the front of the climate chamber

# connect to the climate chamber
climate_chamber = VT4002(ip_address, username, password)

# enable climate chamber
climate_chamber.enable()


""" ******* Measure at different temperatures ******** """
# sweep through temperatures with the climate chamber
for T in range(10,40):
    climate_chamber.go_to_temperature(T, 0.2, 60)
    
    #Read out the current temperature and print the result to the console
    temp = climate_chamber.get_actual_temperature()
    print('Current temperature (°C): ' + str(temp))

    # make some measurement at each temperature
    # use different ranges for high and low voltages to get good results
    current_range=(3e-2,1e-5,1e-8)       
    sweep_start_tuple=(0,0,-2)
    sweep_end_tuple=(2,2,0)
    sweep_step_tuple=(0.01,0.01,0.01)
        
    for i in range(3):
        # Create unique filenames for saving the data        
        filename_csv = 'temperature_'+ str(temp)+"_"+str(i)+"_time_" + time_for_name +'.csv'
        filename_pdf = 'temperature_' + str(temp)+"_"+str(i)+"_time_" + time_for_name +'.pdf'

        # Header for csv
        with open(filename_csv, 'a') as csvfile:
                writer = csv.writer(csvfile, delimiter=';',  lineterminator='\n')
                writer.writerow(["Voltage / V", "Current / A"])
                
        # reset to default settings
        smu.reset()
        # setup the operation mode
        smu.set_mode_voltage_source()
        # set the voltage and current parameters 
        smu.set_voltage_range(2)    # in [V] - Possible ranges: 0.2 V, 2 V, 20 V
        smu.set_voltage_limit(2)    
        smu.set_voltage(0)
        smu.set_current_range(current_range[i]) # in [A]
        smu.set_current_limit(current_range[i])
        smu.set_current(0)
        
        # define sweep parameters
        sweep_start = sweep_start_tuple[i]
        sweep_end = sweep_end_tuple[i]
        sweep_step = sweep_step_tuple[i]
        steps = int((sweep_end - sweep_start) / sweep_step)

        # define variables we store the measurement in
        data_current = []
        data_voltage = []

        # enable the output
        smu.enable_output()
        
        """ ******* Make a voltage-sweep and do some measurements ******** """
        # step through the voltages and get the values from the device
        for nr in range(steps):
            # calculate the new voltage we want to set
            voltage_to_set = sweep_start + (sweep_step * nr)
            # set the new voltage to the SMU
            smu.set_voltage(voltage_to_set)
            # get current and voltage from the SMU and append it to the list so we can plot it later
            [current, voltage] = smu.measure_current_and_voltage()
            data_voltage.append(voltage)
            data_current.append(abs(current))
            print(str(voltage)+' V; '+str(current)+' A')
            # Write the data in a csv
            with open(filename_csv, 'a') as csvfile:
                writer = csv.writer(csvfile, delimiter=';',  lineterminator='\n')
                writer.writerow([voltage, current])

        # disable the output
        smu.disable_output()
        
        """ ******* Plot the measurements ******** """
        #plot data
        plt.figure()
        plt.plot(data_voltage, data_current,'x-', linewidth=2)

        # set labels and a title
        plt.xlabel('Voltage / V', fontsize=14)
        plt.ylabel('Current / A', fontsize=14)
        plt.yscale('log')
        plt.title('Characteristic curve of a diode', fontsize=14)
        plt.tick_params(labelsize = 14)
        plt.tight_layout()
        plt.savefig(filename_pdf)

        # Upload files to eLab
        elab.upload_file(filename_csv)
        elab.upload_file(filename_pdf)
        temp_end = climate_chamber.get_actual_temperature()
        print('Temperature after IV (°C): ' + str(temp_end))

""" ******* properly disconnect from the devices ******** """
# bring the climate chamber to room temperture so you can safely open it
climate_chamber.go_to_temperature(20, 2, 60)

# disconnect from climate chamber
climate_chamber.disable()

# disconnect from SMU
sm.disconnect()


""" ******* upload to eLab ******** """
# Upload files to eLab
elab.upload_script(__file__)
