3.b.1. Command 152: Play Note

Effect: Plays the desired note immediately, where note is an 8-bit encoding of the frequencies of the equal-tempered scale centered around A4 = 440 Hz. Note 0xFF is defined to be a “silent note,” which merely silences the buzzer for a desired period of time. Notes that produce frequencies less than 40 Hz or greater than 10 kHz are not allowed and will result in the closest note that is allowed. Duration is a 16-bit value specified in ms. In C, the notes can be enumerated as follows:

    #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 ) 
    	
    #define SILENT_NOTE   0xFF

The parameter x represents the octave of the note. Typically, x will have a value of 4 – 6. The frequency of a note can be obtained using the formula:

    freq(note) = 440 Hz * 2 ((note – 57) / 12)

If the buzzer is currently playing when this command is received, this command will take precedence and overwrite the current buzzer action. For example, if a melody was playing, the note specified by this command will interrupt the melody and after the note is through the melody will not continue. As such, if you wish to stream a sequence of notes to the mega168 using this command, you must time the issuance of the commands on the mega644 so that each note doesn’t just overwrite the previous. This command will not queue up the notes if called repeatedly.

It is important to note that there is a restriction on the duration of any notes whose frequencies are greater than 1 kHz. The product of the duration (in ms) and the frequency (in kHz) must be no greater than 0xFFFF (65,535). If you attempt to play a frequency of 10 kHz, for example, the maximum duration you can specify is 6553 ms. If you specify a longer duration there will be an integer overflow and the resulting duration of the note will not be what you specified. If you wish to play a 10 kHz frequency for longer than 6.5 seconds, you can accomplish this by stringing together multiple play-note commands.

Bonus feature: If you don’t need it for sound, the buzzer can be used as an extra timer. You can send a command to play a silent note (0xFF) for a specified duration. After that duration has elapsed, the mega168’s status byte will reflect that the buzzer is now finished and the attention line will be set. A silent note disconnects the buzzer so that it makes no sound, however it runs the buzzer PWM at a frequency of 1 kHz and is accurate to the nearest 2 milliseconds.

Values sent: note (8 bits), duration (16 bits)

command byte = 152 | (MSB data byte 3 << 2) | (MSB data byte 2 << 1) | MSB data byte 1

data byte 1 = 7 lower bits of note byte

data byte 2 = most significant byte of duration word (minus the MSB, which is in the command byte)

data byte 3 = least significant byte of duration word (minus the MSB, which is in the command byte)