Buzzer basic operation

Buzzer basic operation [VIDEO]

Platform Test Tools SAM3U2 Firmware nRF51422 Firmware Software
MPG1
MPG2
USB RS-232 Converter Master Branch
Buzzer Basic
AP2 Emulator TeraTerm

Prerequisite Modules

API Description

A simple and common audio source in an embedded system is a piezoelectric buzzer since they can be easily driven with a square wave directly from the processor with very minimal current draw. They will reproduce tones in the full audible range of a human ear (about 50Hz to 15kHz).

The challenge in creating audio with a microcontroller is the various calculations needed to get the actual frequency correct, and then generating a constant frequency square wave without impacting the rest of the program. Therefore an API that does these things is very useful. If you are following along sequentially in the modules, this is the first task that will make use of one of the SAM3U2’s peripherals. If you explore the firmware, you will not find any code that toggles the output lines to the buzzer directly. All output is handled by the peripheral that is simply set up with the frequency and duty cycle required to create the audio signal.

Type Definitions
There are no unique types defined for the audio API, but constants are defined in configuration.h that assign names BUZZER1 and BUZZER2 to the buzzers and the appropriate hardware pins. BUZZER2 is only present on the ASCII LCD development board, and it is on the left side of the board.


Public Functions
The following functions are defined in the board-specific.c file (mpgl1-ehdw-x.c or mpgl2-ehdw-x.c). They are quite straight forward so they do not require their own files. The functions may be used by any application in the system.

  • void PWMAudioSetFrequency(u32 u32Channel_, u16 u16Frequency_) – Configures the buzzer with the desired frequency. Parameter u32Channel_ is either BUZZER1 or BUZZER2; u16Frequency_ is in Hertz and should be in the range 100 – 20,000 though higher and lower frequencies are allowed. The buzzer remains in its current on or off state.
  • void PWMAudioOn(u32 u32Channel_) – Turns on the buzzer specified in u32Channel_. The buzzer will run at whatever frequency it was last configured to. If the buzzer is already on, it will stay on.
  • void PWMAudioOff(u32 u32Channel_) – Turns off the buzzer specified in u32Channel_. If the buzzer is already off, it will stay off.

Examples

Start with the Master code branch from GitHub. Try toggling a 500Hz tone on when BUTTON0 is pressed.

In UserAppInitialize() add this line:

  PWMAudioSetFrequency(BUZZER1, 500);

In UserAppSM_Idle(), add the following:

  if(IsButtonPressed(BUTTON0))
  {
    PWMAudioOn(BUZZER1);
  }
  else
  {
    PWMAudioOff(BUZZER1);
  } 

Build and run the code. Press and hold BUTTON0 and you should hear the tone. If you have an oscilloscope, you could probe the buzzer line and see the output.

As you can see, using the API is very easy. The main thing to watch out for is that you do not repeatedly call PWMAudioSetFrequency() because that will reset the peripheral registers and cause audio glitches.

Exercise

In this exercise you will assign a tone to each of the system buttons that plays while the button is held. Two tones may NOT be played at the same time on the same buzzer, however the ASCII LCD board can play two different tones at the same time (one on each speaker). To keep this example simple, we will only use BUZZER1. If more than one button is pressed, the last button pressed will set the current tone.

Replace the example code in UserAppSM_Idle() with a call to WasButtonPressed(BUTTON0). In the function include a call to PWMAudioSetFrequency() to set BUZZER1 frequency to 262Hz.

  if(WasButtonPressed(BUTTON0))
  {
    ButtonAcknolwedge(BUTTON0);
    PWMAudioSetFrequency(BUZZER1, 262);
  }

Add a call to PWMAudioOn to turn on the buzzer if BUTTON0 is pressed or turn it off if it is not pressed.

  if(IsButtonPressed(BUTTON0))
  {
    PWMAudioOn(BUZZER1);
  }

Build and test the code. Try halting the code while the buzzer is on. You should notice that with the processor halted, the buzzer is still active. Even though the peripheral is on the microcontroller, it is not halted when the main process is halted so it will keep generating the tone.

Copy the WasButtonPressed() code and update for BUTTON1. Use 294Hz for the frequency set here.

  if(WasButtonPressed(BUTTON1))
  {
    ButtonAcknowledge(BUTTON1);
    PWMAudioSetFrequency(BUZZER1, 294);
  }

ASCII LCD board only: Copy the code twice more for BUTTON2 and BUTTON3 and set frequencies 330Hz and 392Hz, respectively.

  if(WasButtonPressed(BUTTON2))
  {
    ButtonAcknowledge(BUTTON2);
    PWMAudioSetFrequency(BUZZER1, 330);
  }

  if(WasButtonPressed(BUTTON3))
  {
    ButtonAcknowledge(BUTTON3);
    PWMAudioSetFrequency(BUZZER1, 392);
  }

Add code to check if any of the BUTTONS are on to ensure the tone is active for any button.

  /* Tone is on as long as button is pressed */
  if( IsButtonPressed(BUTTON0) || IsButtonPressed(BUTTON1) ||
      IsButtonPressed(BUTTON2) || IsButtonPressed(BUTTON3) )
  {
    PWMAudioOn(BUZZER1);
  }
  else
  {
    PWMAudioOff(BUZZER1);    
  }

Build and test the code. You should be able to play “Mary had a little Lamb” on the ASCII board with the frequencies that have been set.

BUTTON2, BUTTON1, BUTTON0, BUTTON1, BUTTON2, BUTTON2, BUTTON2,
BUTTON1, BUTTON1, BUTTON1, 
BUTTON2, BUTTON3, BUTTON3,
BUTTON2, BUTTON1, BUTTON0, BUTTON1, BUTTON2, BUTTON2, BUTTON2, 
BUTTON2, BUTTON1, BUTTON1, BUTTON2, BUTTON1, BUTTON0
[STATUS: RELEASED. LAST UPDATE: 2016-MAR-06]

*** ENGENUICS WILL NOT BE ABLE TO SHIP PRODUCTS BETWEEN MAY 26 AND JUNE 26, 2017 ***