|
| 1 | +// The speaker will play the tune to Happy Birthday continuously |
| 2 | +// Author: Tony DiCola |
| 3 | +// License: MIT (https://opensource.org/licenses/MIT) |
| 4 | + |
| 5 | +#include <Arduino.h> |
| 6 | + |
| 7 | +#ifdef USE_TINYUSB |
| 8 | +// For Serial when selecting TinyUSB. Can't include in the core because Arduino IDE |
| 9 | +// will not link in libraries called from the core. Instead, add the header to all |
| 10 | +// the standard libraries in the hope it will still catch some user cases where they |
| 11 | +// use these libraries. |
| 12 | +// See https://github.com/earlephilhower/arduino-pico/issues/167#issuecomment-848622174 |
| 13 | +#include <Adafruit_TinyUSB.h> |
| 14 | +#endif |
| 15 | + |
| 16 | +// pin_buzzer should be defined by the supported variant e.g CPlay Bluefruit or CLUE. |
| 17 | +// Otherwise please define the pin you would like to use for tone output |
| 18 | +#ifndef PIN_BUZZER |
| 19 | +#define PIN_BUZZER A0 |
| 20 | +#endif |
| 21 | + |
| 22 | +uint8_t const pin_buzzer = PIN_BUZZER; |
| 23 | + |
| 24 | +// A few music note frequencies as defined in this tone example: |
| 25 | +// https://www.arduino.cc/en/Tutorial/toneMelody |
| 26 | +#define NOTE_C4 262 |
| 27 | +#define NOTE_CS4 277 |
| 28 | +#define NOTE_D4 294 |
| 29 | +#define NOTE_DS4 311 |
| 30 | +#define NOTE_E4 330 |
| 31 | +#define NOTE_F4 349 |
| 32 | +#define NOTE_FS4 370 |
| 33 | +#define NOTE_G4 392 |
| 34 | +#define NOTE_GS4 415 |
| 35 | +#define NOTE_A4 440 |
| 36 | +#define NOTE_AS4 466 |
| 37 | +#define NOTE_B4 494 |
| 38 | +#define NOTE_C5 523 |
| 39 | +#define NOTE_CS5 554 |
| 40 | +#define NOTE_D5 587 |
| 41 | +#define NOTE_DS5 622 |
| 42 | +#define NOTE_E5 659 |
| 43 | +#define NOTE_F5 698 |
| 44 | +#define NOTE_FS5 740 |
| 45 | +#define NOTE_G5 784 |
| 46 | +#define NOTE_GS5 831 |
| 47 | +#define NOTE_A5 880 |
| 48 | +#define NOTE_AS5 932 |
| 49 | +#define NOTE_B5 988 |
| 50 | + |
| 51 | +// Define note durations. You only need to adjust the whole note |
| 52 | +// time and other notes will be subdivided from it directly. |
| 53 | +#define WHOLE 2200 // Length of time in milliseconds of a whole note (i.e. a full bar). |
| 54 | +#define HALF WHOLE/2 |
| 55 | +#define QUARTER HALF/2 |
| 56 | +#define EIGHTH QUARTER/2 |
| 57 | +#define EIGHTH_TRIPLE QUARTER/3 |
| 58 | +#define SIXTEENTH EIGHTH/2 |
| 59 | + |
| 60 | +// Play a note of the specified frequency and for the specified duration. |
| 61 | +// Hold is an optional bool that specifies if this note should be held a |
| 62 | +// little longer, i.e. for eighth notes that are tied together. |
| 63 | +// While waiting for a note to play the waitBreath delay function is used |
| 64 | +// so breath detection and pixel animation continues to run. No tones |
| 65 | +// will play if the slide switch is in the -/off position or all the |
| 66 | +// candles have been blown out. |
| 67 | +void playNote(int frequency, int duration, bool hold = false, bool measure = true) { |
| 68 | + (void) measure; |
| 69 | + |
| 70 | + if (hold) { |
| 71 | + // For a note that's held play it a little longer than the specified duration |
| 72 | + // so it blends into the next tone (but there's still a small delay to |
| 73 | + // hear the next note). |
| 74 | + tone(pin_buzzer, frequency, duration + duration / 32); |
| 75 | + } else { |
| 76 | + // For a note that isn't held just play it for the specified duration. |
| 77 | + tone(pin_buzzer, frequency, duration); |
| 78 | + } |
| 79 | + |
| 80 | + delay(duration + duration / 16); |
| 81 | +} |
| 82 | + |
| 83 | +// Song to play when the candles are blown out. |
| 84 | +void celebrateSong() { |
| 85 | + // Play a little charge melody, from: |
| 86 | + // https://en.wikipedia.org/wiki/Charge_(fanfare) |
| 87 | + // Note the explicit boolean parameters in particular the measure=false |
| 88 | + // at the end. This means the notes will play without any breath measurement |
| 89 | + // logic. Without this false value playNote will try to keep waiting for candles |
| 90 | + // to blow out during the celebration song! |
| 91 | + playNote(NOTE_G4, EIGHTH_TRIPLE, true, false); |
| 92 | + playNote(NOTE_C5, EIGHTH_TRIPLE, true, false); |
| 93 | + playNote(NOTE_E5, EIGHTH_TRIPLE, false, false); |
| 94 | + playNote(NOTE_G5, EIGHTH, true, false); |
| 95 | + playNote(NOTE_E5, SIXTEENTH, false); |
| 96 | + playNote(NOTE_G5, HALF, false); |
| 97 | +} |
| 98 | + |
| 99 | +void setup() { |
| 100 | + // Initialize serial output and Circuit Playground library. |
| 101 | + Serial.begin(115200); |
| 102 | + |
| 103 | + pinMode(pin_buzzer, OUTPUT); |
| 104 | + digitalWrite(pin_buzzer, LOW); |
| 105 | +} |
| 106 | + |
| 107 | +void loop() { |
| 108 | + // Play happy birthday tune, from: |
| 109 | + // http://www.irish-folk-songs.com/happy-birthday-tin-whistle-sheet-music.html#.WXFJMtPytBw |
| 110 | + // Inside each playNote call it will play a note and drive the NeoPixel animation |
| 111 | + // and check for a breath against the sound sensor. Once all the candles are blown out |
| 112 | + // the playNote calls will stop playing music. |
| 113 | + playNote(NOTE_D4, EIGHTH, true); |
| 114 | + playNote(NOTE_D4, EIGHTH); |
| 115 | + playNote(NOTE_E4, QUARTER); // Bar 1 |
| 116 | + playNote(NOTE_D4, QUARTER); |
| 117 | + playNote(NOTE_G4, QUARTER); |
| 118 | + playNote(NOTE_FS4, HALF); // Bar 2 |
| 119 | + playNote(NOTE_D4, EIGHTH, true); |
| 120 | + playNote(NOTE_D4, EIGHTH); |
| 121 | + playNote(NOTE_E4, QUARTER); // Bar 3 |
| 122 | + playNote(NOTE_D4, QUARTER); |
| 123 | + playNote(NOTE_A4, QUARTER); |
| 124 | + playNote(NOTE_G4, HALF); // Bar 4 |
| 125 | + playNote(NOTE_D4, EIGHTH, true); |
| 126 | + playNote(NOTE_D4, EIGHTH); |
| 127 | + playNote(NOTE_D5, QUARTER); // Bar 5 |
| 128 | + playNote(NOTE_B4, QUARTER); |
| 129 | + playNote(NOTE_G4, QUARTER); |
| 130 | + playNote(NOTE_FS4, QUARTER); // Bar 6 |
| 131 | + playNote(NOTE_E4, QUARTER); |
| 132 | + playNote(NOTE_C5, EIGHTH, true); |
| 133 | + playNote(NOTE_C5, EIGHTH); |
| 134 | + playNote(NOTE_B4, QUARTER); // Bar 7 |
| 135 | + playNote(NOTE_G4, QUARTER); |
| 136 | + playNote(NOTE_A4, QUARTER); |
| 137 | + playNote(NOTE_G4, HALF); // Bar 8 |
| 138 | + |
| 139 | + celebrateSong(); |
| 140 | + |
| 141 | + // One second pause before repeating the loop and playing |
| 142 | + delay(1000); |
| 143 | +} |
0 commit comments