Created
January 16, 2023 23:04
-
-
Save arnemileswinter/c6635afa93f92fde73d818f55d616d70 to your computer and use it in GitHub Desktop.
Rust snippet using avr-hal: Manual PWM to pull a digital output pin on an arduino to specified Hertz frequency. Useful to operate buzzers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use arduino_hal::{clock::Clock,port::{mode::Output, Pin, PinOps}}; | |
/// Pull an arduino's output pin to specified Hertz for microseconds duration. | |
/// This is essentially manual PWM, without avr-hal's clock prescaling. | |
/// Useful to make buzzers oscillate at 440 hertz. | |
/// This is not measured to be precise but works well enough. | |
/// | |
/// example: | |
/// let dp = arduino_hal::Peripherals::take().unwrap(); | |
/// let pins = arduino_hal::pins!(dp); | |
/// let mut buzzer_pin = pins.d2.into_output() | |
/// pin_to_hz_for_duration_us(&mut buzzer_pin, 440, 2 * 10_u32.pow(6)) // pin d2 buzzes at 440hz for 2 seconds. | |
fn pin_to_hz_for_duration_us<P: PinOps> (pin: &mut Pin<Output, P>, frequency_hz: u32, duration_us: u32) { | |
if frequency_hz == 0 { | |
// can't meaningfully wait | |
arduino_hal::delay_us(duration_us); | |
return; | |
} | |
const CLOCK_SPEED_HZ: u32 = arduino_hal::DefaultClock::FREQ; | |
let wait_time = (CLOCK_SPEED_HZ / frequency_hz) / 100; | |
let mut acc = 0; | |
while acc < duration_us { | |
pin.set_high(); | |
arduino_hal::delay_us(wait_time / 2); | |
pin.set_low(); | |
arduino_hal::delay_us(wait_time / 2); | |
acc += wait_time; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment