volt
This commit is contained in:
parent
511b4ef079
commit
452abc36a5
59
src/main.rs
59
src/main.rs
|
|
@ -18,7 +18,9 @@ use embassy_futures::join::{join3, join4};
|
||||||
use embassy_nrf::gpio::{AnyPin, Input, OutputDrive, Pull};
|
use embassy_nrf::gpio::{AnyPin, Input, OutputDrive, Pull};
|
||||||
use embassy_nrf::interrupt::Priority;
|
use embassy_nrf::interrupt::Priority;
|
||||||
use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
|
use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
|
||||||
use embassy_nrf::Peri;
|
use embassy_nrf::{bind_interrupts, saadc, Peri};
|
||||||
|
use embassy_nrf::peripherals::SAADC;
|
||||||
|
use embassy_nrf::saadc::{ChannelConfig, Gain, Reference, Saadc};
|
||||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
use embassy_sync::mutex::Mutex;
|
use embassy_sync::mutex::Mutex;
|
||||||
use embassy_sync::signal::Signal;
|
use embassy_sync::signal::Signal;
|
||||||
|
|
@ -96,12 +98,16 @@ struct Server {
|
||||||
light: AnimationService,
|
light: AnimationService,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bind_interrupts!(struct AdcIrqs {
|
||||||
|
SAADC => saadc::InterruptHandler;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let mut config = embassy_nrf::config::Config::default();
|
let mut config = embassy_nrf::config::Config::default();
|
||||||
config.gpiote_interrupt_priority = Priority::P2;
|
config.gpiote_interrupt_priority = Priority::P2;
|
||||||
config.time_interrupt_priority = Priority::P2;
|
config.time_interrupt_priority = Priority::P2;
|
||||||
let p = embassy_nrf::init(config);
|
let mut p = embassy_nrf::init(config);
|
||||||
|
|
||||||
let config = nrf_softdevice::Config {
|
let config = nrf_softdevice::Config {
|
||||||
clock: Some(raw::nrf_clock_lf_cfg_t {
|
clock: Some(raw::nrf_clock_lf_cfg_t {
|
||||||
|
|
@ -138,16 +144,23 @@ async fn main(spawner: Spawner) {
|
||||||
let sd = Softdevice::enable(&config);
|
let sd = Softdevice::enable(&config);
|
||||||
let server = Server::new(sd).expect("failed to enable softdevice");
|
let server = Server::new(sd).expect("failed to enable softdevice");
|
||||||
|
|
||||||
let pwm_text = SimplePwm::new_3ch(p.PWM0, p.P1_15, p.P1_13, p.P1_11, &Default::default());
|
let mut channel_config = ChannelConfig::single_ended(p.P0_31.reborrow());
|
||||||
let pwm_heart = SimplePwm::new_3ch(p.PWM2, p.P0_31, p.P0_29, p.P0_02, &Default::default());
|
channel_config.gain = Gain::GAIN1_6;
|
||||||
|
channel_config.reference = Reference::INTERNAL;
|
||||||
|
let saadc = Saadc::new(p.SAADC, AdcIrqs, saadc::Config::default(), [channel_config]);
|
||||||
|
|
||||||
|
let pwm_text = SimplePwm::new_3ch(p.PWM0, p.P1_00, p.P1_04, p.P1_06, &Default::default());
|
||||||
|
let pwm_heart = SimplePwm::new_3ch(p.PWM2, p.P0_17, p.P0_20, p.P0_22, &Default::default());
|
||||||
spawner.spawn(radar_task()).expect("failed to spawn radar task");
|
spawner.spawn(radar_task()).expect("failed to spawn radar task");
|
||||||
spawner.spawn(touch_button(p.P0_20.into())).expect("failed to spawn touch task");
|
spawner.spawn(touch_button(p.P0_08.into())).expect("failed to spawn touch task");
|
||||||
spawner.spawn(actions_task()).expect("failed to spawn actions task");
|
spawner.spawn(actions_task()).expect("failed to spawn actions task");
|
||||||
spawner.spawn(softdevice_task(sd)).expect("failed to spawn softdevice task");
|
spawner.spawn(softdevice_task(sd)).expect("failed to spawn softdevice task");
|
||||||
|
spawner.spawn(battery_task(saadc)).expect("failed to spawn softdevice task");
|
||||||
|
|
||||||
join4(gatt_task(server, sd), moving_radar(p.P0_22.into()), heartbeat_task(pwm_heart), light_task(pwm_text)).await;
|
join4(gatt_task(server, sd), moving_radar(p.P0_06.into()), heartbeat_task(pwm_heart), light_task(pwm_text)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn gatt_task(server: Server, sd: &'static Softdevice) {
|
async fn gatt_task(server: Server, sd: &'static Softdevice) {
|
||||||
static ADV_DATA: LegacyAdvertisementPayload = LegacyAdvertisementBuilder::new()
|
static ADV_DATA: LegacyAdvertisementPayload = LegacyAdvertisementBuilder::new()
|
||||||
.flags(&[Flag::GeneralDiscovery, Flag::LE_Only])
|
.flags(&[Flag::GeneralDiscovery, Flag::LE_Only])
|
||||||
|
|
@ -317,6 +330,40 @@ async fn touch_button(pin: Peri<'static, AnyPin>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn battery_task(mut saadc: Saadc<'static, 1>) {
|
||||||
|
const REFERENCE: f32 = 3.6;
|
||||||
|
let mut measurements = [0i16; 4];
|
||||||
|
let mut index = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut buf = [0; 1];
|
||||||
|
saadc.sample(&mut buf).await;
|
||||||
|
let voltage = ((buf[0] as f32 * REFERENCE) / 2.03f32) as i16;
|
||||||
|
measurements[index] = voltage;
|
||||||
|
index = (index + 1) % measurements.len();
|
||||||
|
if measurements.iter().any(|v| *v == 0) {
|
||||||
|
Timer::after_millis(1000).await;
|
||||||
|
} else {
|
||||||
|
let total = (measurements.iter().sum::<i16>() / measurements.len() as i16) as u16;
|
||||||
|
let percent = battery_mv_to_percent(total);
|
||||||
|
info!("Battery: {=i16}, {=u16}, {}%", voltage, total, percent);
|
||||||
|
Timer::after_millis(2000).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn battery_mv_to_percent(mv: u16) -> u8 {
|
||||||
|
match mv {
|
||||||
|
mv if mv >= 4150 => 100,
|
||||||
|
mv if mv <= 3000 => 0,
|
||||||
|
_ => {
|
||||||
|
let percent = (mv as u32 - 3000) * 100 / (4150 - 3000);
|
||||||
|
percent as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn actions_task() {
|
async fn actions_task() {
|
||||||
loop {
|
loop {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue