PololuBuzzer library
PololuBuzzer.cpp
1 // Copyright Pololu Corporation. For more information, see http://www.pololu.com/
2 
3 #include <avr/interrupt.h>
4 #include "PololuBuzzer.h"
5 
6 #ifdef __AVR_ATmega32U4__
7 
8 // PD7 (OC4D)
9 #define BUZZER_DDR DDRD
10 #define BUZZER (1 << PORTD7)
11 
12 #define TIMER4_CLK_8 0x4 // 2 MHz
13 
14 #define ENABLE_TIMER_INTERRUPT() TIMSK4 = (1 << TOIE4)
15 #define DISABLE_TIMER_INTERRUPT() TIMSK4 = 0
16 
17 #else // 168P or 328P
18 
19 // PD3 (OC2B)
20 #define BUZZER_DDR DDRD
21 #define BUZZER (1 << PORTD3)
22 
23 #define TIMER2_CLK_32 0x3 // 500 kHz
24 
25 static const unsigned int cs2_divider[] = {0, 1, 8, 32, 64, 128, 256, 1024};
26 
27 #define ENABLE_TIMER_INTERRUPT() TIMSK2 = (1 << TOIE2)
28 #define DISABLE_TIMER_INTERRUPT() TIMSK2 = 0
29 
30 #endif
31 
32 unsigned char buzzerInitialized = 0;
33 volatile unsigned char buzzerFinished = 1; // flag: 0 while playing
34 const char * volatile buzzerSequence = 0;
35 
36 // declaring these globals as static means they won't conflict
37 // with globals in other .cpp files that share the same name
38 static volatile unsigned int buzzerTimeout = 0; // tracks buzzer time limit
39 static volatile char play_mode_setting = PLAY_AUTOMATIC;
40 
41 extern volatile unsigned char buzzerFinished; // flag: 0 while playing
42 extern const char * volatile buzzerSequence;
43 
44 
45 static volatile unsigned char use_program_space; // boolean: true if we should
46  // use program space
47 
48 // music settings and defaults
49 static volatile unsigned char octave = 4; // the current octave
50 static volatile unsigned int whole_note_duration = 2000; // the duration of a whole note
51 static volatile unsigned int note_type = 4; // 4 for quarter, etc
52 static volatile unsigned int duration = 500; // the duration of a note in ms
53 static volatile unsigned int volume = 15; // the note volume
54 static volatile unsigned char staccato = 0; // true if playing staccato
55 
56 // staccato handling
57 static volatile unsigned char staccato_rest_duration; // duration of a staccato rest,
58  // or zero if it is time to play a note
59 
60 static void nextNote();
61 
62 #ifdef __AVR_ATmega32U4__
63 
64 // Timer4 overflow interrupt
65 ISR (TIMER4_OVF_vect)
66 {
67  if (buzzerTimeout-- == 0)
68  {
69  DISABLE_TIMER_INTERRUPT();
70  sei(); // re-enable global interrupts (nextNote() is very slow)
71  TCCR4B = (TCCR4B & 0xF0) | TIMER4_CLK_8; // select IO clock
72  unsigned int top = (F_CPU/16) / 1000; // set TOP for freq = 1 kHz:
73  TC4H = top >> 8; // top 2 bits... (TC4H temporarily stores top 2 bits of 10-bit accesses)
74  OCR4C = top; // and bottom 8 bits
75  TC4H = 0; // 0% duty cycle: top 2 bits...
76  OCR4D = 0; // and bottom 8 bits
77  buzzerFinished = 1;
78  if (buzzerSequence && (play_mode_setting == PLAY_AUTOMATIC))
79  nextNote();
80  }
81 }
82 
83 #else
84 
85 // Timer2 overflow interrupt
86 ISR (TIMER2_OVF_vect)
87 {
88  if (buzzerTimeout-- == 0)
89  {
90  DISABLE_TIMER_INTERRUPT();
91  sei(); // re-enable global interrupts (nextNote() is very slow)
92  TCCR2B = (TCCR2B & 0xF8) | TIMER2_CLK_32; // select IO clock
93  OCR2A = (F_CPU/64) / 1000; // set TOP for freq = 1 kHz
94  OCR2B = 0; // 0% duty cycle
95  buzzerFinished = 1;
96  if (buzzerSequence && (play_mode_setting == PLAY_AUTOMATIC))
97  nextNote();
98  }
99 }
100 
101 #endif
102 
103 // this is called by playFrequency()
104 inline void PololuBuzzer::init()
105 {
106  if (!buzzerInitialized)
107  {
108  buzzerInitialized = 1;
109  init2();
110  }
111 }
112 
113 // initializes timer4 (32U4) or timer2 (328P) for buzzer control
114 void PololuBuzzer::init2()
115 {
116  DISABLE_TIMER_INTERRUPT();
117 
118 #ifdef __AVR_ATmega32U4__
119  TCCR4A = 0x00; // bits 7 and 6 clear: normal port op., OC4A disconnected
120  // bits 5 and 4 clear: normal port op., OC4B disconnected
121  // bit 3 clear: no force output compare for channel A
122  // bit 2 clear: no force output compare for channel B
123  // bit 1 clear: disable PWM for channel A
124  // bit 0 clear: disable PWM for channel B
125 
126  TCCR4B = 0x04; // bit 7 clear: disable PWM inversion
127  // bit 6 clear: no prescaler reset
128  // bits 5 and 4 clear: dead time prescaler 1
129  // bit 3 clear, 2 set, 1-0 clear: timer clock = CK/8
130 
131  TCCR4C = 0x09; // bits 7 and 6 clear: normal port op., OC4A disconnected
132  // bits 5 and 4 clear: normal port op., OC4B disconnected
133  // bit 3 set, 2 clear: clear OC4D on comp match when upcounting,
134  // set OC4D on comp match when downcounting
135  // bit 1 clear: no force output compare for channel D
136  // bit 0 set: enable PWM for channel 4
137 
138  TCCR4D = 0x01; // bit 7 clear: disable fault protection interrupt
139  // bit 6 clear: disable fault protection mode
140  // bit 5 clear: disable fault protection noise canceler
141  // bit 4 clear: falling edge triggers fault
142  // bit 3 clear: disable fault protection analog comparator
143  // bit 2 clear: fault protection interrupt flag
144  // bit 1 clear, 0 set: select waveform generation mode,
145  // phase- and frequency-correct PWM, TOP = OCR4C,
146  // OCR4D set at BOTTOM, TOV4 flag set at BOTTOM
147 
148  // This sets timer 4 to run in phase- and frequency-correct PWM mode,
149  // where TOP = OCR4C, OCR4D is updated at BOTTOM, TOV1 Flag is set on BOTTOM.
150  // OC4D is cleared on compare match when upcounting, set on compare
151  // match when downcounting; OC4A and OC4B are disconnected.
152 
153  unsigned int top = (F_CPU/16) / 1000; // set TOP for freq = 1 kHz:
154  TC4H = top >> 8; // top 2 bits...
155  OCR4C = top; // and bottom 8 bits
156  TC4H = 0; // 0% duty cycle: top 2 bits...
157  OCR4D = 0; // and bottom 8 bits
158 #else
159  TCCR2A = 0x21; // bits 7 and 6 clear: normal port op., OC2A disconnected
160  // bit 5 set, 4 clear: clear OC2B on comp match when upcounting,
161  // set OC2B on comp match when downcounting
162  // bits 3 and 2: not used
163  // bit 1 clear, 0 set: combine with bit 3 of TCCR2B...
164 
165  TCCR2B = 0x0B; // bit 7 clear: no force output compare for channel A
166  // bit 6 clear: no force output compare for channel B
167  // bits 5 and 4: not used
168  // bit 3 set: combine with bits 1 and 0 of TCCR2A to
169  // select waveform generation mode 5, phase-correct PWM,
170  // TOP = OCR2A, OCR2B set at TOP, TOV2 flag set at BOTTOM
171  // bit 2 clear, 1-0 set: timer clock = clkT2S/32
172 
173  // This sets timer 2 to run in phase-correct PWM mode, where TOP = OCR2A,
174  // OCR2B is updated at TOP, TOV2 Flag is set on BOTTOM. OC2B is cleared
175  // on compare match when upcounting, set on compare match when downcounting;
176  // OC2A is disconnected.
177  // Note: if the PWM frequency and duty cycle are changed, the first
178  // cycle of the new frequency will be at the old duty cycle, since
179  // the duty cycle (OCR2B) is not updated until TOP.
180 
181 
182  OCR2A = (F_CPU/64) / 1000; // set TOP for freq = 1 kHz
183  OCR2B = 0; // 0% duty cycle
184 #endif
185 
186  BUZZER_DDR |= BUZZER; // buzzer pin set as an output
187  sei();
188 }
189 
190 
191 // Set up the timer to play the desired frequency (in Hz or .1 Hz) for the
192 // the desired duration (in ms). Allowed frequencies are 40 Hz to 10 kHz.
193 // volume controls buzzer volume, with 15 being loudest and 0 being quietest.
194 // Note: frequency*duration/1000 must be less than 0xFFFF (65535). This
195 // means that you can't use a max duration of 65535 ms for frequencies
196 // greater than 1 kHz. For example, the max duration you can use for a
197 // frequency of 10 kHz is 6553 ms. If you use a duration longer than this,
198 // you will cause an integer overflow that produces unexpected behavior.
199 void PololuBuzzer::playFrequency(unsigned int freq, unsigned int dur,
200  unsigned char volume)
201 {
202  init(); // initializes the buzzer if necessary
203  buzzerFinished = 0;
204 
205  unsigned int timeout;
206  unsigned char multiplier = 1;
207 
208  if (freq & DIV_BY_10) // if frequency's DIV_BY_10 bit is set
209  { // then the true frequency is freq/10
210  multiplier = 10; // (gives higher resolution for small freqs)
211  freq &= ~DIV_BY_10; // clear DIV_BY_10 bit
212  }
213 
214  unsigned char min = 40 * multiplier;
215  if (freq < min) // min frequency allowed is 40 Hz
216  freq = min;
217  if (multiplier == 1 && freq > 10000)
218  freq = 10000; // max frequency allowed is 10kHz
219 
220 #ifdef __AVR_ATmega32U4__
221  uint8_t dividerExponent = 0;
222  uint32_t dividedClk = F_CPU/2;
223 
224  // The divided clock cannot be greater than or equal to 1024x the target
225  // frequency; otherwise, the timer's TOP value would overflow the max for a
226  // 10-bit number.
227  // Because the calculation for the TOP value will round to the nearest int,
228  // we use 1023.5 (which would round up to 1024) to calculate the smallest
229  // divided clock that would overflow.
230  uint32_t overflowClk = ((uint32_t)2047 * freq + multiplier) / 2 / multiplier;
231 
232  while (dividedClk >= overflowClk)
233  {
234  dividerExponent++;
235  dividedClk >>= 1;
236  }
237 #else
238  uint8_t newCS2 = 2; // try prescaler divider of 8 first (minimum necessary for 10 kHz)
239  uint32_t dividedClk = F_CPU/2 / cs2_divider[newCS2];
240 
241  // The divided clock cannot be greater than or equal to 256x the target
242  // frequency; otherwise, the timer's TOP value would overflow the max for an
243  // 8-bit number.
244  // Because the calculation for the TOP value will round to the nearest int,
245  // we use 255.5 (which would round up to 256) to calculate the smallest
246  // divided clock that would overflow.
247  uint32_t overflowClk = ((uint32_t)511 * freq + multiplier) / 2 / multiplier;
248 
249  while (dividedClk >= overflowClk)
250  {
251  newCS2++;
252  dividedClk = F_CPU/2 / cs2_divider[newCS2];
253  }
254 #endif
255 
256  uint16_t top = ((dividedClk * multiplier) + (freq >> 1)) / freq;
257 
258  // set timeout (duration):
259  if (multiplier == 10)
260  freq = (freq + 5) / 10;
261 
262  if (freq == 1000)
263  timeout = dur; // duration for silent notes is exact
264  else
265  timeout = (unsigned int)((long)dur * freq / 1000);
266 
267  if (volume > 15)
268  volume = 15;
269 
270  DISABLE_TIMER_INTERRUPT(); // disable interrupts while writing to registers
271 
272 #ifdef __AVR_ATmega32U4__
273  TCCR4B = (TCCR4B & 0xF0) | (dividerExponent + 1); // select timer 4 clock prescaler: divider = 2^n if CS4 = n+1
274  TC4H = top >> 8; // set timer 4 pwm frequency: top 2 bits...
275  OCR4C = top; // and bottom 8 bits
276  unsigned int width = top >> (16 - volume); // set duty cycle (volume):
277  TC4H = width >> 8; // top 2 bits...
278  OCR4D = width; // and bottom 8 bits
279  buzzerTimeout = timeout; // set buzzer duration
280 
281  TIFR4 |= 0xFF; // clear any pending t4 overflow int.
282 #else
283  TCCR2B = (TCCR2B & 0xF8) | newCS2; // select timer 2 clock prescaler
284  OCR2A = top; // set timer 2 pwm frequency
285  OCR2B = top >> (16 - volume); // set duty cycle (volume)
286  buzzerTimeout = timeout; // set buzzer duration
287 
288  TIFR2 |= 0xFF; // clear any pending t2 overflow int.
289 #endif
290 
291  ENABLE_TIMER_INTERRUPT();
292 }
293 
294 
295 
296 // Determine the frequency for the specified note, then play that note
297 // for the desired duration (in ms). This is done without using floats
298 // and without having to loop. volume controls buzzer volume, with 15 being
299 // loudest and 0 being quietest.
300 // Note: frequency*duration/1000 must be less than 0xFFFF (65535). This
301 // means that you can't use a max duration of 65535 ms for frequencies
302 // greater than 1 kHz. For example, the max duration you can use for a
303 // frequency of 10 kHz is 6553 ms. If you use a duration longer than this,
304 // you will cause an integer overflow that produces unexpected behavior.
305 void PololuBuzzer::playNote(unsigned char note, unsigned int dur,
306  unsigned char volume)
307 {
308  // note = key + octave * 12, where 0 <= key < 12
309  // example: A4 = A + 4 * 12, where A = 9 (so A4 = 57)
310  // A note is converted to a frequency by the formula:
311  // Freq(n) = Freq(0) * a^n
312  // where
313  // Freq(0) is chosen as A4, which is 440 Hz
314  // and
315  // a = 2 ^ (1/12)
316  // n is the number of notes you are away from A4.
317  // One can see that the frequency will double every 12 notes.
318  // This function exploits this property by defining the frequencies of the
319  // 12 lowest notes allowed and then doubling the appropriate frequency
320  // the appropriate number of times to get the frequency for the specified
321  // note.
322 
323  // if note = 16, freq = 41.2 Hz (E1 - lower limit as freq must be >40 Hz)
324  // if note = 57, freq = 440 Hz (A4 - central value of ET Scale)
325  // if note = 111, freq = 9.96 kHz (D#9 - upper limit, freq must be <10 kHz)
326  // if note = 255, freq = 1 kHz and buzzer is silent (silent note)
327 
328  // The most significant bit of freq is the "divide by 10" bit. If set,
329  // the units for frequency are .1 Hz, not Hz, and freq must be divided
330  // by 10 to get the true frequency in Hz. This allows for an extra digit
331  // of resolution for low frequencies without the need for using floats.
332 
333  unsigned int freq = 0;
334  unsigned char offset_note = note - 16;
335 
336  if (note == SILENT_NOTE || volume == 0)
337  {
338  freq = 1000; // silent notes => use 1kHz freq (for cycle counter)
339  playFrequency(freq, dur, 0);
340  return;
341  }
342 
343  if (note <= 16)
344  offset_note = 0;
345  else if (offset_note > 95)
346  offset_note = 95;
347 
348  unsigned char exponent = offset_note / 12;
349 
350  // frequency table for the lowest 12 allowed notes
351  // frequencies are specified in tenths of a Hertz for added resolution
352  switch (offset_note - exponent * 12) // equivalent to (offset_note % 12)
353  {
354  case 0: // note E1 = 41.2 Hz
355  freq = 412;
356  break;
357  case 1: // note F1 = 43.7 Hz
358  freq = 437;
359  break;
360  case 2: // note F#1 = 46.3 Hz
361  freq = 463;
362  break;
363  case 3: // note G1 = 49.0 Hz
364  freq = 490;
365  break;
366  case 4: // note G#1 = 51.9 Hz
367  freq = 519;
368  break;
369  case 5: // note A1 = 55.0 Hz
370  freq = 550;
371  break;
372  case 6: // note A#1 = 58.3 Hz
373  freq = 583;
374  break;
375  case 7: // note B1 = 61.7 Hz
376  freq = 617;
377  break;
378  case 8: // note C2 = 65.4 Hz
379  freq = 654;
380  break;
381  case 9: // note C#2 = 69.3 Hz
382  freq = 693;
383  break;
384  case 10: // note D2 = 73.4 Hz
385  freq = 734;
386  break;
387  case 11: // note D#2 = 77.8 Hz
388  freq = 778;
389  break;
390  }
391 
392  if (exponent < 7)
393  {
394  freq = freq << exponent; // frequency *= 2 ^ exponent
395  if (exponent > 1) // if the frequency is greater than 160 Hz
396  freq = (freq + 5) / 10; // we don't need the extra resolution
397  else
398  freq += DIV_BY_10; // else keep the added digit of resolution
399  }
400  else
401  freq = (freq * 64 + 2) / 5; // == freq * 2^7 / 10 without int overflow
402 
403  if (volume > 15)
404  volume = 15;
405  playFrequency(freq, dur, volume); // set buzzer this freq/duration
406 }
407 
408 
409 
410 // Returns 1 if the buzzer is currently playing, otherwise it returns 0
411 unsigned char PololuBuzzer::isPlaying()
412 {
413  return !buzzerFinished || buzzerSequence != 0;
414 }
415 
416 
417 // Plays the specified sequence of notes. If the play mode is
418 // PLAY_AUTOMATIC, the sequence of notes will play with no further
419 // action required by the user. If the play mode is PLAY_CHECK,
420 // the user will need to call playCheck() in the main loop to initiate
421 // the playing of each new note in the sequence. The play mode can
422 // be changed while the sequence is playing.
423 // This is modeled after the PLAY commands in GW-BASIC, with just a
424 // few differences.
425 //
426 // The notes are specified by the characters C, D, E, F, G, A, and
427 // B, and they are played by default as "quarter notes" with a
428 // length of 500 ms. This corresponds to a tempo of 120
429 // beats/min. Other durations can be specified by putting a number
430 // immediately after the note. For example, C8 specifies C played as an
431 // eighth note, with half the duration of a quarter note. The special
432 // note R plays a rest (no sound).
433 //
434 // Various control characters alter the sound:
435 // '>' plays the next note one octave higher
436 //
437 // '<' plays the next note one octave lower
438 //
439 // '+' or '#' after a note raises any note one half-step
440 //
441 // '-' after a note lowers any note one half-step
442 //
443 // '.' after a note "dots" it, increasing the length by
444 // 50%. Each additional dot adds half as much as the
445 // previous dot, so that "A.." is 1.75 times the length of
446 // "A".
447 //
448 // 'O' followed by a number sets the octave (default: O4).
449 //
450 // 'T' followed by a number sets the tempo (default: T120).
451 //
452 // 'L' followed by a number sets the default note duration to
453 // the type specified by the number: 4 for quarter notes, 8
454 // for eighth notes, 16 for sixteenth notes, etc.
455 // (default: L4)
456 //
457 // 'V' followed by a number from 0-15 sets the music volume.
458 // (default: V15)
459 //
460 // 'MS' sets all subsequent notes to play staccato - each note is played
461 // for 1/2 of its allotted time, followed by an equal period
462 // of silence.
463 //
464 // 'ML' sets all subsequent notes to play legato - each note is played
465 // for its full length. This is the default setting.
466 //
467 // '!' resets all persistent settings to their defaults.
468 //
469 // The following plays a c major scale up and back down:
470 // play("L16 V8 cdefgab>cbagfedc");
471 //
472 // Here is an example from Bach:
473 // play("T240 L8 a gafaeada c+adaeafa <aa<bac#ada c#adaeaf4");
474 void PololuBuzzer::play(const char *notes)
475 {
476  DISABLE_TIMER_INTERRUPT(); // prevent this from being interrupted
477  buzzerSequence = notes;
478  use_program_space = 0;
479  staccato_rest_duration = 0;
480  nextNote(); // this re-enables the timer interrupt
481 }
482 
483 void PololuBuzzer::playFromProgramSpace(const char *notes_p)
484 {
485  DISABLE_TIMER_INTERRUPT(); // prevent this from being interrupted
486  buzzerSequence = notes_p;
487  use_program_space = 1;
488  staccato_rest_duration = 0;
489  nextNote(); // this re-enables the timer interrupt
490 }
491 
492 
493 // stop all sound playback immediately
495 {
496  DISABLE_TIMER_INTERRUPT(); // disable interrupts
497 
498 #ifdef __AVR_ATmega32U4__
499  TCCR4B = (TCCR4B & 0xF0) | TIMER4_CLK_8; // select IO clock
500  unsigned int top = (F_CPU/16) / 1000; // set TOP for freq = 1 kHz:
501  TC4H = top >> 8; // top 2 bits... (TC4H temporarily stores top 2 bits of 10-bit accesses)
502  OCR4C = top; // and bottom 8 bits
503  TC4H = 0; // 0% duty cycle: top 2 bits...
504  OCR4D = 0; // and bottom 8 bits
505 #else
506  TCCR2B = (TCCR2B & 0xF8) | TIMER2_CLK_32; // select IO clock
507  OCR2A = (F_CPU/64) / 1000; // set TOP for freq = 1 kHz
508  OCR2B = 0; // 0% duty cycle
509 #endif
510 
511  buzzerFinished = 1;
512  buzzerSequence = 0;
513 }
514 
515 // Gets the current character, converting to lower-case and skipping
516 // spaces. For any spaces, this automatically increments sequence!
517 static char currentCharacter()
518 {
519  char c = 0;
520  do
521  {
522  if(use_program_space)
523  c = pgm_read_byte(buzzerSequence);
524  else
525  c = *buzzerSequence;
526 
527  if(c >= 'A' && c <= 'Z')
528  c += 'a'-'A';
529  } while(c == ' ' && (buzzerSequence ++));
530 
531  return c;
532 }
533 
534 // Returns the numerical argument specified at buzzerSequence[0] and
535 // increments sequence to point to the character immediately after the
536 // argument.
537 static unsigned int getNumber()
538 {
539  unsigned int arg = 0;
540 
541  // read all digits, one at a time
542  char c = currentCharacter();
543  while(c >= '0' && c <= '9')
544  {
545  arg *= 10;
546  arg += c-'0';
547  buzzerSequence ++;
548  c = currentCharacter();
549  }
550 
551  return arg;
552 }
553 
554 static void nextNote()
555 {
556  unsigned char note = 0;
557  unsigned char rest = 0;
558  unsigned char tmp_octave = octave; // the octave for this note
559  unsigned int tmp_duration; // the duration of this note
560  unsigned int dot_add;
561 
562  char c; // temporary variable
563 
564  // if we are playing staccato, after every note we play a rest
565  if(staccato && staccato_rest_duration)
566  {
567  PololuBuzzer::playNote(SILENT_NOTE, staccato_rest_duration, 0);
568  staccato_rest_duration = 0;
569  return;
570  }
571 
572  parse_character:
573 
574  // Get current character
575  c = currentCharacter();
576  buzzerSequence ++;
577 
578  // Interpret the character.
579  switch(c)
580  {
581  case '>':
582  // shift the octave temporarily up
583  tmp_octave ++;
584  goto parse_character;
585  case '<':
586  // shift the octave temporarily down
587  tmp_octave --;
588  goto parse_character;
589  case 'a':
590  note = NOTE_A(0);
591  break;
592  case 'b':
593  note = NOTE_B(0);
594  break;
595  case 'c':
596  note = NOTE_C(0);
597  break;
598  case 'd':
599  note = NOTE_D(0);
600  break;
601  case 'e':
602  note = NOTE_E(0);
603  break;
604  case 'f':
605  note = NOTE_F(0);
606  break;
607  case 'g':
608  note = NOTE_G(0);
609  break;
610  case 'l':
611  // set the default note duration
612  note_type = getNumber();
613  duration = whole_note_duration/note_type;
614  goto parse_character;
615  case 'm':
616  // set music staccato or legato
617  if(currentCharacter() == 'l')
618  staccato = false;
619  else
620  {
621  staccato = true;
622  staccato_rest_duration = 0;
623  }
624  buzzerSequence ++;
625  goto parse_character;
626  case 'o':
627  // set the octave permanently
628  octave = tmp_octave = getNumber();
629  goto parse_character;
630  case 'r':
631  // Rest - the note value doesn't matter.
632  rest = 1;
633  break;
634  case 't':
635  // set the tempo
636  whole_note_duration = 60*400/getNumber()*10;
637  duration = whole_note_duration/note_type;
638  goto parse_character;
639  case 'v':
640  // set the volume
641  volume = getNumber();
642  goto parse_character;
643  case '!':
644  // reset to defaults
645  octave = 4;
646  whole_note_duration = 2000;
647  note_type = 4;
648  duration = 500;
649  volume = 15;
650  staccato = 0;
651  // reset temp variables that depend on the defaults
652  tmp_octave = octave;
653  tmp_duration = duration;
654  goto parse_character;
655  default:
656  buzzerSequence = 0;
657  return;
658  }
659 
660  note += tmp_octave*12;
661 
662  // handle sharps and flats
663  c = currentCharacter();
664  while(c == '+' || c == '#')
665  {
666  buzzerSequence ++;
667  note ++;
668  c = currentCharacter();
669  }
670  while(c == '-')
671  {
672  buzzerSequence ++;
673  note --;
674  c = currentCharacter();
675  }
676 
677  // set the duration of just this note
678  tmp_duration = duration;
679 
680  // If the input is 'c16', make it a 16th note, etc.
681  if(c > '0' && c < '9')
682  tmp_duration = whole_note_duration/getNumber();
683 
684  // Handle dotted notes - the first dot adds 50%, and each
685  // additional dot adds 50% of the previous dot.
686  dot_add = tmp_duration/2;
687  while(currentCharacter() == '.')
688  {
689  buzzerSequence ++;
690  tmp_duration += dot_add;
691  dot_add /= 2;
692  }
693 
694  if(staccato)
695  {
696  staccato_rest_duration = tmp_duration / 2;
697  tmp_duration -= staccato_rest_duration;
698  }
699 
700  // this will re-enable the timer overflow interrupt
701  PololuBuzzer::playNote(rest ? SILENT_NOTE : note, tmp_duration, volume);
702 }
703 
704 
705 // This puts play() into a mode where instead of advancing to the
706 // next note in the sequence automatically, it waits until the
707 // function playCheck() is called. The idea is that you can
708 // put playCheck() in your main loop and avoid potential
709 // delays due to the note sequence being checked in the middle of
710 // a time sensitive calculation. It is recommended that you use
711 // this function if you are doing anything that can't tolerate
712 // being interrupted for more than a few microseconds.
713 // Note that the play mode can be changed while a sequence is being
714 // played.
715 //
716 // Usage: playMode(PLAY_AUTOMATIC) makes it automatic (the
717 // default), playMode(PLAY_CHECK) sets it to a mode where you have
718 // to call playCheck().
719 void PololuBuzzer::playMode(unsigned char mode)
720 {
721  play_mode_setting = mode;
722 
723  // We want to check to make sure that we didn't miss a note if we
724  // are going out of play-check mode.
725  if(mode == PLAY_AUTOMATIC)
726  playCheck();
727 }
728 
729 
730 // Checks whether it is time to start another note, and starts
731 // it if so. If it is not yet time to start the next note, this method
732 // returns without doing anything. Call this as often as possible
733 // in your main loop to avoid delays between notes in the sequence.
734 //
735 // Returns true if it is still playing.
736 unsigned char PololuBuzzer::playCheck()
737 {
738  if(buzzerFinished && buzzerSequence != 0)
739  nextNote();
740  return buzzerSequence != 0;
741 }
SILENT_NOTE
#define SILENT_NOTE
silences buzzer for the note duration
Definition: PololuBuzzer.h:81
PololuBuzzer::stopPlaying
static void stopPlaying()
Stops any note, frequency, or melody being played.
Definition: PololuBuzzer.cpp:494
PLAY_AUTOMATIC
#define PLAY_AUTOMATIC
Specifies that the sequence of notes will play with no further action required by the user.
Definition: PololuBuzzer.h:42
PololuBuzzer::isPlaying
static unsigned char isPlaying()
Checks whether a note, frequency, or sequence is being played.
Definition: PololuBuzzer.cpp:411
PololuBuzzer::play
static void play(const char *sequence)
Plays the specified sequence of notes.
Definition: PololuBuzzer.cpp:474
DIV_BY_10
#define DIV_BY_10
frequency bit that indicates Hz/10 e.g. frequency = (445 | DIV_BY_10) gives a frequency of 44....
Definition: PololuBuzzer.h:86
PololuBuzzer::playFromProgramSpace
static void playFromProgramSpace(const char *sequence)
Plays the specified sequence of notes from program space.
Definition: PololuBuzzer.cpp:483
PololuBuzzer::playNote
static void playNote(unsigned char note, unsigned int duration, unsigned char volume)
Plays the specified note for the specified duration.
Definition: PololuBuzzer.cpp:305
PololuBuzzer::playCheck
static unsigned char playCheck()
Starts the next note in a sequence, if necessary, in PLAY_CHECK mode.
Definition: PololuBuzzer.cpp:736
PololuBuzzer::playFrequency
static void playFrequency(unsigned int freq, unsigned int duration, unsigned char volume)
Plays the specified frequency for the specified duration.
Definition: PololuBuzzer.cpp:199
PololuBuzzer.h
PololuBuzzer::playMode
static void playMode(unsigned char mode)
Controls whether play() sequence is played automatically or must be driven with playCheck().
Definition: PololuBuzzer.cpp:719