feat: blink, voltage detection.
This commit is contained in:
parent
5058005031
commit
d20344fe5e
@ -17,8 +17,10 @@ pio = ["esp-idf-sys/pio"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
embedded-hal = "0.2.7"
|
||||
embedded-svc = "0.22.0"
|
||||
env_logger = "0.9.0"
|
||||
esp-idf-hal = "0.38.0"
|
||||
esp-idf-svc = "0.42.1"
|
||||
esp-idf-sys = { version = "0.31.6", features = ["binstart"] }
|
||||
log = "0.4.17"
|
||||
|
47
src/blink.rs
Normal file
47
src/blink.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct Blink<T>
|
||||
where
|
||||
T: OutputPin,
|
||||
{
|
||||
state: bool,
|
||||
pin: T,
|
||||
stopped: bool,
|
||||
}
|
||||
|
||||
impl<T> Blink<T>
|
||||
where
|
||||
T: OutputPin,
|
||||
{
|
||||
pub fn new(pin: T) -> Blink<T> {
|
||||
return Blink {
|
||||
state: false,
|
||||
pin,
|
||||
stopped: false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toggle(&mut self) -> Result<(), T::Error> {
|
||||
self.state = !self.state;
|
||||
if self.state {
|
||||
self.pin.set_high()
|
||||
} else {
|
||||
self.pin.set_low()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play(&mut self) where <T as embedded_hal::digital::v2::OutputPin>::Error: std::fmt::Debug {
|
||||
loop {
|
||||
if self.stopped {
|
||||
break;
|
||||
}
|
||||
self.toggle().unwrap();
|
||||
thread::sleep(Duration::from_millis(30));
|
||||
|
||||
self.toggle().unwrap();
|
||||
thread::sleep(Duration::from_millis(1930));
|
||||
}
|
||||
}
|
||||
}
|
50
src/main.rs
50
src/main.rs
@ -1,13 +1,22 @@
|
||||
use std::{env, thread::sleep, time::{Duration}};
|
||||
use embedded_svc::mqtt::client::{Publish, QoS};
|
||||
use esp_idf_sys as _;
|
||||
use log::*;
|
||||
use std::{
|
||||
env,
|
||||
thread::{self, sleep},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
mod blink;
|
||||
mod message_queue;
|
||||
mod wifi;
|
||||
mod time;
|
||||
mod wifi;
|
||||
mod voltage_detection;
|
||||
|
||||
use crate::{
|
||||
message_queue::MessageQueue, time::Time, wifi::Internet, voltage_detection::VoltageDetection,
|
||||
};
|
||||
|
||||
use crate::{message_queue::MessageQueue, wifi::Internet, time::Time};
|
||||
fn main() {
|
||||
env::set_var("DEFMT_LOG", "trace");
|
||||
env::set_var("RUST_BACKTRACE", "1");
|
||||
@ -18,7 +27,31 @@ fn main() {
|
||||
// or else some patches to the runtime implemented by esp-idf-sys might not link properly.
|
||||
esp_idf_sys::link_patches();
|
||||
|
||||
println!("Hello, world!");
|
||||
info!("Hello, world!");
|
||||
|
||||
let peripherals = esp_idf_hal::peripherals::Peripherals::take().unwrap();
|
||||
|
||||
let blink_pin = peripherals.pins.gpio5;
|
||||
let beep_pin = peripherals.pins.gpio6;
|
||||
let ledc_timer0 = peripherals.ledc.timer0;
|
||||
let ledc_channel0 = peripherals.ledc.channel0;
|
||||
let dc_out_ctl_pin = peripherals.pins.gpio3;
|
||||
let i2c0 = peripherals.i2c0;
|
||||
let sda_pin = peripherals.pins.gpio4;
|
||||
let scl_pin = peripherals.pins.gpio10;
|
||||
|
||||
thread::spawn(move || {
|
||||
let mut blink = blink::Blink::new(
|
||||
blink_pin
|
||||
.into_output()
|
||||
.expect("Failed to set GPIO5 as output"),
|
||||
);
|
||||
blink.play();
|
||||
});
|
||||
|
||||
let mut voltage_detection = VoltageDetection::new();
|
||||
|
||||
voltage_detection.watching().expect("Can not watch voltages.");
|
||||
|
||||
let _wifi = Internet::new().unwrap();
|
||||
|
||||
@ -34,14 +67,15 @@ fn main() {
|
||||
let timestamps = time.get_time().as_millis();
|
||||
|
||||
info!("timestamps {}", timestamps);
|
||||
mq_client.publish(
|
||||
mq_client
|
||||
.publish(
|
||||
"ups-0.2/heartbeat",
|
||||
QoS::AtMostOnce,
|
||||
false,
|
||||
timestamps.to_string().as_bytes(),
|
||||
).map_err(|err| {
|
||||
warn!("publish heartbeat failed {}", err)
|
||||
}).unwrap();
|
||||
)
|
||||
.map_err(|err| warn!("publish heartbeat failed {}", err))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ impl MessageQueue {
|
||||
};
|
||||
|
||||
let (mut client, mut connection) =
|
||||
EspMqttClient::new_with_conn("mqtt://192.168.31.8:1883", &conf)?;
|
||||
EspMqttClient::new_with_conn("mqtt://192.168.31.11:1883", &conf)?;
|
||||
|
||||
info!("MQTT client started");
|
||||
thread::spawn(move || {
|
||||
|
124
src/voltage_detection.rs
Normal file
124
src/voltage_detection.rs
Normal file
@ -0,0 +1,124 @@
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use embedded_hal::{adc::Channel, prelude::_embedded_hal_adc_OneShot, digital::v2::OutputPin};
|
||||
use embedded_svc::timer::{PeriodicTimer, TimerService};
|
||||
use esp_idf_hal::{
|
||||
adc::{
|
||||
config::{self},
|
||||
Analog, PoweredAdc, ADC1,
|
||||
},
|
||||
gpio::{Gpio1, Gpio2, Gpio3, Input, Pull},
|
||||
};
|
||||
use esp_idf_svc::timer::{EspTimer, EspTimerService};
|
||||
use log::{info, warn};
|
||||
|
||||
pub struct VoltageDetection {
|
||||
pub worker: VoltageDetectionWorker,
|
||||
watch_timer: Option<EspTimer>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct VoltageDetectionWorker {
|
||||
pub adapter_voltage: u16,
|
||||
pub battery_voltage: u16,
|
||||
pub output_voltage: u16,
|
||||
}
|
||||
|
||||
impl VoltageDetection {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
worker: VoltageDetectionWorker::new(),
|
||||
watch_timer: None,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn watching(&mut self) -> anyhow::Result<()> {
|
||||
let worker = Arc::new(Mutex::new(self.worker));
|
||||
let mut timer = EspTimerService::new()?.timer(move || {
|
||||
info!("One-shot timer triggered");
|
||||
match worker.as_ref().lock().as_mut() {
|
||||
Ok(worker) => {
|
||||
if let Err(err) = worker.read_once() {
|
||||
warn!("Read Failed. {}", err);
|
||||
}
|
||||
info!(
|
||||
"Adapter: {},\tBattery: {},\t Output: {}",
|
||||
worker.adapter_voltage, worker.battery_voltage, worker.output_voltage
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Lock VoltageDetection Worker Failed. {}", err)
|
||||
}
|
||||
}
|
||||
})?;
|
||||
timer.every(Duration::from_secs(1))?;
|
||||
|
||||
self.watch_timer = Some(timer);
|
||||
return anyhow::Ok(());
|
||||
}
|
||||
}
|
||||
impl VoltageDetectionWorker {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
adapter_voltage: 0,
|
||||
battery_voltage: 0,
|
||||
output_voltage: 0,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn read_once(&mut self) -> anyhow::Result<()> {
|
||||
let adapter_pin = unsafe { Gpio1::<Input>::new() }
|
||||
.into_analog_atten_11db()
|
||||
.map_err(|err| anyhow::anyhow!("Failed to set GPIO 1 as analog input. {}", err))?;
|
||||
match self.read_pin_once(adapter_pin) {
|
||||
Ok(voltage) => {
|
||||
self.adapter_voltage = voltage;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Adapter Voltage read failed: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
let battery_pin = unsafe { Gpio2::<Input>::new() }
|
||||
.into_analog_atten_11db()
|
||||
.map_err(|err| anyhow::anyhow!("Failed to set GPIO 1 as analog input. {}", err))?;
|
||||
match self.read_pin_once(battery_pin) {
|
||||
Ok(voltage) => {
|
||||
self.battery_voltage = voltage;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Adapter Voltage read failed: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
let output_pin = unsafe { Gpio3::<Input>::new() }
|
||||
.into_analog_atten_11db()
|
||||
.map_err(|err| anyhow::anyhow!("Failed to set GPIO 1 as analog input. {}", err))?;
|
||||
match self.read_pin_once(output_pin) {
|
||||
Ok(voltage) => {
|
||||
self.output_voltage = voltage;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Adapter Voltage read failed: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
return anyhow::Ok(());
|
||||
}
|
||||
pub fn read_pin_once<AN: Analog<ADC1>, PIN: Channel<AN, ID = u8>>(
|
||||
&mut self,
|
||||
mut pin: PIN,
|
||||
) -> anyhow::Result<u16> {
|
||||
let mut adc = PoweredAdc::new(unsafe { ADC1::new() }, config::Config::new())?;
|
||||
let voltage = adc.read(&mut pin);
|
||||
match voltage {
|
||||
Ok(voltage) => anyhow::Ok((self.adapter_voltage + voltage * 10) / 11),
|
||||
Err(err) => {
|
||||
anyhow::bail!("Adapter Voltage read failed: {:?}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user