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` | Show current input |
|
||||||
| `report mode` | Show current report mode |
|
| `report mode` | Show current report mode |
|
||||||
| `report mode <off or on>` | Set 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 target <value>` | |
|
||||||
| `pid kp <value>` | |
|
| `pid kp <value>` | |
|
||||||
| `pid ki <value>` | |
|
| `pid ki <value>` | |
|
||||||
|
@ -64,6 +64,7 @@ impl fmt::Display for Error {
|
|||||||
pub enum ShowCommand {
|
pub enum ShowCommand {
|
||||||
Input,
|
Input,
|
||||||
Reporting,
|
Reporting,
|
||||||
|
Pwm,
|
||||||
Pid,
|
Pid,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,15 +80,21 @@ pub enum PidParameter {
|
|||||||
IntegralMax,
|
IntegralMax,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum PwmMode {
|
||||||
|
Manual {
|
||||||
|
width: u32,
|
||||||
|
total: u32,
|
||||||
|
},
|
||||||
|
Pid,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Quit,
|
Quit,
|
||||||
Show(ShowCommand),
|
Show(ShowCommand),
|
||||||
Reporting(bool),
|
Reporting(bool),
|
||||||
Pwm {
|
Pwm(PwmMode),
|
||||||
width: u32,
|
|
||||||
total: u32,
|
|
||||||
},
|
|
||||||
Pid {
|
Pid {
|
||||||
parameter: PidParameter,
|
parameter: PidParameter,
|
||||||
value: f32,
|
value: f32,
|
||||||
@ -147,9 +154,7 @@ fn report(input: &[u8]) -> IResult<&[u8], Command> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `pwm <width> <total>` - Set pwm duty cycle
|
/// `pwm <width> <total>` - Set pwm duty cycle
|
||||||
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
fn pwm_manual(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
let (input, _) = tag("pwm")(input)?;
|
|
||||||
let (input, _) = whitespace(input)?;
|
|
||||||
let (input, width) = unsigned(input)?;
|
let (input, width) = unsigned(input)?;
|
||||||
let width = match width {
|
let width = match width {
|
||||||
Ok(width) => width,
|
Ok(width) => width,
|
||||||
@ -161,7 +166,25 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||||||
Ok(total) => total,
|
Ok(total) => total,
|
||||||
Err(e) => return Ok((input, Err(e.into()))),
|
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>> {
|
fn pid_parameter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
|
@ -37,7 +37,7 @@ mod board;
|
|||||||
use self::board::{gpio::Gpio, systick::get_time};
|
use self::board::{gpio::Gpio, systick::get_time};
|
||||||
mod ethmac;
|
mod ethmac;
|
||||||
mod command_parser;
|
mod command_parser;
|
||||||
use command_parser::{Command, ShowCommand};
|
use command_parser::{Command, ShowCommand, PwmMode};
|
||||||
mod session;
|
mod session;
|
||||||
use self::session::{Session, SessionOutput};
|
use self::session::{Session, SessionOutput};
|
||||||
mod ad7172;
|
mod ad7172;
|
||||||
@ -155,6 +155,8 @@ fn main() -> ! {
|
|||||||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
||||||
|
|
||||||
let mut pid = pid::Controller::new(DEFAULT_PID_PARAMETERS.clone());
|
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());
|
let mut hardware_addr = EthernetAddress(board::get_mac_address());
|
||||||
if hardware_addr.is_multicast() {
|
if hardware_addr.is_multicast() {
|
||||||
@ -214,8 +216,13 @@ fn main() -> ! {
|
|||||||
}).map(|channel| {
|
}).map(|channel| {
|
||||||
let now = get_time();
|
let now = get_time();
|
||||||
let data = adc.read_data().unwrap();
|
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() {
|
for (session, _) in sessions_handles.iter_mut() {
|
||||||
session.set_report_pending(channel.into());
|
session.set_report_pending(channel.into());
|
||||||
}
|
}
|
||||||
@ -270,9 +277,19 @@ fn main() -> ! {
|
|||||||
out!(integral_min);
|
out!(integral_min);
|
||||||
out!(integral_max);
|
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);
|
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 } => {
|
Command::Pid { parameter, value } => {
|
||||||
use command_parser::PidParameter::*;
|
use command_parser::PidParameter::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user