diff --git a/src/main.rs b/src/main.rs index e378ed5..c639df8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,8 +40,7 @@ async fn main(spawner: Spawner) { // configure, which tasks to spawn. For a production build we need all tasks, for troubleshooting we can disable some // the tasks are all spawned in main.rs, so we can disable them here // clutter in the output aside, the binary size is conveniently reduced by disabling tasks - let mut task_config = TaskConfig::new(); - task_config.sound_handler = false; + let task_config = TaskConfig::new(); // RTC // Initialize the RTC in a static cell, we will need it in multiple places @@ -102,9 +101,6 @@ async fn main(spawner: Spawner) { } // Neopixel - // Note! -> we may need more than one neopixel task eventually, in that case we will need mutexes around the resources - // i want to keep it simple for now - // the neopixel task will be spawned on core1, because it will run in parallel to the other tasks and it may block // spawn the neopixel tasks, on core1 as opposed to the other tasks static mut CORE1_STACK: Stack<4096> = Stack::new(); diff --git a/src/task/light_effects.rs b/src/task/light_effects.rs index 2a5f1c1..256ba67 100644 --- a/src/task/light_effects.rs +++ b/src/task/light_effects.rs @@ -268,13 +268,13 @@ pub async fn light_effects_handler(_spawner: Spawner, r: NeopixelResources) { let mut data = [RGB8::default(); NUM_LEDS]; 'noise: loop { - if LIGHTFX_STOP_SIGNAL.signaled() { - info!("Noise effect aborting"); - LIGHTFX_STOP_SIGNAL.reset(); - break 'noise; - }; - for j in 0..(256 * 5) { + if LIGHTFX_STOP_SIGNAL.signaled() { + info!("Noise effect aborting"); + LIGHTFX_STOP_SIGNAL.reset(); + break 'noise; + }; + for i in 0..NUM_LEDS { data[i] = neopixel_mgr.wheel( (((i * 256) as u16 / NUM_LEDS as u16 + j as u16) & 255) diff --git a/src/task/orchestrate.rs b/src/task/orchestrate.rs index b6e7fd8..02c1f84 100644 --- a/src/task/orchestrate.rs +++ b/src/task/orchestrate.rs @@ -93,7 +93,9 @@ pub async fn orchestrator(_spawner: Spawner) { SCHEDULER_STOP_SIGNAL.signal(Commands::SchedulerStop); DISPLAY_SIGNAL.signal(Commands::DisplayUpdate); LIGHTFX_SIGNAL.signal(Commands::LightFXUpdate((0, 0, 0))); - SOUND_SIGNAL.signal(Commands::SoundUpdate); + if SOUND_START_SIGNAL.signaled() { + SOUND_STOP_SIGNAL.signal(Commands::SoundUpdate); + } } Events::WakeUp => { info!("Wake up event"); @@ -112,16 +114,13 @@ pub async fn orchestrator(_spawner: Spawner) { DISPLAY_SIGNAL.signal(Commands::DisplayUpdate); LIGHTFX_STOP_SIGNAL.signal(Commands::LightFXUpdate((0, 0, 0))); LIGHTFX_SIGNAL.signal(Commands::LightFXUpdate((0, 0, 0))); - SOUND_SIGNAL.signal(Commands::SoundUpdate); + SOUND_STOP_SIGNAL.signal(Commands::SoundUpdate); } Events::SunriseEffectFinished => { info!("Sunrise effect finished event"); state_manager.set_alarm_state(AlarmState::Noise); - SOUND_SIGNAL.signal(Commands::SoundUpdate); + SOUND_START_SIGNAL.signal(Commands::SoundUpdate); LIGHTFX_SIGNAL.signal(Commands::LightFXUpdate((0, 0, 0))); - // ToDo: state manager must go to the next alarm state - // ToDo: neopixel must go to the next effect - // ToDo: sound must play } } // log the state of the system diff --git a/src/task/sound.rs b/src/task/sound.rs index 2126d25..2988286 100644 --- a/src/task/sound.rs +++ b/src/task/sound.rs @@ -3,6 +3,7 @@ //! //! The task is responsible for initializing the DFPlayer Mini module, powering it on, playing a sound, and powering it off. use crate::task::resources::{DfPlayerResources, Irqs}; +use crate::task::task_messages::{SOUND_START_SIGNAL, SOUND_STOP_SIGNAL}; use defmt::{info, Debug2Format}; use dfplayer_serial::{DfPlayer, Equalizer, PlayBackSource}; use embassy_executor::Spawner; @@ -38,6 +39,9 @@ pub async fn sound_handler(_spawner: Spawner, r: DfPlayerResources) { let mut pwr = Output::new(r.power_pin, Level::Low); loop { + // wait for the signal to start playing sound + SOUND_START_SIGNAL.wait().await; + // power on the dfplayer info!("Powering on the dfplayer"); pwr.set_high(); @@ -57,24 +61,23 @@ pub async fn sound_handler(_spawner: Spawner, r: DfPlayerResources) { info!("Playing sound"); if let Ok(ref mut dfp) = dfp_result { - let _ = dfp.volume(5).await; + let _ = dfp.volume(20).await; Timer::after(Duration::from_millis(100)).await; let _ = dfp.equalizer(Equalizer::Classic).await; Timer::after(Duration::from_millis(100)).await; let _ = dfp.playback_source(PlayBackSource::SDCard).await; Timer::after(Duration::from_millis(100)).await; let _ = dfp.play(1).await; - Timer::after(Duration::from_secs(100)).await; + Timer::after(Duration::from_millis(200)).await; } else { info!("DfPlayer not initialized, skipping sound playback."); } - Timer::after(Duration::from_secs(10)).await; + + // wait for the signal to stop playing sound + SOUND_STOP_SIGNAL.wait().await; // power off the dfplayer info!("Powering off the dfplayer"); pwr.set_low(); - Timer::after(Duration::from_secs(1)).await; - - Timer::after(Duration::from_secs(10)).await; } } diff --git a/src/task/task_messages.rs b/src/task/task_messages.rs index 6a05e8b..8d4600d 100644 --- a/src/task/task_messages.rs +++ b/src/task/task_messages.rs @@ -95,6 +95,8 @@ pub static LIGHTFX_SIGNAL: Signal = Signal::n pub static LIGHTFX_STOP_SIGNAL: Signal = Signal::new(); /// Signal for the update commands that we want the orchestrator to send to the sound task. -pub static SOUND_SIGNAL: Signal = Signal::new(); +pub static SOUND_START_SIGNAL: Signal = Signal::new(); +pub static SOUND_STOP_SIGNAL: Signal = Signal::new(); +/// Signal for the wake command that we want the orchestrator to send to the vsys_voltage_reader task. pub static VSYS_WAKE_SIGNAL: Signal = Signal::new();