forked from M-Labs/thermostat
pwm -> output
Current limit pins are driven by PWM inputs to the MAX1968 driver, but this is an implementation detail, and should not be exposed in the form of the command interface. Rename it to "output" in all instances. See M-Labs/thermostat#62 (comment).
This commit is contained in:
parent
c6040899dd
commit
9ea1492b5f
26
README.md
26
README.md
@ -99,12 +99,12 @@ formatted as line-delimited JSON.
|
|||||||
| `report` | Show current input |
|
| `report` | Show current input |
|
||||||
| `report mode` | Show current report mode |
|
| `report mode` | Show current report mode |
|
||||||
| `report mode <off/on>` | Set report mode |
|
| `report mode <off/on>` | Set report mode |
|
||||||
| `pwm` | Show current PWM settings |
|
| `output` | Show current output settings |
|
||||||
| `pwm <0/1> max_i_pos <amp>` | Set maximum positive output current |
|
| `output <0/1> max_i_pos <amp>` | Set maximum positive output current |
|
||||||
| `pwm <0/1> max_i_neg <amp>` | Set maximum negative output current |
|
| `output <0/1> max_i_neg <amp>` | Set maximum negative output current |
|
||||||
| `pwm <0/1> max_v <volt>` | Set maximum output voltage |
|
| `output <0/1> max_v <volt>` | Set maximum output voltage |
|
||||||
| `pwm <0/1> i_set <amp>` | Disengage PID, set fixed output current |
|
| `output <0/1> i_set <amp>` | Disengage PID, set fixed output current |
|
||||||
| `pwm <0/1> pid` | Let output current to be controlled by the PID |
|
| `output <0/1> pid` | Let output current to be controlled by the PID |
|
||||||
| `center <0/1> <volt>` | Set the MAX1968 0A-centerpoint to the specified fixed voltage |
|
| `center <0/1> <volt>` | Set the MAX1968 0A-centerpoint to the specified fixed voltage |
|
||||||
| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF |
|
| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF |
|
||||||
| `pid` | Show PID configuration |
|
| `pid` | Show PID configuration |
|
||||||
@ -193,7 +193,7 @@ Testing heat flow direction with a low set current is recommended before install
|
|||||||
Each of the MAX1968 TEC driver has analog/PWM inputs for setting
|
Each of the MAX1968 TEC driver has analog/PWM inputs for setting
|
||||||
output limits.
|
output limits.
|
||||||
|
|
||||||
Use the `pwm` command to see current settings and maximum values.
|
Use the `output` command to see current settings and maximum values.
|
||||||
|
|
||||||
| Limit | Unit | Description |
|
| Limit | Unit | Description |
|
||||||
| --- | :---: | --- |
|
| --- | :---: | --- |
|
||||||
@ -204,28 +204,28 @@ Use the `pwm` command to see current settings and maximum values.
|
|||||||
|
|
||||||
Example: set the maximum voltage of channel 0 to 1.5 V.
|
Example: set the maximum voltage of channel 0 to 1.5 V.
|
||||||
```
|
```
|
||||||
pwm 0 max_v 1.5
|
output 0 max_v 1.5
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: set the maximum negative current of channel 0 to -3 A.
|
Example: set the maximum negative current of channel 0 to -3 A.
|
||||||
```
|
```
|
||||||
pwm 0 max_i_neg 3
|
output 0 max_i_neg 3
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: set the maximum positive current of channel 1 to 3 A.
|
Example: set the maximum positive current of channel 1 to 3 A.
|
||||||
```
|
```
|
||||||
pwm 0 max_i_pos 3
|
output 0 max_i_pos 3
|
||||||
```
|
```
|
||||||
|
|
||||||
### Open-loop mode
|
### Open-loop mode
|
||||||
|
|
||||||
To manually control TEC output current, omit the limit parameter of
|
To manually control TEC output current, omit the limit parameter of
|
||||||
the `pwm` command. Doing so will disengage the PID control for that
|
the `output` command. Doing so will disengage the PID control for that
|
||||||
channel.
|
channel.
|
||||||
|
|
||||||
Example: set output current of channel 0 to 0 A.
|
Example: set output current of channel 0 to 0 A.
|
||||||
```
|
```
|
||||||
pwm 0 i_set 0
|
output 0 i_set 0
|
||||||
```
|
```
|
||||||
|
|
||||||
## PID-stabilized temperature control
|
## PID-stabilized temperature control
|
||||||
@ -238,7 +238,7 @@ pid 0 target 20
|
|||||||
Enter closed-loop mode by switching control of the TEC output current
|
Enter closed-loop mode by switching control of the TEC output current
|
||||||
of channel 0 to the PID algorithm:
|
of channel 0 to the PID algorithm:
|
||||||
```
|
```
|
||||||
pwm 0 pid
|
output 0 pid
|
||||||
```
|
```
|
||||||
|
|
||||||
## LED indicators
|
## LED indicators
|
||||||
|
@ -253,9 +253,9 @@ def main():
|
|||||||
|
|
||||||
tuner_out = tuner.output()
|
tuner_out = tuner.output()
|
||||||
|
|
||||||
tec.set_param("pwm", channel, "i_set", tuner_out)
|
tec.set_param("output", channel, "i_set", tuner_out)
|
||||||
|
|
||||||
tec.set_param("pwm", channel, "i_set", 0)
|
tec.set_param("output", channel, "i_set", 0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -2,9 +2,9 @@ from pytec.client import Client
|
|||||||
|
|
||||||
tec = Client() #(host="localhost", port=6667)
|
tec = Client() #(host="localhost", port=6667)
|
||||||
tec.set_param("s-h", 1, "t0", 20)
|
tec.set_param("s-h", 1, "t0", 20)
|
||||||
print(tec.get_pwm())
|
print(tec.get_output())
|
||||||
print(tec.get_pid())
|
print(tec.get_pid())
|
||||||
print(tec.get_pwm())
|
print(tec.get_output())
|
||||||
print(tec.get_postfilter())
|
print(tec.get_postfilter())
|
||||||
print(tec.get_steinhart_hart())
|
print(tec.get_steinhart_hart())
|
||||||
for data in tec.report_mode():
|
for data in tec.report_mode():
|
||||||
|
@ -12,11 +12,11 @@ class Client:
|
|||||||
self._check_zero_limits()
|
self._check_zero_limits()
|
||||||
|
|
||||||
def _check_zero_limits(self):
|
def _check_zero_limits(self):
|
||||||
pwm_report = self.get_pwm()
|
output_report = self.get_output()
|
||||||
for pwm_channel in pwm_report:
|
for output_channel in output_report:
|
||||||
for limit in ["max_i_neg", "max_i_pos", "max_v"]:
|
for limit in ["max_i_neg", "max_i_pos", "max_v"]:
|
||||||
if pwm_channel[limit]["value"] == 0.0:
|
if output_channel[limit]["value"] == 0.0:
|
||||||
logging.warning("`{}` limit is set to zero on channel {}".format(limit, pwm_channel["channel"]))
|
logging.warning("`{}` limit is set to zero on channel {}".format(limit, output_channel["channel"]))
|
||||||
|
|
||||||
def _read_line(self):
|
def _read_line(self):
|
||||||
# read more lines
|
# read more lines
|
||||||
@ -46,8 +46,8 @@ class Client:
|
|||||||
result[int(item["channel"])] = item
|
result[int(item["channel"])] = item
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_pwm(self):
|
def get_output(self):
|
||||||
"""Retrieve PWM limits for the TEC
|
"""Retrieve output limits for the TEC
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
[{'channel': 0,
|
[{'channel': 0,
|
||||||
@ -64,7 +64,7 @@ class Client:
|
|||||||
'max_i_pos': {'max': 3.0, 'value': 3.0}}
|
'max_i_pos': {'max': 3.0, 'value': 3.0}}
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
return self._get_conf("pwm")
|
return self._get_conf("output")
|
||||||
|
|
||||||
def get_pid(self):
|
def get_pid(self):
|
||||||
"""Retrieve PID control state
|
"""Retrieve PID control state
|
||||||
@ -141,7 +141,7 @@ class Client:
|
|||||||
"""Set configuration parameters
|
"""Set configuration parameters
|
||||||
|
|
||||||
Examples::
|
Examples::
|
||||||
tec.set_param("pwm", 0, "max_v", 2.0)
|
tec.set_param("output", 0, "max_v", 2.0)
|
||||||
tec.set_param("pid", 1, "output_max", 2.5)
|
tec.set_param("pid", 1, "output_max", 2.5)
|
||||||
tec.set_param("s-h", 0, "t0", 20.0)
|
tec.set_param("s-h", 0, "t0", 20.0)
|
||||||
tec.set_param("center", 0, "vref")
|
tec.set_param("center", 0, "vref")
|
||||||
@ -158,7 +158,7 @@ class Client:
|
|||||||
def power_up(self, channel, target):
|
def power_up(self, channel, target):
|
||||||
"""Start closed-loop mode"""
|
"""Start closed-loop mode"""
|
||||||
self.set_param("pid", channel, "target", value=target)
|
self.set_param("pid", channel, "target", value=target)
|
||||||
self.set_param("pwm", channel, "pid")
|
self.set_param("output", channel, "pid")
|
||||||
|
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
"""Save current configuration to EEPROM"""
|
"""Save current configuration to EEPROM"""
|
||||||
|
@ -514,8 +514,8 @@ impl Channels {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pwm_summary(&mut self, channel: usize) -> PwmSummary {
|
fn output_summary(&mut self, channel: usize) -> OutputSummary {
|
||||||
PwmSummary {
|
OutputSummary {
|
||||||
channel,
|
channel,
|
||||||
center: CenterPointJson(self.channel_state(channel).center.clone()),
|
center: CenterPointJson(self.channel_state(channel).center.clone()),
|
||||||
i_set: (self.get_i(channel), MAX_TEC_I).into(),
|
i_set: (self.get_i(channel), MAX_TEC_I).into(),
|
||||||
@ -525,10 +525,10 @@ impl Channels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pwm_summaries_json(&mut self) -> Result<JsonBuffer, serde_json_core::ser::Error> {
|
pub fn output_summaries_json(&mut self) -> Result<JsonBuffer, serde_json_core::ser::Error> {
|
||||||
let mut summaries = Vec::<_, U2>::new();
|
let mut summaries = Vec::<_, U2>::new();
|
||||||
for channel in 0..CHANNELS {
|
for channel in 0..CHANNELS {
|
||||||
let _ = summaries.push(self.pwm_summary(channel));
|
let _ = summaries.push(self.output_summary(channel));
|
||||||
}
|
}
|
||||||
serde_json_core::to_vec(&summaries)
|
serde_json_core::to_vec(&summaries)
|
||||||
}
|
}
|
||||||
@ -616,7 +616,7 @@ impl<T: Serialize> From<(T, T)> for PwmSummaryField<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct PwmSummary {
|
pub struct OutputSummary {
|
||||||
channel: usize,
|
channel: usize,
|
||||||
center: CenterPointJson,
|
center: CenterPointJson,
|
||||||
i_set: PwmSummaryField<ElectricCurrent>,
|
i_set: PwmSummaryField<ElectricCurrent>,
|
||||||
|
@ -126,7 +126,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn show_pwm(socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
fn show_pwm(socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
match channels.pwm_summaries_json() {
|
match channels.output_summaries_json() {
|
||||||
Ok(buf) => {
|
Ok(buf) => {
|
||||||
send_line(socket, &buf);
|
send_line(socket, &buf);
|
||||||
}
|
}
|
||||||
@ -419,12 +419,12 @@ impl Handler {
|
|||||||
Command::Show(ShowCommand::Reporting) => Handler::show_report_mode(socket, session),
|
Command::Show(ShowCommand::Reporting) => Handler::show_report_mode(socket, session),
|
||||||
Command::Show(ShowCommand::Input) => Handler::show_report(socket, channels),
|
Command::Show(ShowCommand::Input) => Handler::show_report(socket, channels),
|
||||||
Command::Show(ShowCommand::Pid) => Handler::show_pid(socket, channels),
|
Command::Show(ShowCommand::Pid) => Handler::show_pid(socket, channels),
|
||||||
Command::Show(ShowCommand::Pwm) => Handler::show_pwm(socket, channels),
|
Command::Show(ShowCommand::Output) => Handler::show_pwm(socket, channels),
|
||||||
Command::Show(ShowCommand::SteinhartHart) => Handler::show_steinhart_hart(socket, channels),
|
Command::Show(ShowCommand::SteinhartHart) => Handler::show_steinhart_hart(socket, channels),
|
||||||
Command::Show(ShowCommand::PostFilter) => Handler::show_post_filter(socket, channels),
|
Command::Show(ShowCommand::PostFilter) => Handler::show_post_filter(socket, channels),
|
||||||
Command::Show(ShowCommand::Ipv4) => Handler::show_ipv4(socket, ipv4_config),
|
Command::Show(ShowCommand::Ipv4) => Handler::show_ipv4(socket, ipv4_config),
|
||||||
Command::PwmPid { channel } => Handler::engage_pid(socket, channels, channel),
|
Command::OutputPid { channel } => Handler::engage_pid(socket, channels, channel),
|
||||||
Command::Pwm { channel, pin, value } => Handler::set_pwm(socket, channels, channel, pin, value),
|
Command::Output { channel, pin, value } => Handler::set_pwm(socket, channels, channel, pin, value),
|
||||||
Command::CenterPoint { channel, center } => Handler::set_center_point(socket, channels, channel, center),
|
Command::CenterPoint { channel, center } => Handler::set_center_point(socket, channels, channel, center),
|
||||||
Command::Pid { channel, parameter, value } => Handler::set_pid(socket, channels, channel, parameter, value),
|
Command::Pid { channel, parameter, value } => Handler::set_pid(socket, channels, channel, parameter, value),
|
||||||
Command::SteinhartHart { channel, parameter, value } => Handler::set_steinhart_hart(socket, channels, channel, parameter, value),
|
Command::SteinhartHart { channel, parameter, value } => Handler::set_steinhart_hart(socket, channels, channel, parameter, value),
|
||||||
|
@ -97,7 +97,7 @@ pub struct Ipv4Config {
|
|||||||
pub enum ShowCommand {
|
pub enum ShowCommand {
|
||||||
Input,
|
Input,
|
||||||
Reporting,
|
Reporting,
|
||||||
Pwm,
|
Output,
|
||||||
Pid,
|
Pid,
|
||||||
SteinhartHart,
|
SteinhartHart,
|
||||||
PostFilter,
|
PostFilter,
|
||||||
@ -150,13 +150,13 @@ pub enum Command {
|
|||||||
Show(ShowCommand),
|
Show(ShowCommand),
|
||||||
Reporting(bool),
|
Reporting(bool),
|
||||||
/// PWM parameter setting
|
/// PWM parameter setting
|
||||||
Pwm {
|
Output {
|
||||||
channel: usize,
|
channel: usize,
|
||||||
pin: PwmPin,
|
pin: PwmPin,
|
||||||
value: f64,
|
value: f64,
|
||||||
},
|
},
|
||||||
/// Enable PID control for `i_set`
|
/// Enable PID control for `i_set`
|
||||||
PwmPid {
|
OutputPid {
|
||||||
channel: usize,
|
channel: usize,
|
||||||
},
|
},
|
||||||
CenterPoint {
|
CenterPoint {
|
||||||
@ -316,13 +316,13 @@ fn pwm_setup(input: &[u8]) -> IResult<&[u8], Result<(PwmPin, f64), Error>> {
|
|||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `pwm <0-1> pid` - Set PWM to be controlled by PID
|
/// `output <0-1> pid` - Set output to be controlled by PID
|
||||||
fn pwm_pid(input: &[u8]) -> IResult<&[u8], ()> {
|
fn output_pid(input: &[u8]) -> IResult<&[u8], ()> {
|
||||||
value((), tag("pid"))(input)
|
value((), tag("pid"))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
fn output(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
let (input, _) = tag("pwm")(input)?;
|
let (input, _) = tag("output")(input)?;
|
||||||
alt((
|
alt((
|
||||||
|input| {
|
|input| {
|
||||||
let (input, _) = whitespace(input)?;
|
let (input, _) = whitespace(input)?;
|
||||||
@ -330,14 +330,14 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||||||
let (input, _) = whitespace(input)?;
|
let (input, _) = whitespace(input)?;
|
||||||
let (input, result) = alt((
|
let (input, result) = alt((
|
||||||
|input| {
|
|input| {
|
||||||
let (input, ()) = pwm_pid(input)?;
|
let (input, ()) = output_pid(input)?;
|
||||||
Ok((input, Ok(Command::PwmPid { channel })))
|
Ok((input, Ok(Command::OutputPid { channel })))
|
||||||
},
|
},
|
||||||
|input| {
|
|input| {
|
||||||
let (input, config) = pwm_setup(input)?;
|
let (input, config) = pwm_setup(input)?;
|
||||||
match config {
|
match config {
|
||||||
Ok((pin, value)) =>
|
Ok((pin, value)) =>
|
||||||
Ok((input, Ok(Command::Pwm { channel, pin, value }))),
|
Ok((input, Ok(Command::Output { channel, pin, value }))),
|
||||||
Err(e) =>
|
Err(e) =>
|
||||||
Ok((input, Err(e))),
|
Ok((input, Err(e))),
|
||||||
}
|
}
|
||||||
@ -346,7 +346,7 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||||||
end(input)?;
|
end(input)?;
|
||||||
Ok((input, result))
|
Ok((input, result))
|
||||||
},
|
},
|
||||||
value(Ok(Command::Show(ShowCommand::Pwm)), end)
|
value(Ok(Command::Show(ShowCommand::Output)), end)
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,7 +591,7 @@ fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||||||
value(Ok(Command::Reset), tag("reset")),
|
value(Ok(Command::Reset), tag("reset")),
|
||||||
ipv4,
|
ipv4,
|
||||||
map(report, Ok),
|
map(report, Ok),
|
||||||
pwm,
|
output,
|
||||||
center_point,
|
center_point,
|
||||||
pid,
|
pid,
|
||||||
steinhart_hart,
|
steinhart_hart,
|
||||||
@ -702,8 +702,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_pwm_i_set() {
|
fn parse_pwm_i_set() {
|
||||||
let command = Command::parse(b"pwm 1 i_set 16383");
|
let command = Command::parse(b"output 1 i_set 16383");
|
||||||
assert_eq!(command, Ok(Command::Pwm {
|
assert_eq!(command, Ok(Command::Output {
|
||||||
channel: 1,
|
channel: 1,
|
||||||
pin: PwmPin::ISet,
|
pin: PwmPin::ISet,
|
||||||
value: 16383.0,
|
value: 16383.0,
|
||||||
@ -712,16 +712,16 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_pwm_pid() {
|
fn parse_pwm_pid() {
|
||||||
let command = Command::parse(b"pwm 0 pid");
|
let command = Command::parse(b"output 0 pid");
|
||||||
assert_eq!(command, Ok(Command::PwmPid {
|
assert_eq!(command, Ok(Command::OutputPid {
|
||||||
channel: 0,
|
channel: 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_pwm_max_i_pos() {
|
fn parse_pwm_max_i_pos() {
|
||||||
let command = Command::parse(b"pwm 0 max_i_pos 7");
|
let command = Command::parse(b"output 0 max_i_pos 7");
|
||||||
assert_eq!(command, Ok(Command::Pwm {
|
assert_eq!(command, Ok(Command::Output {
|
||||||
channel: 0,
|
channel: 0,
|
||||||
pin: PwmPin::MaxIPos,
|
pin: PwmPin::MaxIPos,
|
||||||
value: 7.0,
|
value: 7.0,
|
||||||
@ -730,8 +730,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_pwm_max_i_neg() {
|
fn parse_pwm_max_i_neg() {
|
||||||
let command = Command::parse(b"pwm 0 max_i_neg 128");
|
let command = Command::parse(b"output 0 max_i_neg 128");
|
||||||
assert_eq!(command, Ok(Command::Pwm {
|
assert_eq!(command, Ok(Command::Output {
|
||||||
channel: 0,
|
channel: 0,
|
||||||
pin: PwmPin::MaxINeg,
|
pin: PwmPin::MaxINeg,
|
||||||
value: 128.0,
|
value: 128.0,
|
||||||
@ -740,8 +740,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_pwm_max_v() {
|
fn parse_pwm_max_v() {
|
||||||
let command = Command::parse(b"pwm 0 max_v 32768");
|
let command = Command::parse(b"output 0 max_v 32768");
|
||||||
assert_eq!(command, Ok(Command::Pwm {
|
assert_eq!(command, Ok(Command::Output {
|
||||||
channel: 0,
|
channel: 0,
|
||||||
pin: PwmPin::MaxV,
|
pin: PwmPin::MaxV,
|
||||||
value: 32768.0,
|
value: 32768.0,
|
||||||
|
Loading…
Reference in New Issue
Block a user