Table of content

What is this :grey_question:

The rules of the game are explained in my original.

57th Challenge

Challenge

Build on yesterday’s example and use the buzzer of the generic node to make a buzz! πŸ“£ Here is a picture of the generic node again. Its a piece of hardware with an STM32WL5x and has a bunch of sensors and actuators as well as the possibility to use LoRaWAN.

Solution :white_check_mark:

Lets start from a template again, same folder as yesterday.

    cargo generate \
    --git https://github.com/stm32-rs/stm32wlxx-hal\
    --name stm32
    

The template, looks like this, when running tree -L 3

    .
    β”œβ”€β”€ CHANGELOG.md
    β”œβ”€β”€ Cargo.lock
    β”œβ”€β”€ Cargo.toml
    β”œβ”€β”€ LICENSE-APACHE
    β”œβ”€β”€ LICENSE-MIT
    β”œβ”€β”€ README.md
    β”œβ”€β”€ examples
    β”‚Β Β  β”œβ”€β”€ Cargo.toml
    β”‚Β Β  β”œβ”€β”€ examples
    β”‚Β Β  └── src
    β”œβ”€β”€ hal
    β”‚Β Β  β”œβ”€β”€ Cargo.toml
    β”‚Β Β  └── src
    β”œβ”€β”€ lora-e5-bsp
    β”‚Β Β  β”œβ”€β”€ Cargo.toml
    β”‚Β Β  β”œβ”€β”€ README.md
    β”‚Β Β  └── src
    β”œβ”€β”€ memory.x
    β”œβ”€β”€ nucleo-wl55jc-bsp
    β”‚Β Β  β”œβ”€β”€ Cargo.toml
    β”‚Β Β  β”œβ”€β”€ README.md
    β”‚Β Β  └── src
    β”œβ”€β”€ rustfmt.toml
    └── testsuite
        β”œβ”€β”€ Cargo.toml
        β”œβ”€β”€ README.md
        β”œβ”€β”€ runall.py
        └── src
    

To run tests we run DEFMT_LOG=info cargo test -p testsuite --target thumbv7em-none-eabi --bin pka.

To keep things simple, we will add an additional example, instead of doing something complicated. The buzzer is a β€œPiezo speaker - provides audible feedback.” According to the documentation it is connected to PA15 - internally connected to the piezo speaker. The schematic can be found under following link. The relevant part looks as follows.

The datasheet of the buzzer MLT-7525 shows that the oscillation frequency is 2700Hz which you can listen to onyoutube - it sounds annoying. . So we must toggle the output at the resonant frequency of 2700 Hz, which means we need to toggle the GPIO every 185e-6 seconds. This means we toggle -> delay_us(185)permantently to activate the buzzer if we do it very simply and in a blocking manner.

    Michaels-MBP-10:stm32 michael$ DEFMT_LOG=trace cargo run-ex buzzer
        Blocking waiting for file lock on build directory
       Compiling defmt-macros v0.3.2
       Compiling defmt v0.3.2
       Compiling panic-probe v0.3.0
       Compiling defmt-rtt v0.3.2
       Compiling stm32wlxx-hal v0.6.1 (/Volumes/data/4_github/learn-rust/100-rust-snippets/stm32/hal)
       Compiling examples v0.1.0 (/Volumes/data/4_github/learn-rust/100-rust-snippets/stm32/examples)
        Finished dev [optimized + debuginfo] target(s) in 10.33s
         Running `probe-run --chip STM32WLE5JCIx --connect-under-reset target/thumbv7em-none-eabi/debug/examples/buzzer`
    (HOST) INFO  flashing program (11 pages / 11.00 KiB)
    (HOST) INFO  success!
    ────────────────────────────────────────────────────────────────────────────────
    INFO  Starting buzzer
    └─ buzzer::__cortex_m_rt_main @ examples/examples/buzzer.rs:27

    

And here we have it the result running on the target:

See the repo on as a fork of the original repos. For the lazy, here is the source embedded into this page:

    // Sounds a buzzer, will work only for TTN Generic node with STM32WL5x
    // see https://github.com/TheThingsIndustries/generic-node-se
    // The datasheet of the buzzer `MLT-7525` shows that the oscillation frequency is `2700Hz` so the period
    // is around 185us

    #![no_std]
    #![no_main]

    use defmt_rtt as _; // global logger
    use panic_probe as _; // panic handler

    use stm32wlxx_hal::{
        self as hal,
        cortex_m::{self, delay::Delay},
        gpio::{pins, Output, PinState, PortA},
        pac,
        util::new_delay,
    };

    #[hal::cortex_m_rt::entry]
    fn main() -> ! {
        let mut dp: pac::Peripherals = defmt::unwrap!(pac::Peripherals::take());
        let cp: pac::CorePeripherals = defmt::unwrap!(pac::CorePeripherals::take());

        let gpioa: PortA = PortA::split(dp.GPIOA, &mut dp.RCC);
        let mut buzzer: Output<pins::A15> =
            cortex_m::interrupt::free(|cs| Output::default(gpioa.a15, cs));

        let mut delay: Delay = new_delay(cp.SYST, &dp.RCC);

        defmt::info!("Starting buzzer");

        loop {
            for &level in &[PinState::High, PinState::Low] {
                buzzer.set_level(level);
                delay.delay_us(185);
            }
        }
    }