Select Git revision
hp3497a_lib.py
hp3497a_lib.py 15.44 KiB
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)
2) Counter Functions (Pages 291-295)
3) Digital Interrupt commands (Page 297,page 299)
4) Service Request Enable (Pages 303-304)
5) System Lock (Page 305)
6) Status Register Read (Page 308)
7) System Write (Page 310)
7) Timer Commands (Page 310-314)
8) Irrelevant Voltmeter Commands
"""
def __init__(self,address="GPIB0::9::INSTR"):
"""
Parameters
----------
address: The GPIBO address is to be found at the I/O monitor
Atrributes
---------
rm: pyvisa resource manager to connect to instrument(s)
inst : an object to control the hp3497a
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(5) #local lockout
self.inst.timeout = None
def __del__(self):
"""
Destructor: Close the remote connection
"""
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.
Any integer input which is not a multiple of 2.5mV is automatically rounded to the nearest integer multiple of 2.5mV
(i.e., sending 1365 or 1366 results in a 1.365V output)
The IDAC has two jumper selectable ranges: 0-20mA (5uA increments) or 4-20mA (4uA increments). The IDAC can be programmed in units of 0.01% of value range.
However, the output can only change in increments of 0.025% of range.
See page 289 for voltage and current levels
Examples
--------
"A015,0,-2500" #Outputs -2.5V on channel 0 of a VDAC in slot 15
"AO15,1,160" #Outputs 4.256 mA on channel 1 of an IDAC in slot 15 if assembly is set for 4-20mA operation.
Outputs 0.320mA on channel 1 of an IDAC in slot 15 if assembly is set for 0-20mA operation
Notes
-----
1) Slots 5 through 9 do not exist. Attempted access to these slots may cause errors in data transfer
2) Only one channel maybe adressed at a time
3) Current Output can be 0-102.4% of full-scale
4) Power on state : Analog Output disabled (no output)
"""
command = f"AO{slot},{channel},{integer}"
self.inst.write(command)
def analog_reset(self):
"""
Opens all channels for analog assemblies. In addition AR sets VF1,VT1,VR5,VW0,VS0,AE0,AF0 and AL999
(if you don't know these commands take a look at the manual)
Notes
-----
1) Although VS0 is set, AR does not clear the storage buffer
2) After AR is performed,approximately 1/4 sec is required before another analog command can be sent
3) Power on state : Analog reset once at turn on
"""
self.inst.write("AR")
def analog_step(self):
"""
Performs a software channel advance from the presently closed analog channel between the limits set by the AF and AL commands
(see analog_first_channel and analog_last_channel)
Repeating the AS Command causes channels to sequence from an AF to AL and then Repeat the Sequence starting at AF
Notes
-----
1) if AF<AL channels increment.if AF>AL channels decremend
2) if multiple channels are closed and the AS command is givwn,only the last channel in sequence will increment. The other channels will be opened
3) Power on state: Analog Step disabled
"""
self.inst.write("AS")
def analog_viewed_channel(self,channel):
"""
AV chan# chan# = 0 to 999
Dedicates the 3 digit display and the 6 digit display to the channel specified in the command.
Comamnd does not close channel and does not affect other 3497A operations
Display is updated when a channel is closed and a measurement taken
Note
----
1) Power on State : Analog Viewed disabled
"""
command = f"AV{channel}"
self.inst.write(command)
# All digital commands refer to the 16 channel actuator-multimeter
def digital_close(self,slot,*channels):
"""
DC slot#,chan#,chan#...
slot# = 0 to 89
chan# = 0 to 15
Description
-----------
The Digital Close (DC) command is used with the actuator assemblies.
For the actuator/digital assembly (Option 110) DC connects the normal open (NO) position relay to common (bit 1)
Notes
-----
1) Channels not specified in the DC command remain in the previous state
2) Up to 16 channels may be included in the DC command
3) Power On State : All relays in Normal Closed position
"""
command = f"DC{slot},"
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 digital_load(self,slot):
"""
DL slot# slot# = 0 to 89
DL returns the octal value(0-177777) of the output conditions of the 16 channels in the assembly where a "1" in a channel indicates that the channel relay is closed
Notes
-----
1) Power on state : Digital Load Disabled
2) Digital Load returns the same information as Digital Read command, except that only one reading is produced for each command
"""
return self.inst.query(f"DL{slot}")
def digital_open(self,slot,*channels):
"""
DO slot#,chan#,chan#,...
slot# 0 to 15
Description
----------
DO connects the normal closed position of the channel relay(s) addressed to common (bit 0)
Channel relays not specified in the DO command remain in the previous state
Notes
-----
1) Channels not specified in the DC command remain in the previous state
2) Up to 16 channels may be included in the DC command
3) Power On State : All relays in Normal Closed position
"""
command = f"DO{slot},"
for i,channel in enumerate(channels):
if i != len(channels)-1:
command = command + f"{channel},"
else:
command = command + f"{channel}"
print(command)
self.inst.write(command)
def digital_read(self,slot):
"""
DR slot#
slot# = 0 to 89
Description
-----------
DR returns the octal value (0-177777) of the output condition of the 16 channels in the assembly, where a "1" in a channel indicates that the relay is in the normal open position
Same as the SL but continiously updates data
"""
self.inst.write(f"DR{slot}")
def digital_viewed_slot(self,slot):
"""
DV slot# slot# = 0 to 89
Dedicates the hp3497a front panel to a digital slot (diasabled in power on state). To exit this mode send "DV" without a slot number
"""
self.inst.write(f"DV{slot}")
def digital_write(self,slot,octal):
"""
DW slot#,value slot# = 0 to 89
value# = 0 to 177777 (octal)
DW connects the normal open position of the channel relay(s) to common
Channels are set by the octal value sent
In contrast to DC or DO command, The DW command affects all channels simultaneously,while DC and DO affect only the channels specified in the command
Notes
----
1) All channels in assembly adressed are affected by the DW command
2) Power on state: All relays in Normal Closed position
"""
self.inst.write(f"DW{slot},{octal}")
def system_alarm(self):
"""
System Alarm initiates an audible alarm (BEEP) in the HP3497A. A BEEP is generated internally by the 3497A when it recieves illegal syntax
Power on state: "SA" - one BEEP
"""
self.inst.write("SA")
def system_clear(self):
"""
The system clear command is similar to the Break message,except that SC does not clear the command (input) buffer or return the 3497A to local mode.
Also SC clears all system errors
1) All command execution is terminated
2) All data transmission stops
3) All analog and digital channels are opened
4) The interrupt mask and status registers are cleared
5) Sets the DVM for internal trigger (VT1)
6) Sets analog first channel = 000 and analog last channel = 999
Notes
----
1) SC command does not reset VF2 or VF3 or clear the voltometer storage buffer
2) SC Command does not return the 3497A to local mode or clear the 3497A command (input) buffer
3) Power On State: System clear disabled
"""
self.inst.write("SC")
def system_display(self,status):
"""
SD0 = OFF SD1 = ON
SDO turns off the 6-digit display and the Channel annuciators for faster reading rates and to allow only data enttered with an SV (system view) command to affect the data display
"""
self.inst.write(f"SD{status}")
def system_init(self):
"""
Returns digial assemblies and the DVM to initial conditions
"""
self.inst.write("SI")
def system_output(self,status):
"""
Set 0 for continious output to controller
Set 1 for single output command to the controller
Power on State: SO0 Continious Output mode
"""
self.inst.write(f"SO{status}")
def system_read(self,slot):
"""
See the Plug-in in the respective slot
Returns octal code where last digit means:
0 Digital input
1 Actuator or HV Actuator
2 D/A Converter
3 Counter
7 Empty of Analog Assembly
"""
return self.inst.query(f"SR{slot},0")
def self_test(self,status=1):
"""
Perform a self test by sending 1. Disable by sending 0
Returns:
8E8 Self test passes
1E1 Cross guard fails
2E2 Voltometer Fails
3E3 Timer Fails
"""
return self.inst.query(f"ST{status}")
def system_view(self,n):
"""
Write data to the 6 digit Display on thr 3497A if the display has been previously turned off by the SD0 Command
n = -999999 to 999999
"""
self.inst.write(f"SV{n}")
def voltmeter_number(self,num):
"""
This command sets the number of readings per trigger (1 to 999)
"""
self.inst.write(f"VN{num}")
def voltmeter_trigger(self,mode):
"""
VT1 = INTERNAL (auto from hp3497a (power on))
VT2 = EXTERNAL (external from trigger pulses)
VT3 = SOFTWARE (Trigger and get the number of readings set by VNn)
VT4 = HOLD
"""
self.inst.write(f"VT{mode}")
def voltmeter_wait(self,n):
"""
Wait for n*100 usec beetween eanch reading. Maximum wait tieme is 99.9999 seconds
n = 0 to 999999
"""
self.inst.write(f"VW{n}")
# This to convert binary to octal and vise versa
def bin_to_octal(bin):
"""
Converts Binary to Octal
"""
decimal = int(str(bin),2)
octal = format(decimal,'o')
return octal
def octal_to_bin(octal):
"""
Converts octal number to binary
"""
decimal = int(str(octal),8)
bin = format(decimal,'b')
return bin
def channels_to_octal(*channels):
"""
Converets normaly open (1) channels(0-15) to octal
"""
decimal = 0
for channel in channels:
decimal = decimal + 2**channel
octal = format(decimal,'o')
return octal
def octal_to_channels(octal):
"""
Returns the channels in normally open position (1) as a list
"""
binary = str(octal_to_bin(octal)) # convert to string
channels = []
for i,digit in enumerate(binary[::-1]):
if int(digit)==1:
channels.append(i)
return channels