|
1
|
|
|
# -*- coding: utf-8 -*- |
|
2
|
|
|
""" |
|
3
|
|
|
This module controls the Stanford Instruments CTC100 temperature |
|
4
|
|
|
controller (also rebranded as CryoVac TIC500, etc). |
|
5
|
|
|
|
|
6
|
|
|
Qudi is free software: you can redistribute it and/or modify |
|
7
|
|
|
it under the terms of the GNU General Public License as published by |
|
8
|
|
|
the Free Software Foundation, either version 3 of the License, or |
|
9
|
|
|
(at your option) any later version. |
|
10
|
|
|
|
|
11
|
|
|
Qudi is distributed in the hope that it will be useful, |
|
12
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14
|
|
|
GNU General Public License for more details. |
|
15
|
|
|
|
|
16
|
|
|
You should have received a copy of the GNU General Public License |
|
17
|
|
|
along with Qudi. If not, see <http://www.gnu.org/licenses/>. |
|
18
|
|
|
|
|
19
|
|
|
Copyright (c) the Qudi Developers. See the COPYRIGHT.txt file at the |
|
20
|
|
|
top-level directory of this distribution and at <https://github.com/Ulm-IQO/qudi/> |
|
21
|
|
|
""" |
|
22
|
|
|
|
|
23
|
|
|
from core.base import Base |
|
24
|
|
|
import visa |
|
25
|
|
|
|
|
26
|
|
|
class CTC100(Base): |
|
27
|
|
|
""" |
|
28
|
|
|
This module implements communication with the Edwards turbopump and |
|
29
|
|
|
vacuum equipment. |
|
30
|
|
|
""" |
|
31
|
|
|
_modclass = 'ctc100' |
|
32
|
|
|
_modtype = 'hardware' |
|
33
|
|
|
|
|
34
|
|
|
# connectors |
|
35
|
|
|
_out = {'ctc': 'CTC'} |
|
36
|
|
|
|
|
37
|
|
|
def on_activate(self, e): |
|
38
|
|
|
config = self.getConfiguration() |
|
39
|
|
|
self.connect(config['interface']) |
|
40
|
|
|
|
|
41
|
|
|
def on_deactivate(self, e): |
|
42
|
|
|
self.disconnect() |
|
43
|
|
|
|
|
44
|
|
|
def connect(self, interface): |
|
45
|
|
|
""" Connect to Instrument. |
|
46
|
|
|
|
|
47
|
|
|
@param str interface: visa interface identifier |
|
48
|
|
|
|
|
49
|
|
|
@return bool: connection success |
|
50
|
|
|
""" |
|
51
|
|
|
try: |
|
52
|
|
|
self.rm = visa.ResourceManager() |
|
53
|
|
|
self.inst = self.rm.open_resource(interface, baud_rate=9600, term_chars='\n', send_end=True) |
|
54
|
|
|
except visa.VisaIOError as e: |
|
55
|
|
|
self.log.exception("") |
|
56
|
|
|
return False |
|
57
|
|
|
else: |
|
58
|
|
|
return True |
|
59
|
|
|
|
|
60
|
|
|
def disconnect(self): |
|
61
|
|
|
""" |
|
62
|
|
|
Close the connection to the instrument. |
|
63
|
|
|
""" |
|
64
|
|
|
self.inst.close() |
|
65
|
|
|
self.rm.close() |
|
66
|
|
|
|
|
67
|
|
|
def get_channel_names(self): |
|
68
|
|
|
return self.inst.ask('getOutputNames?').split(', ') |
|
69
|
|
|
|
|
70
|
|
|
def is_channel_selected(self, channel): |
|
71
|
|
|
return self.inst.ask(channel.replace(" ", "") + '.selected?' ).split(' = ')[-1] == 'On' |
|
72
|
|
|
|
|
73
|
|
|
def is_output_on(self): |
|
74
|
|
|
result = self.inst.ask('OutputEnable?').split()[2] |
|
75
|
|
|
return result == 'On' |
|
76
|
|
|
|
|
77
|
|
|
def get_temp_by_name(self, name): |
|
78
|
|
|
return self.inst.ask_for_values('{}.value?'.format(name))[0] |
|
79
|
|
|
|
|
80
|
|
|
def get_all_outputs(self): |
|
81
|
|
|
names = self.get_channel_names() |
|
82
|
|
|
raw = self.inst.ask('getOutputs?').split(', ') |
|
83
|
|
|
values = [] |
|
84
|
|
|
for substr in raw: |
|
85
|
|
|
values.append(float(substr)) |
|
86
|
|
|
return dict(zip(names, values)) |
|
87
|
|
|
|
|
88
|
|
|
def get_selected_channels(self): |
|
89
|
|
|
names = self.get_channel_names() |
|
90
|
|
|
values = [] |
|
91
|
|
|
for channel in names: |
|
92
|
|
|
values.append(self.is_channel_selected(channel)) |
|
93
|
|
|
return dict(zip(names, values)) |
|
94
|
|
|
|
|
95
|
|
|
def enable_output(self): |
|
96
|
|
|
if self.is_output_on(): |
|
97
|
|
|
return True |
|
98
|
|
|
else: |
|
99
|
|
|
result = self.inst.ask('OutputEnable = On').split()[2] |
|
100
|
|
|
return result == 'On' |
|
101
|
|
|
|
|
102
|
|
|
def disable_output(self): |
|
103
|
|
|
if self.is_output_on(): |
|
104
|
|
|
result = self.inst.ask('OutputEnable = Off').split()[2] |
|
105
|
|
|
return result == 'Off' |
|
106
|
|
|
else: |
|
107
|
|
|
return True |
|
108
|
|
|
|
|
109
|
|
|
def get_setpoint(self, channel): |
|
110
|
|
|
return self.inst.ask_for_values('{}.PID.setpoint?'.format(channel))[0] |
|
111
|
|
|
|
|
112
|
|
|
def set_setpoint(self, channel, setpoint): |
|
113
|
|
|
return self.inst.ask_for_values('{}.PID.setpoint = {}'.format(channel, setpoint))[0] |
|
114
|
|
|
|
|
115
|
|
|
def get_pid_mode(self, channel): |
|
116
|
|
|
return self.inst.ask('{}.PID.Mode?'.format(channel)).split(' = ')[1] |
|
117
|
|
|
|
|
118
|
|
|
def set_pid_mode(self, channel, mode): |
|
119
|
|
|
return self.inst.ask('{}.PID.Mode = {}'.format(channel, mode)).split(' = ')[1] |
|
120
|
|
|
|
|
121
|
|
|
def channel_off(self, channel): |
|
122
|
|
|
return self.inst.ask('{}.Off'.format(channel)).split(' = ')[1] |
|
123
|
|
|
|
|
124
|
|
|
def get_value(self, channel): |
|
125
|
|
|
try: |
|
126
|
|
|
return self.inst.ask_for_values('{}.Value?'.format(channel))[0] |
|
127
|
|
|
except: |
|
128
|
|
|
return NonNonee |
|
129
|
|
|
|
|
130
|
|
|
def set_value(self, channel, value): |
|
131
|
|
|
return self.inst.ask_for_values('{}.Value = {}'.format(channel, value))[0] |
|
132
|
|
|
|
|
133
|
|
|
|