Jump to content

joshna

Members
  • Posts

    2
  • Joined

  • Last visited

Posts posted by joshna

  1. On 4/2/2024 at 9:31 AM, attila said:

    Hi @joshna

    Probably the V_DS input voltage on the analog input channel is out the range. 
    The analog inputs of AD3 have two input ranges, approximately 5V and 50V pk2pk, and adjustable offset.
    Set offset or range dwf.FDwfAnalogInChannelOffsetSet(hdwf, #, c_double(2.5)) or dwf.FDwfAnalogInChannelRangeSet(hdwf, #, c_double(50.0))

    @attila Thank you so much! This helped me a lot with increasing the input voltage.

     

    However, I now see 2 other problems so I was wondering if you would be able to help me with that?

    One problem is that the voltages I get now go up to 30 Volts, by the input waveform should only go from 0 to 10 volts so the channel should not be getting and plotting 30 Volts.

    For reference, this is the new graph:

    Screenshot2024-04-09at16_27_08.thumb.png.f858589617b43114eb4bf7b1434af75a.png

    And this is the updated code:

    from WF_SDK import device, scope, wavegen   # import instruments
    
    import matplotlib.pyplot as plt   # needed for plotting
    
    import csv #needed for generating CSV files for graphing later
    import ctypes
    from sys import platform, path    # this is needed to check the OS type and get the PATH
    from os import sep                # OS specific file path separators
     
    """-----------------------------------------------------------------------"""
    # assign dwf to be used later
    # load the dynamic library, get constants path (the path is OS specific)
    if platform.startswith("win"):
        # on Windows
        dwf = ctypes.cdll.dwf
        constants_path = "C:" + sep + "Program Files (x86)" + sep + "Digilent" + sep + "WaveFormsSDK" + sep + "samples" + sep + "py"
    elif platform.startswith("darwin"):
        # on macOS
        lib_path = sep + "Library" + sep + "Frameworks" + sep + "dwf.framework" + sep + "dwf"
        dwf = ctypes.cdll.LoadLibrary(lib_path)
        constants_path = sep + "Applications" + sep + "WaveForms.app" + sep + "Contents" + sep + "Resources" + sep + "SDK" + sep + "samples" + sep + "py"
    else:
        # on Linux
        dwf = ctypes.cdll.LoadLibrary("libdwf.so")
        constants_path = sep + "usr" + sep + "share" + sep + "digilent" + sep + "waveforms" + sep + "samples" + sep + "py"
    
    # import constants
    path.append(constants_path)
     
    drain_resistance = 100#float(input("Enter the resistance in Ohms of the resistor in series with the mosfet DRAIN: "))
    gate_resistance = 100#float(input("Enter the resistance in Ohms of the resistor in series with the mosfet GATE: "))
    chip_number = "305"#input("Enter your chip number (ex. 305): ")
    device_id = "2b1"#input("Enter the device being tested (ex. 2b1): ")
    gate_voltages = input("Enter the gate voltages to test as a comma-separated list (Ex. 1, 1.5, 1.6, 3): ").replace(" ", "").split(",")
    # name of csv files
    filename_currents = f"csvfiles/{chip_number}_{device_id}_currents.csv"
    filename_voltages = f"csvfiles/{chip_number}_{device_id}_voltages.csv"
    # connect to the device
    ad3_data1 = device.open() #open the first analog discovery 3 to measure Id and Vds
    ad3_data2 = device.open() #open the second analog discovery 3 to measure Ig and Vds
    #ad3_data3 = device.open() #open the third analog discovery 3 to measure Ib and Vds TODO
     
    """-----------------------------------"""
    
    # writing to csv file  
    for filename in [filename_currents, filename_voltages]:
        with open(filename, 'w') as csvfile: # opens csv files
            csvwriter = csv.writer(csvfile)  # creating a csv writer object 
            csvwriter.writerow(gate_voltages) # writes header row (gate voltages)
     
    # initialize the scope with default settings
    scope.open(ad3_data1, sampling_frequency=10e5)
    
    wavegen.generate(ad3_data1, channel=1, function=wavegen.function.sine, offset=5, frequency=100, amplitude=5) #generation sine waveform to drain
    
    #set voltage peak to peak input range to 50 V on both channels
    dwf.FDwfAnalogInChannelRangeSet(ad3_data1.handle, 0, ctypes.c_double(50.0))
    dwf.FDwfAnalogInChannelRangeSet(ad3_data1.handle, 1, ctypes.c_double(50.0))
    
    # generate a 10KHz sine signal with 2V amplitude on channel 1
    current_dict = {}
    volt_dict = {}
    #for VB in body_voltages: #TODO loop through body as well
    for VG in gate_voltages:
        VG = float(VG)
        wavegen.generate(ad3_data1, channel=2, function=wavegen.function.dc, offset=VG, frequency=10e2, amplitude=1) #generate dc signal to gate voltage at voltage i
        [drain_voltages, ds_voltages1] = scope.record2(ad3_data1) # get data with first AD3 oscilloscope
        [gate_voltages, ds_voltages2] = scope.record2(ad3_data2) # get data with second AD3 oscilloscope
        drain_currents = []
        gate_currents = []
        for i in range(len(drain_voltages)):
            drain_currents.append(drain_voltages[i]/drain_resistance) # calculate current with ohms law
            gate_currents.append(gate_voltages[i]/gate_resistance) # calculate current with ohms law
        for filename in [filename_currents, filename_voltages]: #outputs currents and voltages to csv TODO add second AD3 data maybe to XLS
            with open(filename,'a') as csvfile:
                writer = csv.writer(csvfile)
                if "current" in filename:
                    writer.writerow(drain_currents)
                elif "voltage" in filename:
                    writer.writerow(ds_voltages1)
        plt.plot(ds_voltages1, drain_currents, label = f"Id with Vg = {VG}") #plot curve of Id vs. Vds    
        #plt.plot(ds_voltages2, gate_currents, label = f"Ig with Vg = {VG}") #plot curve of Id vs. Vds   
        #TODO figure out how to 3d plot agains Ib as well 
    
    
    #plot labels and show
    leg = plt.legend(loc='upper center')
    #plt.xlim(0, 10)
    #plt.ylim(-0.001, 0.03)
    plt.xlabel("Voltage (V_DS) [V]")
    plt.ylabel("Current [A]")
    plt.show()
    
    #TODO only save data to csv if plot looks good
    
    # reset the scope
    scope.close(ad3_data1)
     
    # reset the wavegen
    wavegen.close(ad3_data1)
     
    # close the connection
    device.close(ad3_data1)

     

    The other problem I have, is that when I don't start off with a gate voltage of 1 V, I get really strange looking graphs. For example,

     Vg = 1, 2, 3, 4, 5 on 50V vs 5V analog inputScreenshot2024-04-09at16_27_08.thumb.png.7629e145c6c2c848834d8e2c03ebecd6.png:Screenshot2024-04-09at16_29_38.thumb.png.d91e1a886d4080ee4079f3badabe5a7f.png

     

     

    Vg = 2, 3, 4, 5 on 50V vs 5V analog input:

    Screenshot2024-04-09at16_27_24.thumb.png.30fcafc3a3b13e86d018545547159a82.pngScreenshot2024-04-09at16_29_51.thumb.png.58741db714d3f8396284ae00e8d40def.png

     

    Vg = 2, 3, 4 on 50V vs 5V analog input:

    Screenshot2024-04-09at16_27_58.thumb.png.a7f8a5c590beee36a786136dd7303bdd.pngScreenshot2024-04-09at16_30_14.thumb.png.e21c5c523f89c5141a297167fdc0d536.png

     

    Vg = 3, 4, 5 on 50V vs 5V analog input:

    Screenshot2024-04-09at16_28_16.thumb.png.97f83b57e4104a719b1db486f47059cf.pngScreenshot2024-04-09at16_30_46.thumb.png.f9f088c0c1ffbc2de6594fff7859e056.png

     

    Screenshot 2024-04-09 at 16.27.08.png

    Screenshot 2024-04-09 at 16.29.38.png

  2. Hi all,

    I created a script (below) using the Waveforms SDK to use an Analog Discovery 3 to sweep gate and drain voltages over a mosfet and generate IV curves. The plots look right but they seem to be limited by current and aren't showing the full plot. I was wondering if anyone knows why this is?

     

    The plots:

    Screenshot2024-03-26at17_35_38.thumb.png.471bb9ee7ebb7e82f1800ff46d914dd9.png

    Screenshot 2024-03-26 at 17.34.41.png

     

    This is the script I am runing:

    from WF_SDK import device, scope, wavegen   # import instruments
     
    import matplotlib.pyplot as plt   # needed for plotting
    
    import csv #needed for generating CSV files for graphing later
     
    """-----------------------------------------------------------------------"""
     
    #resistance = float(input("Enter the resistance in Ohms of the resistor in series with the mosfet: ")) TODO user inputs later
    resistance = 100
    gate_voltages = [0, 1, 2, 3, 4, 5] #gate voltages to sweep across
    # name of csv files
    filename_currents = "chip_currents.csv"
    filename_voltages = "chip_voltages.csv"
    # connect to the device
    device_data = device.open() #TODO open again to get second device
     
    """-----------------------------------"""
    
    # writing to csv file  
    for filename in [filename_currents, filename_voltages]:
        with open(filename, 'w') as csvfile: # opens csv files
            csvwriter = csv.writer(csvfile)  # creating a csv writer object 
            csvwriter.writerow(gate_voltages) # writes header row (gate voltages)
     
    # initialize the scope with default settings
    scope.open(device_data, sampling_frequency=10e5)
    
    # generate a 10KHz sine signal with 2V amplitude on channel 1
    current_dict = {}
    volt_dict = {}
    for VG in gate_voltages:
        wavegen.generate(device_data, channel=2, function=wavegen.function.dc, offset=VG, frequency=10e2, amplitude=1) #generate dc signal to gate voltage at voltage i
        wavegen.generate(device_data, channel=1, function=wavegen.function.sine, offset=2.5, frequency=10e2, amplitude=2.5) #generation sine waveform to drain
        [mosfet_voltages, resistor_voltages] = scope.record2(device_data) # get data with AD3 oscilloscope
        mosfet_currents = []
        for v in resistor_voltages:
            mosfet_currents.append(v/resistance) # calculate current with ohms law
        for filename in [filename_currents, filename_voltages]: #outputs currents and voltages to csv
            with open(filename,'a') as csvfile:
                writer = csv.writer(csvfile)
                if "current" in filename:
                    writer.writerow(mosfet_currents)
                elif "voltage" in filename:
                    writer.writerow(mosfet_voltages)
        plt.plot(mosfet_voltages, mosfet_currents) #plot curve of mosfet voltages vs. mosfet currrents    
    
    #plot labels and show
    plt.xlabel("Voltage (V_DS) [V]")
    plt.ylabel("Current (I_D) [A]")
    plt.show()
    
    # reset the scope
    scope.close(device_data)
     
    # reset the wavegen
    wavegen.close(device_data)
     
    # close the connection
    device.close(device_data)

     

    In case anyone asks, record2 which I use to record data from the oscilloscope is just a modified scope.record function in order to get data from both channels at the same time. Even if I use record, I still see current limiting graphs but they are also just wrong because of the time offset so I don't think that is the problem. Regardless, the code for record2 in scope.py looks like this:

    def record2(device_data):
        """
            record an analog signal
    
            parameters: - device data
                        - the selected oscilloscope channel (1-2, or 1-4)
    
            returns:    - a list with the recorded voltages
        """
        # set up the instrument
        if dwf.FDwfAnalogInConfigure(device_data.handle, ctypes.c_bool(False), ctypes.c_bool(True)) == 0:
            check_error()
        
        # read data to an internal buffer
        while True:
            status = ctypes.c_byte()    # variable to store buffer status
            if dwf.FDwfAnalogInStatus(device_data.handle, ctypes.c_bool(True), ctypes.byref(status)) == 0:
                check_error()
        
            # check internal buffer status
            if status.value == constants.DwfStateDone.value:
                    # exit loop when ready
                    break
        
        # copy buffer
        buffer = (ctypes.c_double * data.buffer_size)()   # create an empty buffer
        buffer2 = (ctypes.c_double * data.buffer_size)()   # create an empty buffer
        if dwf.FDwfAnalogInStatusData(device_data.handle, ctypes.c_int(0), buffer, ctypes.c_int(data.buffer_size)) == 0:
            check_error()
        if dwf.FDwfAnalogInStatusData(device_data.handle, ctypes.c_int(1), buffer2, ctypes.c_int(data.buffer_size)) == 0:
            check_error()
        
        # convert into list
        buffer = [float(element) for element in buffer]
        buffer2 = [float(element) for element in buffer2]
        return [buffer, buffer2]

     

    Thank you so much!

     

×
×
  • Create New...