feat: ADC 采样改为子线程执行,并增加异常时的蜂鸣器报警。

This commit is contained in:
Ivan Li 2022-05-08 14:48:22 +08:00
parent de84c85190
commit c5d382fafe
3 changed files with 61 additions and 15 deletions

View File

@ -11,6 +11,8 @@ type LedcChannel<P, T, C> = Channel<C, T, Timer<T>, P>;
pub struct Beep<P: OutputPin, T: ledc::HwTimer, C: ledc::HwChannel> {
state: bool,
stopped: bool,
beat: u8,
ringtone: ringtone::Type,
channel: LedcChannel<P, T, C>,
}
@ -20,6 +22,8 @@ impl<P: OutputPin, T: ledc::HwTimer, C: ledc::HwChannel> Beep<P, T, C> {
state: false,
stopped: false,
channel: Self::init_channel(pin, timer, channel)?,
beat: 0,
ringtone: ringtone::SILENCE,
});
}
@ -41,16 +45,40 @@ impl<P: OutputPin, T: ledc::HwTimer, C: ledc::HwChannel> Beep<P, T, C> {
}
}
pub fn play(&mut self) {
pub fn play(&mut self, rx: &mut std::sync::mpsc::Receiver<ringtone::Type>) {
loop {
if self.stopped {
break;
let curr_ringtone = rx.try_recv().unwrap_or_else(|_| self.ringtone);
if !curr_ringtone.eq(&mut self.ringtone) {
self.beat = 0;
self.ringtone = curr_ringtone;
}
self.toggle().unwrap();
thread::sleep(Duration::from_millis(500));
self.toggle().unwrap();
thread::sleep(Duration::from_millis(1500));
let curr = curr_ringtone[self.beat as usize];
if curr {
self.channel.set_duty(50).expect("Failed to set duty");
} else {
self.channel.set_duty(0).expect("Failed to set duty");
}
thread::sleep(Duration::from_millis(100));
self.beat += 1;
if self.beat == 16 {
self.beat = 0;
}
}
}
}
pub mod ringtone {
pub type Type = [bool; 16];
pub const POWER_DOWN: Type = [
true, true, true, true, false, false, false, false, false, false, false, false, false,
false, false, false,
];
pub const BATTERY_LOW: Type = [
true, true, false, false, true, true, false, false, true, true, false, false, true, true,
false, false,
];
pub const SILENCE: Type = [false; 16];
}

View File

@ -1,5 +1,5 @@
use esp_idf_sys as _;
use std::{thread, time::Duration};
use std::{thread, time::Duration, sync::mpsc};
mod beep;
mod blink;
@ -26,6 +26,8 @@ fn main() {
let adapter_pin = peripherals.pins.gpio1;
let battery_pin = peripherals.pins.gpio2;
let (tx, mut rx) = mpsc::channel();
println!("Starting screen");
let display = screen::Screen::new(i2c0, gpio9, gpio10).expect("Failed to create screen");
@ -46,10 +48,10 @@ fn main() {
ledc_channel0,
)
.expect("Failed to create beep");
beep.play();
beep.play(&mut rx);
});
let mut dc_out_ctl = dc_out_controller::DcOutController::new(
let dc_out_ctl = dc_out_controller::DcOutController::new(
dc_out_ctl_pin
.into_output()
.expect("Failed to set GPIO3 as output"),
@ -60,6 +62,7 @@ fn main() {
adc1,
adapter_pin.into_analog_atten_11db().expect("Failed to set GPIO1 as analog input"),
battery_pin.into_analog_atten_11db().expect("Failed to set GPIO2 as analog input"),
tx,
).expect("Failed to create manager");
loop {
manager.handling_once().expect("Failed to handle once");

View File

@ -1,14 +1,14 @@
use std::{thread, time::Duration};
use std::{sync::mpsc, thread, time::Duration};
use embedded_hal::digital::blocking::OutputPin;
use embedded_hal_0_2::{adc::OneShot, digital::v2::InputPin};
use embedded_hal_0_2::adc::OneShot;
use esp_idf_hal::{
adc::{Adc, Atten11dB, PoweredAdc, ADC1},
gpio::{Gpio1, Gpio2}, delay,
adc::{Atten11dB, PoweredAdc, ADC1},
gpio::{Gpio1, Gpio2},
};
use esp_idf_sys::EspError;
use crate::{dc_out_controller::DcOutController, screen::Screen};
use crate::{beep::ringtone, dc_out_controller::DcOutController, screen::Screen};
type AdapterGpio = Gpio1<Atten11dB<ADC1>>;
type BatteryGpio = Gpio2<Atten11dB<ADC1>>;
@ -22,6 +22,7 @@ where
adc: PoweredAdc<ADC1>,
adapter_pin: AdapterGpio,
battery_pin: BatteryGpio,
tx: mpsc::Sender<ringtone::Type>,
}
impl<C> Manager<C>
@ -34,6 +35,7 @@ where
adc1: ADC1,
adapter_pin: AdapterGpio,
battery_pin: BatteryGpio,
tx: mpsc::Sender<ringtone::Type>,
) -> Result<Self, EspError> {
let adc = PoweredAdc::new(
adc1,
@ -45,6 +47,7 @@ where
adc,
adapter_pin,
battery_pin,
tx,
});
}
@ -69,7 +72,19 @@ where
if adapter < 1000.0 {
self.dc_out_controller.off().expect("Can not turn off Out");
if battery < 1000.0 {
self.tx
.send(ringtone::BATTERY_LOW)
.expect("Can not send message");
} else {
self.tx
.send(ringtone::POWER_DOWN)
.expect("Can not send message");
}
} else {
self.tx
.send(ringtone::SILENCE)
.expect("Can not send message");
self.dc_out_controller.on().expect("Can not turn on Out");
}
self.screen