use embedded_hal::digital::OutputPin;
use syunit::*;
use crate::device::pwm::SoftwarePWM;
use crate::{Setup, Dismantle};
use crate::data::servo::ServoConst;
#[derive(Debug)]
pub struct Servo<P : OutputPin + Send> {
gamma : Gamma,
consts : ServoConst,
pwm : SoftwarePWM<P>
}
impl<P : OutputPin + Send + 'static> Servo<P> {
pub fn new(consts : ServoConst, pin : P) -> Self {
Self {
gamma: consts.default_pos(),
consts,
pwm: SoftwarePWM::new(pin)
}
}
pub fn consts(&self) -> &ServoConst {
&self.consts
}
pub fn start(&mut self) -> Result<(), crate::Error> {
self.pwm.set_period(self.consts.default_pulse(), self.consts.period_time());
Ok(())
}
pub fn gamma(&self) -> Gamma {
self.gamma
}
pub fn set_gamma(&mut self, gamma : Gamma) {
self.pwm.set_period(self.consts.pulse_for_angle(gamma), self.consts.period_time());
self.gamma = gamma
}
pub fn perc(&self) -> f32 {
self.gamma / self.consts.gamma_max
}
pub fn set_perc(&mut self, perc : f32) {
self.pwm.set_period(self.consts.pulse_for_factor(perc), self.consts.period_time());
self.gamma = self.consts.gamma_max * perc
}
pub fn default_pos(&mut self) {
self.pwm.set_period(self.consts.default_pulse(), self.consts.period_time())
}
pub fn endpoint_min(&mut self) {
self.set_perc(0.0)
}
pub fn endpoint_max(&mut self) {
self.set_perc(1.0)
}
pub fn stop(&mut self) -> Result<(), crate::Error> {
self.pwm.stop()
}
}
impl<P : OutputPin + Send + 'static> Setup for Servo<P> {
fn setup(&mut self) -> Result<(), crate::Error> {
self.start()
}
}
impl<P : OutputPin + Send + 'static> Dismantle for Servo<P> {
fn dismantle(&mut self) -> Result<(), crate::Error> {
self.stop()
}
}