diff --git a/TLM_tool/DAQ_test.ipynb b/TLM_tool/DAQ_test.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..0265e3e60271b6396a8ffb1064391a5b17d99126 --- /dev/null +++ b/TLM_tool/DAQ_test.ipynb @@ -0,0 +1,53 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "b3965c31-edec-4d04-856c-c4bb850bd22a", + "metadata": {}, + "outputs": [], + "source": [ + "import hp3497a_lib" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2c7d107a-4035-48b6-8024-2fe5a438b1b7", + "metadata": {}, + "outputs": [], + "source": [ + "daq = hp3497a_lib.hp3497a()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4f45391-ec6d-47c2-ae1e-445097197bdb", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/TLM_tool/TLM_test.ipynb b/TLM_tool/TLM_test.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..e34c45a87c6b8830890549f9e76621d9d9eb9137 --- /dev/null +++ b/TLM_tool/TLM_test.ipynb @@ -0,0 +1,157 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b3e34c09-2034-478a-aa83-20842b4fd2ed", + "metadata": {}, + "outputs": [], + "source": [ + "import hp3497a_lib" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "310d4da7-5604-41c8-9c1f-643eaffd0fe5", + "metadata": {}, + "outputs": [], + "source": [ + "hp3497a = hp3497a_lib.hp3497a()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0c221d59-b803-40d5-9572-a4143c0e215c", + "metadata": {}, + "outputs": [], + "source": [ + "import keithley224_lib" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "0ba94ac3-34d2-4ca9-afb2-35679abe013a", + "metadata": {}, + "outputs": [], + "source": [ + "k224 = keithley224_lib.keithley224()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ca1e3eb3-1394-4abf-adf4-83332a5576f8", + "metadata": {}, + "outputs": [], + "source": [ + "k224.set_current(50e-3)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "db84a327-f609-45c7-ae09-4d61062a340e", + "metadata": {}, + "outputs": [], + "source": [ + "k224.set_operation(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "bc962183-5552-434e-8a81-07da03584cd8", + "metadata": {}, + "outputs": [], + "source": [ + "#trigger measurement\n", + "voltages = []\n", + "channels = [11,1,3,4,15]\n", + "octal_codes = [4562,303,42303,63303,100327]\n", + "for i in range(5) :\n", + " hp3497a.inst.write(f\"DW3,{octal_codes[i]}\")\n", + " voltage = hp3497a.inst.query(f\"AI{channels[i]}SO0VT3VN20\")\n", + " #voltage = voltage.strip()\n", + " voltages.append(voltage)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "1086f8c3-6ad4-41ea-b100-282f13cafcbe", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['-0.55772E+0', '-0.67859E+0', '-0.17070E+0', '-0.22628E+0', '-0.13430E+0']\n" + ] + } + ], + "source": [ + "print(voltages)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "85d8304b-05f8-4f30-9498-87e09265760e", + "metadata": {}, + "outputs": [], + "source": [ + "i,v,w = k224.read_parameters()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "a1170083-3dbd-48b3-a9fe-7c563b35ab88", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.05\n" + ] + } + ], + "source": [ + "print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf25f171-e3ac-4881-a846-e0cd0c8cbaa9", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/TLM_tool/contact_check.ipynb b/TLM_tool/contact_check.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..2889fb1b54e0e61ebff4211f85c75a9916a46c6e --- /dev/null +++ b/TLM_tool/contact_check.ipynb @@ -0,0 +1,109 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "c2ed1aa9-0936-4cf7-9737-7d077342abf0", + "metadata": {}, + "outputs": [], + "source": [ + "import keithley224_lib \n", + "import hp3497a_lib" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1ee2c2d0-9dc5-4ab6-a2e9-cb464d8724e5", + "metadata": {}, + "outputs": [], + "source": [ + "k224 = keithley224_lib.keithley224()\n", + "hp3497a = hp3497a_lib.hp3497a()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "b116f382-9669-4bce-99e5-2b1e2aded438", + "metadata": {}, + "outputs": [], + "source": [ + "k224.set_current(50e-3)\n", + "k224.set_operation(1)\n", + "hp3497a.digital_viewed(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "ee855c9f-a611-41d9-a68f-12c66fb55ee8", + "metadata": {}, + "outputs": [], + "source": [ + "slot = 3" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "00c0628b-24f8-412c-a48a-4a52b808aea1", + "metadata": {}, + "outputs": [], + "source": [ + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "f72daedc-a330-4302-bafc-7824395fb560", + "metadata": {}, + "outputs": [], + "source": [ + "#for octal in range(177778):\n", + "hp3497a.digital_write(slot,63303)\n", + "time.sleep(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b91f75f9-8a8d-4384-bd12-222fbc67e02a", + "metadata": {}, + "outputs": [], + "source": [ + "k224.set_operation(0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0481621f-804f-4e69-a480-1c59d4c3a2cc", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/TLM_tool/hp3497a_lib.py b/TLM_tool/hp3497a_lib.py index eb01de740456780e7f2cc9759b404d144d5ef16e..3fd8daee72537e5d856244ebe92ee798d0d8e9a2 100644 --- a/TLM_tool/hp3497a_lib.py +++ b/TLM_tool/hp3497a_lib.py @@ -4,6 +4,10 @@ import pyvisa class hp3497a(object): """ This is a the control class of hp3497a based on the command directory that can be found in the manual HP3497A Operating Programming and Configuration Chapter 6 + + Commands That are not stil present in this library: + 1) Analog External Increment (page 287) + """ def __init__(self,address="GPIB0::9::INSTR"): @@ -20,11 +24,12 @@ class hp3497a(object): Help --- 1) Set instrument timeout to NONE to prevent disconnections + 2) Set Local Lockout """ self.address = address self.rm = pyvisa.ResourceManager() self.inst = self.rm.open_resource(address) - self.inst.control_ren(3) + self.inst.control_ren(5) self.inst.timeout = None def __del__(self): @@ -34,7 +39,131 @@ class hp3497a(object): self.inst.control_ren(0) self.inst.close() + def analog_close(self,*channels): + """ + Description + ----------- + Closes 1 to 4 channels,one per decade,simultaneously. Used to control analog assemblines + + Examples + -------- + "AC3" #Close channel 3 + "AC3,13,23,33" #Close channels 3,13,23,33 + + Notes + ----- + 1) Up to 4 Channels (1/decade) may be closed simultaneously + 2) AC command opens all previously closed channels + 3) AC without channel parameter opens all channels + 4) Power On State: Analog Close disabled + + Parameters + ---------- + *channels:Up to 4 channel numbers (integers) + """ + + command = "AC" + for i,channel in enumerate(channels): + if i != len(channels)-1: + command = command + f"{channel}," + else: + command = command +f"{channel}" + + self.inst.write(command) + + def analog_first_channel(self,channel): + """ + Description + ----------- + Selects the first channel to be closed in a scan sequence but does not close the channel(see ANALOG STEP command). Used to control analog assemblines + + Examples + -------- + "AF30" #Sets channel 30 as first channel + "AF5" #Sets channel 5 as first channel + + Note + ---- + 1) Power On State: AF0 = First Channel is 000 + + Parameters + ---------- + Channel Number : Int + """ + command = f"AF{channel}" + self.inst.write(command) + + def analog_input(self,channel): + """ + Description + ----------- + Closes the channel indicated and triggers DVM to take a single reading. The measurement result is formated by the VFn command(See VOLTOMETER TRIGGER command).Used to control analog assemblines + + Examples + -------- + "AI15" # Voltage measurement on channel 15 + "AI3" # Voltage measurement on channel 3 + + Note + ---- + 1) Power on State: Analog Input disabled + """ + + command = f"AI{channel}" + self.inst.write(command) + + def analog_last_channel(self,channel): + """ + AL chan# chan#= 0 to 999 + + Description + ----------- + Selects the last channel to be closed in a scan sequence, but does not close the channel(see ANALOG STEP command) + Used to control analog assemblines + + Examples + -------- + "AL30" # Sets channel 30 as last channel + "AL5" # Sets channel 5 as last channel + + Note + ---- + Power On State: AL999 = Last channel is 999 + """ + command = f"AL{channel}" + self.inst.write(command) + + def analog_output(self,slot,channel,integer): + """ + AO slot#,chan#,integer + slot# = 0 to 89 + chan# = 0 or 1 + integer = -10238 to 10238 (VDAC) + = 0 to 10238 (IDAC) + + Description + ----------- + Sets the output voltage level for the Voltage D/A (VDAC) or the output current level for the Current D/A converter (IDAC) + + Output Voltage range for the VDAC is from -10.2375V to +10.2375V in 2.5mV increments. + """ + def system_read(self,slot): return self.inst.query(f"SR{slot},0") - \ No newline at end of file + def digital_close(self,slot,channel): + self.inst.write(f"DC{slot},{channel}") + + def digital_open(self,slot,channel): + self.inst.write(f"DO{slot},{channel}") + + def digital_load(self,slot): + return self.inst.query(f"DR{slot}") + + def digital_viewed(self,slot): + self.inst.write(f"DV{slot}") + + def digital_write(self,slot,octal): + self.inst.write(f"DW{slot},{octal}") + + \ No newline at end of file diff --git a/TLM_tool/old/keitley_224_control_class.py b/TLM_tool/old/keitley_224_control_class.py new file mode 100644 index 0000000000000000000000000000000000000000..36916014839508c7b70ecae3c45d7aed669df6a4 --- /dev/null +++ b/TLM_tool/old/keitley_224_control_class.py @@ -0,0 +1,182 @@ +''' +KEITHLEY 224 instrument driver +TODO: SRQ decoding +https://www.eevblog.com/forum/testgear/keithley-224-python-code/ +''' +import pyvisa +import enum + +class Readout_Values: + def __init__(self): + self.raw = "" + self.current = 0.0 + self.overcompliance = False + self.voltage = 0.0 + self.time = 0.0 + +# Range Commands +RANGE_LIST = ( + 'R0', + 'R5', + 'R6', + 'R7', + 'R8', + 'R9', + ) + +def get_available_devices(): + rm = pyvisa.ResourceManager() + devices = rm.list_resources() + rm.close() + return devices + +def _decode_values(rawdata): + splitted = rawdata.split(',') + readout = Readout_Values() + readout.raw = rawdata + for element in splitted: + if 'DCI' in element: + if element[0] is 'O': + readout.overcompliance = True + readout.current = float(element[4:]) + if 'V' in element: + readout.voltage = float(element[1:]) + if 'W' in element: + readout.time = float(element[1:]) + return readout + +def _format_e(n): + a = '%E' % n + return a.split('E')[0].rstrip('0').rstrip('.') + 'E' + a.split('E')[1] + +class KEITHLEY_224(object): + + class Ranges(enum.Enum): + AUTO = 0 + MAN_20uA = 1 + MAN_200uA = 2 + MAN_2mA = 3 + MAN_20mA = 4 + MAN_1m01A = 5 + + def __init__(self, address): + self._address = address + self._rm = pyvisa.ResourceManager() + self._inst = self._rm.open_resource(address) + self._range = self.Ranges.AUTO + self.voltage = 3.0 + self.current = float(1e-06) + self.time = 0.05 + self.operate = False + self._inst.control_ren(1) ## +++++++++++++++++++++++ + + def __del__(self): + self.operate = False + self._inst.control_ren(0) ## +++++++++++++++++++++++ + self._rm.close() + + def get_measurement(self): + self._inst.timeout = 1000 + result = _decode_values(self._inst.read()) + return result + + @property + def range(self): + return self._range + + @range.setter + def range(self, range): + if not isinstance(range, self.Ranges): + raise TypeError('mode must be an instance of Ranges Enum') + self._range = range + self._inst.write(RANGE_LIST[self._range.value]+'X') + + @property + def voltage(self): + return self._voltage + + @voltage.setter + def voltage(self, voltage): + if (voltage < 1) or (voltage > 105): + raise ValueError('voltage limits: 1 to 105') + self._voltage = voltage + self._inst.write('V'+ _format_e(voltage)+'X') + + @property + def current(self): + return self._current + + @current.setter + def current(self, current): + if (current < -0.101) or (current > 0.101): + raise ValueError('current limits: +/- 0.101') + self._current = current + self._inst.write('I' + _format_e(current) + 'X') +# print('I' + _format_e(current) + 'X') ## +++++++++++++++++++++++ + + @property + def time(self): + return self._time + + @time.setter + def time(self, time): + if (time < 0.05) or (time > 0.9999): + raise ValueError('time limits: 0.05 to 0.9999 sec') + self._time = time + self._inst.write('W' + _format_e(time) + 'X') + + @property + def operate(self): + return self._operate + + @operate.setter + def operate(self, operate): + if type(operate) is not type(True): + raise ValueError('operate takes a bool value') + self._operate = operate + if operate is True: + self._inst.write('F1X') + else: + self._inst.write('F0X') + + +# testing the code +if __name__ == '__main__': + import numpy + import time + +## instrument = KEITHLEY_224("GPIB0::15::INSTR") +## +## meas = instrument.get_measurement() +## print('Raw data: ' + str(meas.raw)) +## print('Current: ' + str(meas.current)) +## print('Overcompliance: ' + str(meas.overcompliance)) +## print('Voltage: ' + str(meas.voltage)) +## print('Time: ' + str(meas.time)) +## +## instrument.operate = True +## instrument.voltage = 15 +## instrument.time = 0.5 +## +## time.sleep(5) +## +## for i in numpy.arange(0.001,0.015,0.001): +## instrument.current = i +## time.sleep(5.1) +## +## meas = instrument.get_measurement() +## print('Raw data: ' + str(meas.raw)) +## print('Current: ' + str(meas.current)) +## print('Overcompliance: ' + str(meas.overcompliance)) +## print('Voltage: ' + str(meas.voltage)) +## print('Time: ' + str(meas.time) + '\n\n\n') +## +## del instrument + + instrument = KEITHLEY_224("GPIB0::15::INSTR") + + while True: + try: + pass + except: + del instrument