serial_instruments
unknown
python
2 years ago
12 kB
5
Indexable
import serial from time import sleep, time import serial.tools.list_ports def printCOMports(showIDN=True): ports = serial.tools.list_ports.comports() for port, desc, hwid in sorted(ports): print("{}: {} [{}]".format(port, desc, hwid)) if showIDN: try: inst = SerialInstrument(port) IDN = inst.get_idn() print('\t' + IDN) except: pass # Set instrument to remote mode to be able to control it class SerialInstrument: def __init__(self, COMport, timeout=2, baudrate=9600, EOL='\r\n', removeEOL=True, tsleep=0): self.serial = serial.Serial() self.serial.port = COMport self.serial.timeout = timeout self.serial.baudrate = baudrate self.EOL = EOL self.removeEOL = removeEOL self.tsleep = tsleep if not self.serial.is_open: self.serial.open() def write(self, command): self.serial.write((command + self.EOL).encode()) sleep(self.tsleep) def read(self): answer = self.serial.readline().decode() if self.removeEOL: answer = answer.rstrip(self.EOL) return answer def query(self, command): self.write(command) return self.read() def remote_mode(self): self.write('SYST:REM') def local_mode(self): self.write('SYST:LOC') def get_idn(self): return self.query('*IDN?') def get_error(self): return self.query('SYST:ERR?') def get_version(self): return self.query('SYST:VERS?') def beep(self): self.write('SYST:BEEP') def reset(self): self.write('*RST') def cls(self): # Clear status (clear errors) self.write('*CLS') def display_on(self): self.write('DISP ON') def display_off(self): self.write('DISP OFF') # Multimeter Hewlett Packard 34401A class HP34401A(SerialInstrument): def __init__(self, COMport, timeout=2, baudrate=9600, EOL='\r\n', removeEOL=True, tsleep=0.15): super().__init__(COMport, timeout, baudrate, EOL, removeEOL, tsleep) self.__modes = { 'VDC': ['CONF:VOLT:DC DEF, DEF', 'DC Voltage measurement'], 'VAC': ['CONF:VOLT:AC DEF, DEF', 'AC Voltage measurement'], 'IDC': ['CONF:CURR:DC DEF, DEF', 'DC Current measurement'], 'IAC': ['CONF:CURR:AC DEF, DEF', 'AC Current measurement'], 'R': ['CONF:RES DEF, DEF', '2-wire resistance measurement'], 'R4W': ['CONF:FRES DEF, DEF', '4-wire resistance measurement'], 'F': ['CONF:FREQ DEF, DEF', 'Frequency measurement'], 'T': ['CONF:PER DEF, DEF', 'Period measurement'] } def help_modes(self): for mode in self.__modes: comment = self.__modes[mode][1] print(mode + ': ' + comment) def meas(self, mode='VDC', num_of_samples=1): cmd_mode = self.__modes[mode][0] self.write(cmd_mode) cmd = 'SAMP:COUN ' + str(num_of_samples) self.write(cmd) self.write('READ?') sleep(0.4*num_of_samples) data_str = self.read() data = [] for str_value in data_str.split(','): if str_value: data.append(float(str_value)) if len(data) == 1: return data[0] else: return data def display_text(self, text): # Display has 12 characters # It is recommended to use uppercase self.write('DISP:TEXT "' + text[:12] + '"') def running_text(self, text): # Set self.tsleep time to change speed of running text # Recomended = 0.15 text = ' '*12 + text tstart = time() i = 0 text_len = len(text) while i <= text_len: self.display_text(text[i:]) i += 1 def display_clear(self): self.write('DISP:TEXT:CLE') # Power Supply BK Precision 9129B class BK9129B(SerialInstrument): def __init__(self, COMport, timeout=2, baudrate=9600, EOL='\r\n', removeEOL=True, tsleep=0): super().__init__(COMport, timeout, baudrate, EOL, removeEOL, tsleep) self.__voltages = [0, 0, 0] self.__currents = [0, 0, 0] self.__outputs = [0, 0, 0] self.__CH_selected = 0 def reset(self): self.write('*RST') self.__voltages = [0, 0, 0] self.__currents = [3.1, 3.1, 3.1] self.__outputs = [0, 0, 0] self.__CH_selected = 0 def __select_channel(self, CH_num): if self.__CH_selected != CH_num: self.write('INST:NSEL ' + str(CH_num)) self.__CH_selected = CH_num def __send_channel_command(self, channel, command, value): self.__select_channel(channel) self.write(command + ' ' + str(value)) if command == 'VOLT': self.__voltages[channel - 1] = value elif command == 'CURR': self.__currents[channel - 1] = value elif command == 'CHAN:OUTP': self.__outputs[channel - 1] = value def __meas_value(self, channel, value_str): measured = None data = '' if isinstance(channel, int): ch = 'CH' + str(channel) data = self.query('MEAS:' + value_str + '? ' + ch) if data: measured = float(data) return measured def meas_current(self, channel): return self.__meas_value(channel, 'CURR') def meas_voltage(self, channel): return self.__meas_value(channel, 'VOLT') def meas_power(self, channel): return self.__meas_value(channel, 'POW') def __meas_values(self, value_str): measured = [] data = self.query('MEAS:' + value_str + '? ALL') if data: measured = [float(i) for i in data.split(', ')] return measured def meas_currents(self): return self.__meas_values('CURR') def meas_voltages(self): return self.__meas_values('VOLT') def meas_powers(self): return self.__meas_values('POW') @property def voltage1(self): return self.__voltages[0] @voltage1.setter def voltage1(self, value): self.__send_channel_command(1, 'VOLT', value) @property def voltage2(self): return self.__voltages[1] @voltage2.setter def voltage2(self, value): self.__send_channel_command(2, 'VOLT', value) @property def voltage3(self): return self.__voltages[2] @voltage3.setter def voltage3(self, value): self.__send_channel_command(3, 'VOLT', value) @property def current1(self): return self.__currents[0] @current1.setter def current1(self, value): self.__send_channel_command(1, 'CURR', value) @property def current2(self): return self.__currents[1] @current2.setter def current2(self, value): self.__send_channel_command(2, 'CURR', value) @property def current3(self): return self.__currents[2] @current3.setter def current3(self, value): self.__send_channel_command(3, 'CURR', value) @property def output1(self): return self.__outputs[0] @output1.setter def output1(self, value): self.__send_channel_command(1, 'CHAN:OUTP', value) @property def output2(self): return self.__outputs[1] @output2.setter def output2(self, value): self.__send_channel_command(2, 'CHAN:OUTP', value) @property def output3(self): return self.__outputs[2] @output3.setter def output3(self, value): self.__send_channel_command(3, 'CHAN:OUTP', value) @property def voltages(self): return self.__voltages @voltages.setter def voltages(self, values): self.__voltages = values self.write('APP:VOLT ' + ','.join(str(value) for value in values)) @property def currents(self): return self.__currents @currents.setter def currents(self, values): self.__currents = values self.write('APP:CURR ' + ','.join(str(value) for value in values)) @property def outputs(self): return self.__outputs @outputs.setter def outputs(self, values): self.__outputs = values self.write('APP:OUT ' + ','.join(str(value) for value in values)) # Power Supply BK Precision 9201B class BK9201B(SerialInstrument): def __init__(self, COMport, timeout=2, baudrate=9600, EOL='\r\n', removeEOL=True, tsleep=0): super().__init__(COMport, timeout, baudrate, EOL, removeEOL, tsleep) self.__voltage = 0 self.__current = 0 self.__output = 0 def reset(self): self.write('*RST') self.__voltage = 0 self.__current = 10.1 self.__output = 0 def __meas_value(self, value_str): measured = None data = self.query('MEAS:' + value_str + '? ') if data: measured = float(data) return measured def meas_current(self): return self.__meas_value('CURR') def meas_voltage(self): return self.__meas_value('VOLT') def meas_power(self): return self.__meas_value('POW') @property def voltage(self): return self.__voltage @voltage.setter def voltage(self, value): self.write('VOLT ' + str(value)) self.__voltage = value @property def current(self): return self.__current @current.setter def current(self, value): self.write('CURR ' + str(value)) self.__current = value @property def output(self): return self.__output @output.setter def output(self, value): self.write('OUTP ' + str(value)) self.__output = value # Universal calibrator Digistant 4420-V001 class DIGISTANT4420(SerialInstrument): def __init__(self, COMport, timeout=2, baudrate=9600, EOL='\r\n', removeEOL=True, tsleep=0): super().__init__(COMport, timeout, baudrate, EOL, removeEOL, tsleep) self._stx = chr(2) # '\x02' - start of text self._eot = chr(4) # '\x04' - end of transmition self._etx = chr(3) # '\x03' - end of text self._enq = chr(5) # '\x05' - enquiry self._ack = chr(6) # '\x06' - acknowledge self._nak = chr(21) # '\x15' - negative acknowledge self._cr = chr(13) # '\x0d' = '\r' - carriage return self._lf = chr(10) # '\x0a' = '\n' - new line / line feed self._esc = chr(27) # '\x1b' - escape self._select = self._eot + '0000SR' + self._enq self._polling = self._eot + '0000PO' + self._enq def write(self, command): self.serial.write(self._select.encode()) sleep(self.tsleep) self.serial.write((self._stx + command + self.EOL + self._etx).encode()) sleep(self.tsleep) def read(self): self.serial.reset_input_buffer() self.serial.write(self._polling.encode()) sleep(self.tsleep) answer = self.serial.readline().decode() while len(answer) > 1 and not answer[0].isalnum(): answer = answer[1:] if not answer[0].isalnum(): answer = self.serial.readline().decode() while len(answer) > 1 and not answer[0].isalnum(): answer = answer[1:] if self.removeEOL: answer = answer.rstrip(self.EOL) return answer def query(self, command): self.write(command) return self.read() """ # Example code to test class: bk = BK9129B('COM5') bk.remote_mode() bk.voltages = [10, 5, 3] bk.currents = [2,1,0.2] bk.outputs = [1,1,0] bk.voltage1 = 12 print(bk.meas_voltage(1)) print(bk.meas_voltages()) """
Editor is loading...
Leave a Comment