forked from M-Labs/ionpak-thermostat
let pid control pwm
This commit is contained in:
parent
393c276bda
commit
42a9b89db1
|
@ -23,7 +23,8 @@ The scope of this setting is per TCP session.
|
|||
| `report` | Show current input |
|
||||
| `report mode` | Show current report mode |
|
||||
| `report mode <off or on>` | Set report mode |
|
||||
| `pwm <width> <total>` | Set PWM duty cycle to width / total |
|
||||
| `pwm <width> <total>` | Set PWM duty cycle to manual *width / total* |
|
||||
| `pwm pid` | Set PWM to be controlled by PID |
|
||||
| `pid target <value>` | |
|
||||
| `pid kp <value>` | |
|
||||
| `pid ki <value>` | |
|
||||
|
|
|
@ -64,6 +64,7 @@ impl fmt::Display for Error {
|
|||
pub enum ShowCommand {
|
||||
Input,
|
||||
Reporting,
|
||||
Pwm,
|
||||
Pid,
|
||||
}
|
||||
|
||||
|
@ -79,15 +80,21 @@ pub enum PidParameter {
|
|||
IntegralMax,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PwmMode {
|
||||
Manual {
|
||||
width: u32,
|
||||
total: u32,
|
||||
},
|
||||
Pid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Command {
|
||||
Quit,
|
||||
Show(ShowCommand),
|
||||
Reporting(bool),
|
||||
Pwm {
|
||||
width: u32,
|
||||
total: u32,
|
||||
},
|
||||
Pwm(PwmMode),
|
||||
Pid {
|
||||
parameter: PidParameter,
|
||||
value: f32,
|
||||
|
@ -147,9 +154,7 @@ fn report(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
}
|
||||
|
||||
/// `pwm <width> <total>` - Set pwm duty cycle
|
||||
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||
let (input, _) = tag("pwm")(input)?;
|
||||
let (input, _) = whitespace(input)?;
|
||||
fn pwm_manual(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||
let (input, width) = unsigned(input)?;
|
||||
let width = match width {
|
||||
Ok(width) => width,
|
||||
|
@ -161,7 +166,25 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||
Ok(total) => total,
|
||||
Err(e) => return Ok((input, Err(e.into()))),
|
||||
};
|
||||
Ok((input, Ok(Command::Pwm { width, total })))
|
||||
Ok((input, Ok(Command::Pwm(PwmMode::Manual { width, total }))))
|
||||
}
|
||||
|
||||
/// `pwm pid` - Set PWM to be controlled by PID
|
||||
fn pwm_pid(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||
value(Ok(Command::Pwm(PwmMode::Pid)), tag("pid"))(input)
|
||||
}
|
||||
|
||||
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||
let (input, _) = tag("pwm")(input)?;
|
||||
alt((
|
||||
preceded(
|
||||
whitespace,
|
||||
alt((
|
||||
pwm_pid,
|
||||
pwm_manual,
|
||||
))),
|
||||
|input| Ok((input, Ok(Command::Show(ShowCommand::Pwm))))
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn pid_parameter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||
|
|
|
@ -37,7 +37,7 @@ mod board;
|
|||
use self::board::{gpio::Gpio, systick::get_time};
|
||||
mod ethmac;
|
||||
mod command_parser;
|
||||
use command_parser::{Command, ShowCommand};
|
||||
use command_parser::{Command, ShowCommand, PwmMode};
|
||||
mod session;
|
||||
use self::session::{Session, SessionOutput};
|
||||
mod ad7172;
|
||||
|
@ -155,6 +155,8 @@ fn main() -> ! {
|
|||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
||||
|
||||
let mut pid = pid::Controller::new(DEFAULT_PID_PARAMETERS.clone());
|
||||
// Start with disengaged PID to let user setup parameters first
|
||||
let mut pid_enabled = false;
|
||||
|
||||
let mut hardware_addr = EthernetAddress(board::get_mac_address());
|
||||
if hardware_addr.is_multicast() {
|
||||
|
@ -214,8 +216,13 @@ fn main() -> ! {
|
|||
}).map(|channel| {
|
||||
let now = get_time();
|
||||
let data = adc.read_data().unwrap();
|
||||
report[usize::from(channel)] = Some((now, data));
|
||||
|
||||
if channel == 0 && pid_enabled {
|
||||
let width = pid.update(data as f32) as u32;
|
||||
board::set_timer_pwm(width as u32, 0xffff);
|
||||
}
|
||||
|
||||
report[usize::from(channel)] = Some((now, data));
|
||||
for (session, _) in sessions_handles.iter_mut() {
|
||||
session.set_report_pending(channel.into());
|
||||
}
|
||||
|
@ -270,9 +277,19 @@ fn main() -> ! {
|
|||
out!(integral_min);
|
||||
out!(integral_max);
|
||||
}
|
||||
Command::Pwm { width, total } => {
|
||||
Command::Show(ShowCommand::Pwm) => {
|
||||
let _ = writeln!(socket, "PWM: PID {}",
|
||||
if pid_enabled { "engaged" } else { "disengaged" }
|
||||
);
|
||||
}
|
||||
Command::Pwm(PwmMode::Manual { width, total }) => {
|
||||
pid_enabled = false;
|
||||
board::set_timer_pwm(width, total);
|
||||
let _ = writeln!(socket, "PWM duty cycle: {}/{}", width, total);
|
||||
let _ = writeln!(socket, "PWM duty cycle manually set to {}/{}", width, total);
|
||||
}
|
||||
Command::Pwm(PwmMode::Pid) => {
|
||||
pid_enabled = true;
|
||||
let _ = writeln!(socket, "PID enabled to control PWM");
|
||||
}
|
||||
Command::Pid { parameter, value } => {
|
||||
use command_parser::PidParameter::*;
|
||||
|
|
Loading…
Reference in New Issue