Documents » Pololu AVR Library Command Reference »4. Orangutan Buzzer: Beeps and MusicThe OrangutanBuzzer class and the C functions in this section allow various sounds to be played on the buzzer of the LV-168 or 3pi, from simple beeps to complex tunes. The buzzer is controlled using one of the Timer1 PWM outputs, so it will conflict with any other uses of Timer1. Note durations are timed using a Timer1 overflow interrupt, which will briefly pause your main program at the frequency of the sound. In most cases, the interrupt-handling routine is very short. However, when playing a sequence of notes in PLAY_AUTOMATIC mode with the play() command, longer interrupts occur between notes. It is important to take this into account when writing timing-critical code. For a higher level overview of this library and example programs that show how this library can be used, please see Section 5.b of the guide to Programming Orangutans from the Arduino Environment or Section 6.d of the Pololu AVR C/C++ Library User’s Guide. ReferenceC++ and Arduino methods are shown in red. C functions are shown in green. static void OrangutanBuzzer::playFrequency(unsigned int frequency, unsigned int duration, unsigned char volume) void play_frequency(unsigned int freq, unsigned int duration, unsigned char volume) This method will play the specified frequency (in Hz or 0.1 Hz) for the specified duration (in ms). frequency must be between 40 Hz and 10 kHz. If the most significant bit of frequency is set, the frequency played is the value of the lower 15 bits of frequency in units of 0.1 Hz. Therefore, you can play a frequency of 44.5 Hz by using a frequency of DIV_BY_10 | 445. If the most significant bit of frequency is not set, the units for frequency are Hz. volume controls the buzzer volume, with 15 being the loudest and 0 being the quietest. Example// play a 6 kHz note for 250 ms at half volume OrangutanBuzzer::playFrequency(6000, 250, 7); // wait for buzzer to finish playing the note while (OrangutanBuzzer::isPlaying()); // play a 44.5 Hz note for 1 s at full volume OrangutanBuzzer::playFrequency(DIV_BY_10 | 445, 1000, 15); // wait for buzzer to finish playing the note // (or just use a 1000 ms delay) while (OrangutanBuzzer::isPlaying()); Caution: frequency*duration/1000 must be no greater than 0xFFFF (65535). This means you can’t use a max duration of 65535 ms for frequencies greater than 1 kHz. For example, the maximum duration you can use for a frequency of 10 kHz is 6553 ms. If you use a duration longer than this, you will produce an integer overflow that can result in unexpected behavior. static void OrangutanBuzzer::playNote(unsigned char note, unsigned int duration, unsigned char volume) void play_note(unsigned char note, unsigned int duration, unsigned char volume); This method will play the specified note for the specified duration (in ms). volume controls the buzzer volume, with 15 being the loudest and 0 being the quietest. The note argument is an enumeration for the notes of the equal tempered scale (ETS): Note MacrosTo make it easier for you to specify notes in your code, this library defines the following macros: // x will determine the octave of the note #define C( x ) ( 0 + x*12 ) #define C_SHARP( x ) ( 1 + x*12 ) #define D_FLAT( x ) ( 1 + x*12 ) #define D( x ) ( 2 + x*12 ) #define D_SHARP( x ) ( 3 + x*12 ) #define E_FLAT( x ) ( 3 + x*12 ) #define E( x ) ( 4 + x*12 ) #define F( x ) ( 5 + x*12 ) #define F_SHARP( x ) ( 6 + x*12 ) #define G_FLAT( x ) ( 6 + x*12 ) #define G( x ) ( 7 + x*12 ) #define G_SHARP( x ) ( 8 + x*12 ) #define A_FLAT( x ) ( 8 + x*12 ) #define A( x ) ( 9 + x*12 ) #define A_SHARP( x ) ( 10 + x*12 ) #define B_FLAT( x ) ( 10 + x*12 ) #define B( x ) ( 11 + x*12 ) // 255 (silences buzzer for the note duration) #define SILENT_NOTE 0xFF // e.g. frequency = 445 | DIV_BY_10 // gives a frequency of 44.5 Hz #define DIV_BY_10 (1 << 15) static void OrangutanBuzzer::play(const char* sequence) void play(const char* sequence) This method plays the specified sequence of notes. If the play mode is PLAY_AUTOMATIC, the sequence of notes will play with no further action required by the user. If the play mode is PLAY_CHECK, the user will need to call playCheck() in the main loop to initiate the playing of each new note in the sequence. The play mode can be changed while the sequence is playing. The sequence syntax is modeled after the PLAY commands in GW-BASIC, with just a few differences. The notes are specified by the characters C, D, E, F, G, A, and B, and they are played by default as “quarter notes” with a length of 500 ms. This corresponds to a tempo of 120 beats/min. Other durations can be specified by putting a number immediately after the note. For example, C8 specifies C played as an eighth note, with half the duration of a quarter note. The special note R plays a rest (no sound). The sequence parser is case-insensitive and ignore spaces, which may be used to format your music nicely. Various control characters alter the sound:
Examples:
// play a C major scale up and back down:
OrangutanBuzzer::play("!L16 V8 cdefgab>cbagfedc");
// the first few measures of Bach's fugue in D-minor
OrangutanBuzzer::play("!T240 L8 a gafaeada c+adaeafa >aa>bac#ada c#adaeaf4");
static void playFromProgramSpace(const char* sequence) void play_from_program_space(const char* sequence) A version of play() that takes a pointer to program space instead of RAM. This is desirable since RAM is limited and the string must be stored in program space anyway. Example:
#include <avr/pgmspace.h>
const char melody[] PROGMEM = "!L16 V8 cdefgab>cbagfedc";
void someFunction()
{
OrangutanBuzzer::playFromProgramSpace(melody);
}
static void OrangutanBuzzer::playMode(unsigned char mode) void play_mode(char mode) This method lets you determine whether the notes of the play() sequence are played automatically in the background or are driven by the playCheck() method. If mode is PLAY_AUTOMATIC, the sequence will play automatically in the background, driven by the Timer1 overflow interrupt. The interrupt will take a considerable amount of time to execute when it starts the next note in the sequence playing, so it is recommended that you do not use automatic-play if you cannot tolerate being interrupted for more than a few microseconds. If mode is PLAY_CHECK, you can control when the next note in the sequence is played by calling the playCheck() method at acceptable points in your main loop. If your main loop has substantial delays, it is recommended that you use automatic-play mode rather than play-check mode. Note that the play mode can be changed while the sequence is being played. static void OrangutanBuzzer::playCheck() unsigned char play_check() This method only needs to be called if you are in PLAY_CHECK mode. It checks to see whether it is time to start another note in the sequence initiated by play(), and starts it if so. If it is not yet time to start the next note, this method returns without doing anything. Call this as often as possible in your main loop to avoid delays between notes in the sequence. static unsigned char isPlaying() unsigned char is_playing() This method returns 1 (true) if the buzzer is currently playing a note/frequency. Otherwise, it returns 0 (false). You can poll this method to determine when it’s time to play the next note in a sequence, or you can use it as the argument to a delay loop to wait while the buzzer is busy. static void OrangutanBuzzer::stopPlaying() void stop_playing() This method will immediately silence the buzzer and terminate any note/frequency/melody that is currently playing. |
|
Home
|
Contact
|
About
|
Forum
|
US toll free: 1-877-7-POLOLU |