-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPowerSupply.py
183 lines (153 loc) · 8.28 KB
/
PowerSupply.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import math, time, warnings
from enum import Enum
import numpy as np
from Instrument import *
class PowerSupply():
def __init__(self):
# TODO: capabilites doesn't address differen V/I ranges. For example the 6626A can do up to 50V and 2A, but has a max power of 50W and CANNOT do 40V@1A due to discrete voltage ranges
self.capabilites = {
'voltage_control': False,
'current_control': False,
'power_control': False,
'OVP': False,
'OCP': False,
'voltage_slew_rate_control': False,
'voltage_slew_rate_min': -math.inf,
'voltage_slew_rate_max': math.inf,
'min_voltage': -math.inf,
'max_voltage': math.inf,
'min_current': -math.inf,
'max_current': math.inf,
'min_power': -math.inf,
'max_power': math.inf
}
self.name_str = ""
self.soft_voltage_range = [-math.inf, math.inf]
self.soft_current_range = [-math.inf, math.inf]
self.soft_power_range = [-math.inf, math.inf]
def identify(self, implemented=False):
if not implemented:
raise NotImplementedError
def reset(self, implemented=False):
if not implemented:
raise NotImplementedError
def setState(self, state, implemented=False):
if type(state)!=bool:
if type(state) == int:
if not (int(state)==0 or int(state)==1):
raise TypeError
else:
raise TypeError
if not implemented:
raise NotImplementedError
def getState(self, implemented=False):
if not implemented:
raise NotImplementedError
def setVoltage(self, voltage, implemented=False):
if not self.capabilites['voltage_control']:
raise ExceededInstrumentCapabilitesError("Voltage control not supported")
if voltage < self.capabilites['min_voltage'] or voltage > self.capabilites['max_voltage']:
raise ExceededInstrumentCapabilitesError(f"Voltage setpoint of {voltage}V is out of supply limits of {self.capabilites['min_voltage']}V to {self.capabilites['max_voltage']}V")
if voltage < self.soft_voltage_range[0] or voltage > self.soft_voltage_range[1]:
raise ExceededInstrumentSoftLimitError(f"Voltage setpoint of {voltage}V is out soft voltage limits of {self.soft_voltage_range[0]}V to {self.soft_voltage_range[1]}V")
I = self.getCurrentSetpoint()
if voltage*I > self.capabilites['max_power']:
raise ExceededInstrumentCapabilitesError(f"Voltage setpoint of {voltage}V at a current setpoint of {I}A is too high for the rated power of {self.capabilites['max_power']}W")
# TODO: check that voltage set point is within negative power limit
if not implemented:
raise NotImplementedError
def getVoltage(self, implemented=False):
if not implemented:
raise NotImplementedError
def getVoltageSetpoint(self, implemented=False):
if not implemented:
raise NotImplementedError
def setCurrent(self, current, implemented=False):
if not self.capabilites['current_control']:
raise ExceededInstrumentCapabilitesError("Current control not supported")
if current < self.capabilites['min_current'] or current > self.capabilites['max_current']:
raise ExceededInstrumentCapabilitesError(f"Current setpoint of {current}A is out of supply limits of {self.capabilites['min_current']}A to {self.capabilites['max_current']}A")
if current < self.soft_current_range[0] or current > self.soft_current_range[1]:
raise ExceededInstrumentSoftLimitError(f"Current setpoint of {current}A is out soft current limits of {self.soft_current_range[0]}A to {self.soft_current_range[1]}A")
V = self.getVoltageSetpoint()
if current*V > self.capabilites['max_power']:
raise ExceededInstrumentCapabilitesError(f"Current setpoint of {current}A at a voltage setpoint of {V}V is too high for the rated power of {self.capabilites['max_power']}W")
# TODO: check that voltage set point is within negative power limit
if not implemented:
raise NotImplementedError
def getCurrent(self, implemented=False):
if not implemented:
raise NotImplementedError
def getCurrentSetpoint(self, implemented=False):
if not implemented:
raise NotImplementedError
def setPower(self, power, implemented=False):
if not self.capabilites['power_control']:
raise ExceededInstrumentCapabilitesError("Power control not supported")
if power < self.capabilites['min_power'] or power > self.capabilites['max_power']:
raise ExceededInstrumentCapabilitesError(f"Power setpoint of {power}W is out of supply limits of {self.capabilites['min_power']}W to {self.capabilites['max_power']}W")
if power < self.soft_power_range[0] or power > self.soft_power_range[1]:
raise ExceededInstrumentSoftLimitError(f"Power setpoint of {power}W is out soft power limits of {self.soft_power_range[0]}W to {self.soft_power_range[1]}W")
if not implemented:
raise NotImplementedError
def getPower(self, implemented=False):
if not implemented:
raise NotImplementedError
def getPowerSetpoint(self, implemented=False):
if not implemented:
raise NotImplementedError
def setVoltageSlewRate(self, slew_rate, implemented=False):
if not self.capabilites['voltage_slew_rate_control']:
raise ExceededInstrumentCapabilitesError("Voltage slew rate control not supported")
if slew_rate < self.capabilites['voltage_slew_rate_min'] or voltage > self.capabilites['voltage_slew_rate_max']:
raise ExceededInstrumentCapabilitesError(f"Voltage slew rate set point of {slew_rate} is out of supply limits of {self.capabilites['voltage_slew_rate_min']} to {self.capabilites['voltage_slew_rate_max']}")
if not implemented:
raise NotImplementedError
def getVoltageSlewRate(self, implemented=False):
if not implemented:
raise NotImplementedError
def getStatus(self, implemented=False):
if not implemented:
raise NotImplementedError
def sw_slewOutput(self, endVoltage, slewRate, startVoltage=None, stepsize=0.1):
raise Exception("NEED TO FIX THIS FUNCTION TO RESPECT COMMAND TIMING")
if slewRate < 0:
raise Exception(f"Slew rate \"{slewRate}\" V/s is not valid. Must be > 0.")
elif slewRate > 5:
warnings.warn("Slew rate is > 5 V/s. This will cause the output voltage to be stepped in large steps. Consider a lower slew rate")
if stepsize <= 0:
raise Exception("Step size must be > 0")
if stepsize > 0.25:
warnings.warn("Step size is > 0.25 s. This will cause the output voltage to be stepped in large steps. Consider a lower step size")
if startVoltage is not None:
pass
# defering validation to the individual set functions
# if startVoltage < 0:
# raise Exception("Start Voltage \"{}\" is not valid. Voltage set point must be > 0.".format(startVoltage))
# elif startVoltage > 50.5:
# raise Exception("Start Voltage \"{}\" is not valid. Max voltage is 50.5V".format(startVoltage))
else:
startVoltage=self.getVoltageSetpoint()
# defering validation to the individual set functions
# if endVoltage < 0:
# raise Exception("End Voltage \"{}\" is not valid. Voltage set point must be > 0.".format(endVoltage))
# elif endVoltage > 50.5:
# raise Exception("End Voltage \"{}\" is not valid. Max voltage is 50.5V".format(endVoltage))
if endVoltage < startVoltage:
stepsize = -stepsize
self.setVoltage(startVoltage)
start = time.time()
count = 0
for V in np.arange(startVoltage, endVoltage, slewRate*stepsize):
self.setVoltage(V)
count += 1
while time.time() < start+(count+1)*stepsize:
pass
self.setVoltage(endVoltage)
class psu_mode(Enum):
OFF = 0
CV = 1
CC = 2
OVP = 3
OCP = 4
FAULT = 5