This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

PWM with a piezo buzzer

I'm trying to get some sound out of a piezo buzzer using the PWM library here:

github.com/.../nrf51-pwm-library

My buzzer has a resonant frequency of 2,730Hz. The buzzer doesn't have its own driver, I need to generate the wave for it. What changes do I need to make to main_sin.c to get that frequency?

Here's what I've tried so far.

int main(void)
{
    uint32_t counter = 0;
    
    nrf_pwm_config_t pwm_config = PWM_DEFAULT_CONFIG;
    
    pwm_config.mode             = PWM_MODE_BUZZER_64; // Was PWM_MODE_LED_100
    pwm_config.num_channels     = 1; // Was 3

    // One channel only, on pin 14
    pwm_config.gpio_num[0]      = 14; // Was 8
    // pwm_config.gpio_num[1]      = 8;
    // pwm_config.gpio_num[2]      = 10;
    
    // Initialize the PWM library
    nrf_pwm_init(&pwm_config);

    while (true)
    {
        // Update the 3 outputs with out of phase sine waves
        nrf_pwm_set_value(0, sin_table[counter]);
        // nrf_pwm_set_value(1, sin_table[(counter + 33) % 100]);
        // nrf_pwm_set_value(2, sin_table[(counter + 66) % 100]);
        counter = (counter + 1) % 100;
        
        // Add a delay to control the speed of the sine wave
        // 125 kHz is one wave every 0.000008s or 0.008ms or 8us, so why is this 8000us?
        // nrf_delay_us(8000);

        // If 8000us gets us 125kHz, then 366,300 should get us 2730Hz.
        nrf_delay_us(366300);
    }
}

As the comments above show, I'm confused about how this delay relates to the PWM frequency.

I'd also like to be executing other code while the buzzer is sounding and thought that PPI made this possible. So why the while() loop here at all?

Parents
  • Eliot,

    Loaded your code on a pca10001 with no softdevice using sdk 5.1.0.36092.

    I placed your code inside of the uart application and just included nrf_pwm.c to the lib folder and copied your main over.

    I first verified that your source would generate 2.730kHz signal and it did without any modification.

    Then I added the while loop section and the duty cycle adjusted according to the formula and sin table.

    I am attaching the screen shots.

    tek00002 => manually setting duty tek00003 => using sin table formula tek00004 => using sin table formula

    pics 00003 & 00004 show the duty cycle varying.

    So your code appears to be running fine. Have you or can you try on an evaluation board. That would rule out the software and point to an hardware issue.

    tek00002.png

    tek00003.png

    tek00004.png

Reply
  • Eliot,

    Loaded your code on a pca10001 with no softdevice using sdk 5.1.0.36092.

    I placed your code inside of the uart application and just included nrf_pwm.c to the lib folder and copied your main over.

    I first verified that your source would generate 2.730kHz signal and it did without any modification.

    Then I added the while loop section and the duty cycle adjusted according to the formula and sin table.

    I am attaching the screen shots.

    tek00002 => manually setting duty tek00003 => using sin table formula tek00004 => using sin table formula

    pics 00003 & 00004 show the duty cycle varying.

    So your code appears to be running fine. Have you or can you try on an evaluation board. That would rule out the software and point to an hardware issue.

    tek00002.png

    tek00003.png

    tek00004.png

Children
Related