Add music on button press
This commit is contained in:
parent
9d9adcf7d0
commit
ca5867ba36
1 changed files with 108 additions and 8 deletions
116
src/main.rs
116
src/main.rs
|
@ -8,10 +8,10 @@ use defmt::{info, unwrap};
|
|||
use embassy_executor::Spawner;
|
||||
use embassy_futures::select::{Either, select};
|
||||
use embassy_rp::bind_interrupts;
|
||||
use embassy_rp::config::Config;
|
||||
use embassy_rp::gpio::{self, Input};
|
||||
use embassy_rp::peripherals::{DMA_CH0, PIO0};
|
||||
use embassy_rp::peripherals::{DMA_CH0, PIN_20, PIO0, PWM_SLICE2};
|
||||
use embassy_rp::pio::{InterruptHandler, Pio};
|
||||
use embassy_rp::pwm::{self, Pwm, SetDutyCycle};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::channel::{Channel, Sender};
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
|
@ -81,7 +81,7 @@ async fn button(
|
|||
loop {
|
||||
info!("Waiting for falling edge");
|
||||
input.wait_for_falling_edge().await;
|
||||
sender.send(ChannelMessage::Refilled).await;
|
||||
let _ = sender.try_send(ChannelMessage::Refilled);
|
||||
input.wait_for_high().await;
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ async fn main(spawner: Spawner) {
|
|||
// Timer::after_secs(1).await;
|
||||
// }
|
||||
|
||||
let p = embassy_rp::init(Config::default());
|
||||
let mut p = embassy_rp::init(embassy_rp::config::Config::default());
|
||||
let fw = include_bytes!("../embassy/cyw43-firmware/43439A0.bin");
|
||||
let clm = include_bytes!("../embassy/cyw43-firmware/43439A0_clm.bin");
|
||||
|
||||
|
@ -152,10 +152,7 @@ async fn main(spawner: Spawner) {
|
|||
unwrap!(spawner.spawn(heartbeat(control)));
|
||||
|
||||
unwrap!(spawner.spawn(button(
|
||||
{
|
||||
let input = Input::new(p.PIN_15, gpio::Pull::Up);
|
||||
input
|
||||
},
|
||||
Input::new(p.PIN_15, gpio::Pull::Up),
|
||||
CHANNEL.sender()
|
||||
)));
|
||||
|
||||
|
@ -178,7 +175,10 @@ async fn main(spawner: Spawner) {
|
|||
info!("Water refilled received");
|
||||
water_state.refill();
|
||||
set_leds(water_state, &mut yellow_led, &mut red_led);
|
||||
play_music(&mut p.PWM_SLICE2, &mut p.PIN_20).await;
|
||||
timer = water_state.timer();
|
||||
// only permit one message at a time
|
||||
CHANNEL.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,3 +200,103 @@ fn set_leds(water_state: WaterState, yellow_led: &mut Output, red_led: &mut Outp
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn play_music(slice: &mut PWM_SLICE2, pin: &mut PIN_20) {
|
||||
const SIXTHTEEN_NOTE_MILLIS: u64 = 100;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
#[repr(u16)]
|
||||
enum Note {
|
||||
Rest = 0,
|
||||
C4 = 262,
|
||||
D4 = 294,
|
||||
E4 = 330,
|
||||
F4 = 349,
|
||||
G4 = 392,
|
||||
A5 = 440,
|
||||
#[allow(dead_code)]
|
||||
B5 = 494,
|
||||
C5 = 524,
|
||||
}
|
||||
#[expect(clippy::enum_glob_use)]
|
||||
use Note::*;
|
||||
|
||||
#[repr(u8)]
|
||||
enum Duration {
|
||||
Sixthteenth = 1,
|
||||
Eighth = 2,
|
||||
DottedEighth = 3,
|
||||
Quarter = 4,
|
||||
Half = 8,
|
||||
}
|
||||
#[expect(clippy::enum_glob_use)]
|
||||
use Duration::*;
|
||||
|
||||
const SONG: [(Note, Duration); 36] = [
|
||||
(C4, DottedEighth),
|
||||
(D4, Sixthteenth),
|
||||
(E4, DottedEighth),
|
||||
(F4, Sixthteenth),
|
||||
(G4, Quarter),
|
||||
(C5, Quarter),
|
||||
//
|
||||
(A5, Quarter),
|
||||
(C5, Quarter),
|
||||
(G4, Half),
|
||||
//
|
||||
(F4, Quarter),
|
||||
(F4, Eighth),
|
||||
(G4, Eighth),
|
||||
(E4, Quarter),
|
||||
(E4, Quarter),
|
||||
//
|
||||
(D4, Quarter),
|
||||
(D4, Eighth),
|
||||
(E4, Eighth),
|
||||
(C4, Half),
|
||||
//
|
||||
(C4, DottedEighth),
|
||||
(D4, Sixthteenth),
|
||||
(E4, DottedEighth),
|
||||
(F4, Sixthteenth),
|
||||
(G4, Quarter),
|
||||
(C5, Quarter),
|
||||
//
|
||||
(A5, Quarter),
|
||||
(C5, Quarter),
|
||||
(G4, Half),
|
||||
//
|
||||
(C5, Quarter),
|
||||
(Rest, Eighth),
|
||||
(A5, Eighth),
|
||||
(G4, DottedEighth),
|
||||
(G4, Sixthteenth),
|
||||
(F4, Quarter),
|
||||
//
|
||||
(E4, Quarter),
|
||||
(D4, Quarter),
|
||||
(C4, Half),
|
||||
];
|
||||
|
||||
for (note, duration) in SONG {
|
||||
let clock_freq_hz = embassy_rp::clocks::clk_sys_freq();
|
||||
let divider = 16;
|
||||
#[expect(clippy::cast_possible_truncation)]
|
||||
let period = clock_freq_hz.saturating_div(note as u32 * u32::from(divider)) as u16 - 1;
|
||||
|
||||
let mut c = pwm::Config::default();
|
||||
c.top = period;
|
||||
c.divider = divider.into();
|
||||
|
||||
let mut pwm = Pwm::new_output_a(&mut *slice, &mut *pin, c.clone());
|
||||
|
||||
if note == Rest {
|
||||
let _ = pwm.set_duty_cycle_fully_off();
|
||||
} else {
|
||||
let _ = pwm.set_duty_cycle_percent(50);
|
||||
}
|
||||
Timer::after_millis(duration as u64 * SIXTHTEEN_NOTE_MILLIS).await;
|
||||
let _ = pwm.set_duty_cycle_fully_off();
|
||||
Timer::after_millis(20).await;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue