v0.2:重写项目。 #6
@ -24,6 +24,8 @@ 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"
|
||||
serde = {version="1.0.144", features = ["derive"]}
|
||||
serde_json = "1.0.83"
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -38,10 +38,10 @@ where
|
||||
break;
|
||||
}
|
||||
self.toggle().unwrap();
|
||||
thread::sleep(Duration::from_millis(30));
|
||||
thread::sleep(Duration::from_millis(10));
|
||||
|
||||
self.toggle().unwrap();
|
||||
thread::sleep(Duration::from_millis(1930));
|
||||
thread::sleep(Duration::from_millis(990));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
0
src/eventloop.rs
Normal file
0
src/eventloop.rs
Normal file
62
src/main.rs
62
src/main.rs
@ -1,5 +1,6 @@
|
||||
use embedded_svc::mqtt::client::{Publish, QoS};
|
||||
use esp_idf_sys as _;
|
||||
use embedded_svc::event_bus::EventBus;
|
||||
use esp_idf_svc::eventloop::{Background, EspBackgroundEventLoop, EspEventLoop};
|
||||
use esp_idf_sys::{self as _, EspError};
|
||||
use log::*;
|
||||
use std::{
|
||||
env,
|
||||
@ -10,13 +11,16 @@ use std::{
|
||||
mod blink;
|
||||
mod message_queue;
|
||||
mod time;
|
||||
mod wifi;
|
||||
mod voltage_detection;
|
||||
mod wifi;
|
||||
|
||||
use crate::voltage_detection::VoltageDetectionWorker;
|
||||
use crate::{
|
||||
message_queue::MessageQueue, time::Time, wifi::Internet, voltage_detection::VoltageDetection,
|
||||
message_queue::MessageQueue, time::Time, voltage_detection::VoltageDetection, wifi::Internet,
|
||||
};
|
||||
|
||||
static mut EVENTLOOP: Option<EspEventLoop<esp_idf_svc::eventloop::User<Background>>> = None;
|
||||
|
||||
fn main() {
|
||||
env::set_var("DEFMT_LOG", "trace");
|
||||
env::set_var("RUST_BACKTRACE", "1");
|
||||
@ -40,6 +44,12 @@ fn main() {
|
||||
let sda_pin = peripherals.pins.gpio4;
|
||||
let scl_pin = peripherals.pins.gpio10;
|
||||
|
||||
info!("About to start a background event loop");
|
||||
match EspBackgroundEventLoop::new(&Default::default()) {
|
||||
Ok(eventloop) => unsafe { EVENTLOOP = Some(eventloop) },
|
||||
Err(err) => error!("Init Event Loop failed. {:?}", err),
|
||||
};
|
||||
|
||||
thread::spawn(move || {
|
||||
let mut blink = blink::Blink::new(
|
||||
blink_pin
|
||||
@ -51,7 +61,9 @@ fn main() {
|
||||
|
||||
let mut voltage_detection = VoltageDetection::new();
|
||||
|
||||
voltage_detection.watching().expect("Can not watch voltages.");
|
||||
voltage_detection
|
||||
.watching()
|
||||
.expect("Can not watch voltages.");
|
||||
|
||||
let _wifi = Internet::new().unwrap();
|
||||
|
||||
@ -61,21 +73,35 @@ fn main() {
|
||||
let mut time = Time::new();
|
||||
time.sync().unwrap();
|
||||
|
||||
let _subscription;
|
||||
if let Some(eventloop) = unsafe { EVENTLOOP.as_mut() } {
|
||||
_subscription = eventloop
|
||||
.subscribe(move |message: &VoltageDetectionWorker| {
|
||||
info!("Event Loop Value");
|
||||
if let Ok(json_str) = serde_json::to_string(&message) {
|
||||
if let Err(err) = mq.publish("voltage", json_str.as_bytes()) {
|
||||
warn!("Can not publish message to MQTT. {}", err);
|
||||
}
|
||||
}
|
||||
})
|
||||
.expect(" Listening Event Loop Failed");
|
||||
}
|
||||
|
||||
loop {
|
||||
sleep(Duration::from_millis(1000));
|
||||
if let Some(ref mut mq_client) = mq.client {
|
||||
let timestamps = time.get_time().as_millis();
|
||||
// if let Some(ref mut mq_client) = mq.client {
|
||||
// let timestamps = time.get_time().as_millis();
|
||||
|
||||
info!("timestamps {}", timestamps);
|
||||
mq_client
|
||||
.publish(
|
||||
"ups-0.2/heartbeat",
|
||||
QoS::AtMostOnce,
|
||||
false,
|
||||
timestamps.to_string().as_bytes(),
|
||||
)
|
||||
.map_err(|err| warn!("publish heartbeat failed {}", err))
|
||||
.unwrap();
|
||||
}
|
||||
// info!("timestamps {}", timestamps);
|
||||
// mq_client
|
||||
// .publish(
|
||||
// "ups-0.2/heartbeat",
|
||||
// QoS::AtMostOnce,
|
||||
// false,
|
||||
// timestamps.to_string().as_bytes(),
|
||||
// )
|
||||
// .map_err(|err| warn!("publish heartbeat failed {}", err))
|
||||
// .unwrap();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -61,13 +61,16 @@ impl MessageQueue {
|
||||
anyhow::Ok(())
|
||||
}
|
||||
|
||||
pub fn publish(&mut self, bytes: &[u8]) -> Result<u32> {
|
||||
pub fn publish(&mut self, topic: &str, bytes: &[u8]) -> Result<u32> {
|
||||
self.client
|
||||
.as_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.publish("", QoS::AtMostOnce, false, bytes)
|
||||
.map_err(|err| {
|
||||
anyhow::anyhow!("publish message to queue was failed!. {}", err)
|
||||
})
|
||||
.publish(
|
||||
format!("{}/{}", "ups_0_2", topic).as_str(),
|
||||
QoS::AtMostOnce,
|
||||
false,
|
||||
bytes,
|
||||
)
|
||||
.map_err(|err| anyhow::anyhow!("publish message to queue was failed!. {}", err))
|
||||
}
|
||||
}
|
||||
|
@ -3,24 +3,41 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use embedded_hal::{adc::Channel, prelude::_embedded_hal_adc_OneShot, digital::v2::OutputPin};
|
||||
use embedded_svc::timer::{PeriodicTimer, TimerService};
|
||||
use embedded_hal::{adc::Channel, prelude::_embedded_hal_adc_OneShot};
|
||||
use embedded_svc::{
|
||||
event_bus::Postbox,
|
||||
timer::{PeriodicTimer, TimerService},
|
||||
};
|
||||
use esp_idf_hal::{
|
||||
adc::{
|
||||
config::{self},
|
||||
Analog, PoweredAdc, ADC1,
|
||||
},
|
||||
gpio::{Gpio1, Gpio2, Gpio3, Input, Pull},
|
||||
gpio::{Gpio1, Gpio2, Gpio3, Input},
|
||||
};
|
||||
use esp_idf_svc::timer::{EspTimer, EspTimerService};
|
||||
use esp_idf_svc::{
|
||||
eventloop::{
|
||||
EspEventFetchData, EspEventPostData, EspTypedEventDeserializer, EspTypedEventSerializer,
|
||||
EspTypedEventSource,
|
||||
},
|
||||
timer::{EspTimer, EspTimerService},
|
||||
};
|
||||
use esp_idf_sys::c_types;
|
||||
use log::{info, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::EVENTLOOP;
|
||||
|
||||
const ADAPTER_OFFSET: f32 = 12002f32 / 900f32;
|
||||
const BATTERY_OFFSET: f32 = 12002f32 / 900f32;
|
||||
const OUTPUT_OFFSET: f32 = 12002f32 / 900f32;
|
||||
|
||||
pub struct VoltageDetection {
|
||||
pub worker: VoltageDetectionWorker,
|
||||
watch_timer: Option<EspTimer>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct VoltageDetectionWorker {
|
||||
pub adapter_voltage: u16,
|
||||
pub battery_voltage: u16,
|
||||
@ -39,7 +56,7 @@ impl VoltageDetection {
|
||||
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() {
|
||||
match worker.lock().as_mut() {
|
||||
Ok(worker) => {
|
||||
if let Err(err) = worker.read_once() {
|
||||
warn!("Read Failed. {}", err);
|
||||
@ -48,6 +65,22 @@ impl VoltageDetection {
|
||||
"Adapter: {},\tBattery: {},\t Output: {}",
|
||||
worker.adapter_voltage, worker.battery_voltage, worker.output_voltage
|
||||
);
|
||||
if let Some(eventloop) = unsafe { EVENTLOOP.as_mut() } {
|
||||
if let Err(err) = eventloop.post(
|
||||
&mut VoltageDetectionWorker {
|
||||
adapter_voltage: worker.adapter_voltage,
|
||||
battery_voltage: worker.battery_voltage,
|
||||
output_voltage: worker.output_voltage,
|
||||
},
|
||||
None,
|
||||
) {
|
||||
warn!("Post Result to Event Loop failed. {}", err);
|
||||
} else {
|
||||
info!("Event Loop Post");
|
||||
}
|
||||
} else {
|
||||
warn!("EVENTLOOP IS NONE");
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Lock VoltageDetection Worker Failed. {}", err)
|
||||
@ -60,6 +93,7 @@ impl VoltageDetection {
|
||||
return anyhow::Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl VoltageDetectionWorker {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
@ -71,11 +105,11 @@ impl VoltageDetectionWorker {
|
||||
|
||||
pub fn read_once(&mut self) -> anyhow::Result<()> {
|
||||
let adapter_pin = unsafe { Gpio1::<Input>::new() }
|
||||
.into_analog_atten_11db()
|
||||
.into_analog_atten_6db()
|
||||
.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;
|
||||
self.adapter_voltage = ((voltage as f32) * ADAPTER_OFFSET) as u16;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Adapter Voltage read failed: {:?}", err);
|
||||
@ -83,11 +117,11 @@ impl VoltageDetectionWorker {
|
||||
}
|
||||
|
||||
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))?;
|
||||
.into_analog_atten_6db()
|
||||
.map_err(|err| anyhow::anyhow!("Failed to set GPIO 2 as analog input. {}", err))?;
|
||||
match self.read_pin_once(battery_pin) {
|
||||
Ok(voltage) => {
|
||||
self.battery_voltage = voltage;
|
||||
self.battery_voltage = ((voltage as f32) * BATTERY_OFFSET) as u16;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Adapter Voltage read failed: {:?}", err);
|
||||
@ -95,11 +129,11 @@ impl VoltageDetectionWorker {
|
||||
}
|
||||
|
||||
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))?;
|
||||
.into_analog_atten_6db()
|
||||
.map_err(|err| anyhow::anyhow!("Failed to set GPIO 3 as analog input. {}", err))?;
|
||||
match self.read_pin_once(output_pin) {
|
||||
Ok(voltage) => {
|
||||
self.output_voltage = voltage;
|
||||
self.output_voltage = ((voltage as f32) * OUTPUT_OFFSET) as u16;
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Adapter Voltage read failed: {:?}", err);
|
||||
@ -115,10 +149,34 @@ impl VoltageDetectionWorker {
|
||||
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),
|
||||
Ok(voltage) => anyhow::Ok(voltage),
|
||||
Err(err) => {
|
||||
anyhow::bail!("Adapter Voltage read failed: {:?}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EspTypedEventSource for VoltageDetectionWorker {
|
||||
fn source() -> *const c_types::c_char {
|
||||
b"VOLTAGES\0".as_ptr() as *const _
|
||||
}
|
||||
}
|
||||
|
||||
impl EspTypedEventSerializer<VoltageDetectionWorker> for VoltageDetectionWorker {
|
||||
fn serialize<R>(
|
||||
event: &VoltageDetectionWorker,
|
||||
f: impl for<'a> FnOnce(&'a EspEventPostData) -> R,
|
||||
) -> R {
|
||||
f(&unsafe { EspEventPostData::new(Self::source(), Self::event_id(), event) })
|
||||
}
|
||||
}
|
||||
|
||||
impl EspTypedEventDeserializer<VoltageDetectionWorker> for VoltageDetectionWorker {
|
||||
fn deserialize<R>(
|
||||
data: &EspEventFetchData,
|
||||
f: &mut impl for<'a> FnMut(&'a VoltageDetectionWorker) -> R,
|
||||
) -> R {
|
||||
f(unsafe { data.as_payload() })
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user