|
1 |
| -/* |
2 |
| - * MML Music Tone example |
3 |
| - * MmlMusic library example for Arduino IDE |
4 |
| - * |
5 |
| - * This example demonstrates playing MML music on a piezo speaker |
6 |
| - * using the Arduino tone() function. |
7 |
| - * A callback function is defined to call the tone()/noTone() functions. |
8 |
| - * |
9 |
| - * For more information see: |
10 |
| - * https://github.com/maxint-rd/MmlMusic |
11 |
| - * https://github.com/maxint-rd/MmlMusicPWM |
12 |
| - * |
13 |
| - * Made by MMOLE (@maxint-rd) 2017 |
14 |
| - * |
15 |
| - * For more MML music go to http://www.archeagemmllibrary.com/ |
16 |
| - */ |
| 1 | +/* |
| 2 | + * MML Music Tone example |
| 3 | + * MmlMusic library example for Arduino IDE |
| 4 | + * |
| 5 | + * Tbis example demonstrates playing MML music on a piezo speaker |
| 6 | + * using the Arduino tone() function. |
| 7 | + * A callback function is defined to call the tone()/noTone() functions. |
| 8 | + * |
| 9 | + * For more information see: |
| 10 | + * https://github.com/maxint-rd/MmlMusic |
| 11 | + * https://github.com/maxint-rd/MmlMusicPWM |
| 12 | + * |
| 13 | + * Made by MMOLE (@maxint-rd) 2017 |
| 14 | + * |
| 15 | + * For more MML music go to http://www.archeagemmllibrary.com/ |
| 16 | + */ |
| 17 | + |
| 18 | +// Include header files for the used libraries |
| 19 | +#include <MmlMusic.h> |
| 20 | + |
| 21 | +#if defined(__AVR_ATtiny85__) |
| 22 | + // ATtiny85 has no regular hardware serial. You can use TinyDebugSerial (TX=3) or software serial |
| 23 | + // For more info see http://www.ernstc.dk/arduino/tinycom.html |
| 24 | + //#include <SoftwareSerial.h> |
| 25 | + //SoftwareSerial mySerial(4, 3); // RX, TX |
| 26 | + |
| 27 | + #include <TinyDebugSerial.h> |
| 28 | + TinyDebugSerial mySerial = TinyDebugSerial(); // Debug TX on PB3, no RX, only 9600, 38400 or 115200 |
| 29 | + #define Serial mySerial |
| 30 | + // To use the Arduino tone() function on ATtiny85 the board core needs to support it. |
| 31 | + // Note that the Arduino tone() function is not supported in the standard Arduino "core" for ATtiny85 by D.A. Mellis. |
| 32 | + // Alternative cores: http://www.leonardomiliani.com/en/ , https://github.com/SpenceKonde/ATTinyCore |
| 33 | + #define BUZ_PIN 1 |
| 34 | +#elif defined(ARDUINO_ARCH_ESP8266) |
| 35 | + #define BUZ_PIN 14 |
| 36 | +#else |
| 37 | + #define BUZ_PIN 4 // pin 4 recommended on Pro Mini since it has perfect distance from GND |
| 38 | +#endif |
| 39 | + |
| 40 | +// define the MML Music object |
| 41 | +MmlMusic music; // Note: don't use empty parenthesis () to use the (void) constructor; this will confuse the compiler. |
| 42 | + |
| 43 | +// To play the tones using tone() a callback functions are used. |
| 44 | +// These are also used to display debug information on the serial console |
| 45 | +// Resources are limited on the ATtiny85, so you may need to comment things out to preserve memory. |
| 46 | +bool MyToneCallback(unsigned int frequency, unsigned long length, uint8_t nTrack, uint8_t nVolume) |
| 47 | +{ // the tone callback is called on three occasions |
| 48 | + // 1. play a tone of certain frequency for specified length or indefinitely (len=0) |
| 49 | + // 2. wait for a certain period while tone or silence is played (freq=0, len=msec) |
| 50 | + // 3. stop playing (freq=0; len=0) |
| 51 | + |
| 52 | + if(frequency==0 && length==0) |
| 53 | + { |
| 54 | + //Serial.println(F("shhht")); |
| 55 | + } |
| 56 | + else |
| 57 | + { |
| 58 | + if(frequency>0) |
| 59 | + { |
| 60 | + Serial.print(nTrack); |
| 61 | + Serial.print(F("t:")); |
| 62 | + Serial.print(frequency); |
| 63 | + Serial.print(F(" ")); |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + if(frequency==0 && length==0) |
| 68 | + { // stop specific track |
| 69 | + noTone(BUZ_PIN); |
| 70 | + } |
| 71 | + else if(frequency>0) |
| 72 | + { // tone |
| 73 | + tone(BUZ_PIN, frequency); |
| 74 | + } |
| 75 | + return(true); // return true to indicate callback made the tone and wants original playTone NOT to continue |
| 76 | +} |
| 77 | + |
| 78 | +// Arduino core has no definition for FPSTR |
| 79 | +// on ESP in wstring.h: #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) |
| 80 | +#if !defined(FPSTR) |
| 81 | +#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) |
| 82 | +#endif |
| 83 | +// Unfortunately the definition above won't compile on Arduino IDE 1.6.7. It will compile in IDE 1.8.2 |
| 84 | +// You can upgrade or remove this code and the use of MyPlayCallback below. |
| 85 | + |
| 86 | +// Callback functions can also be set to indicate start or end of playing the music sequence |
| 87 | +void MyPlayCallback(const char* mml, bool fUseFlash) |
| 88 | +{ // Called prior to start of plsy. Note mml may point to PROGMEM string, depending on call to play or play_P |
| 89 | + Serial.print(F("Play ")); |
| 90 | + //Serial.println(fUseFlash ? FPSTR(mml) : mml); // can't use conditional expression with distinct pointer types |
| 91 | + if(fUseFlash) |
| 92 | + Serial.println(FPSTR(mml)); |
| 93 | + else |
| 94 | + Serial.println(mml); |
| 95 | +} |
| 96 | + |
| 97 | +void MyCompletionCallback(void) |
| 98 | +{ // Called prior when done playing |
| 99 | + Serial.println(" Done!"); |
| 100 | +} |
| 101 | + |
| 102 | +void delayR(uint16_t ms) |
| 103 | +{ // Without interrupts, normal delay will not continue playing. |
| 104 | + // Therefor we regularly need to call continuePlaying(). |
| 105 | + unsigned long ulEnd=millis()+ms; |
| 106 | + while(millis()<ulEnd) |
| 107 | + { |
| 108 | + if(music.isPlaying()) |
| 109 | + music.continuePlaying(); |
| 110 | + delay(1); // on ESP we need to yield to feed the watchdog |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +/* |
| 115 | +// Star Wars – The Force theme (originally two tracks, only one played) |
| 116 | +const char szPlay[] PROGMEM="v127t100l4o4 r g>c2d.d16+f16d+2<g.l8g>c4.dd+<d+>l12d+cgf2.<g4>c4.l8dd+.<g16>g.d+16>c2<c4l12d+dcg4&gd+c<g4g8.g16>c2"; |
| 117 | +/**/ |
| 118 | + |
| 119 | +/**/ |
| 120 | +// Star Wars Theme (originally three tracks, only one played. Short version is for ATtiny85. |
| 121 | +//const char szPlay[] PROGMEM="T107o6c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>f16e16d16c16<g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16.>c2<g4f16.e16f16.d4<g4g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16."; |
| 122 | +const char szPlay[] PROGMEM="T107o5c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>f16e16d16c16<g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16.>c2<g4f16.e16f16.d4<g4g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16.>c2<g4>d16.c16<b16.>c4<c16.c16c16.c4"; |
| 123 | +/**/ |
| 124 | + |
| 125 | +void setup() |
| 126 | +{ |
| 127 | + Serial.begin(115200); |
| 128 | + Serial.println(F("\n -- mxUnifiedSN76489 MML Music Tone example --")); |
| 129 | + |
| 130 | + // set callback functions |
| 131 | + music.setPlayCallback(MyPlayCallback); |
| 132 | + music.setToneCallback(MyToneCallback); |
| 133 | + music.setCompletionCallback(MyCompletionCallback); |
| 134 | + |
| 135 | + // Start playing some music (if impatient use the short tune of the lower line). |
| 136 | + //music.play_P(szPlay); |
| 137 | + music.play_P(PSTR("T180 L8 CDEC. r CDEC. r EFG. r EFG. r GAGFEC. r GAGFEC. r L4 C<A>C. r C<A>C.")); |
| 138 | + //music.play("T180 L8 CDEC. r CDEC. r EFG. r EFG. r GAGFEC. r GAGFEC. r L4 C<A>C. r C<A>C."); |
| 139 | +} |
| 140 | + |
| 141 | +// the loop function runs over and over again forever |
| 142 | +void loop() |
| 143 | +{ |
| 144 | + if(music.isPlaying()) |
| 145 | + music.continuePlaying(); // Without timer interupts we regularly need to call continuePlaying() |
| 146 | + // To simplify this use the MmlMusicPWM child library |
| 147 | + else |
| 148 | + { |
| 149 | + music.play_P(PSTR("T240 O4 L64 AB>C")); // give a short blurp |
| 150 | + delayR(1000); // use alternative delay to continue playing as needed |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | + |
17 | 155 |
|
18 |
| -// Include header files for the used libraries |
19 |
| -#include <MmlMusic.h> |
20 |
| - |
21 |
| -#if defined(__AVR_ATtiny85__) |
22 |
| - // ATtiny85 has no regular hardware serial. You can use TinyDebugSerial (TX=3) or software serial |
23 |
| - // For more info see http://www.ernstc.dk/arduino/tinycom.html |
24 |
| - //#include <SoftwareSerial.h> |
25 |
| - //SoftwareSerial mySerial(4, 3); // RX, TX |
26 |
| - |
27 |
| - #include <TinyDebugSerial.h> |
28 |
| - TinyDebugSerial mySerial = TinyDebugSerial(); // Debug TX on PB3, no RX, only 9600, 38400 or 115200 |
29 |
| - #define Serial mySerial |
30 |
| - // To use the Arduino tone() function on ATtiny85 the board core needs to support it. |
31 |
| - // Note that the Arduino tone() function is not supported in the standard Arduino "core" for ATtiny85 by D.A. Mellis. |
32 |
| - // Alternative cores: http://www.leonardomiliani.com/en/ , https://github.com/SpenceKonde/ATTinyCore |
33 |
| - #define BUZ_PIN 1 |
34 |
| -#elif defined(ARDUINO_ARCH_ESP8266) |
35 |
| - #define BUZ_PIN 14 |
36 |
| -#else |
37 |
| - #define BUZ_PIN 4 // pin 4 recommended on Pro Mini since it has perfect distance from GND |
38 |
| -#endif |
39 |
| - |
40 |
| -// define the MML Music object |
41 |
| -MmlMusic music; // Note: don't use empty parenthesis () to use the (void) constructor; this will confuse the compiler. |
42 |
| - |
43 |
| -// To play the tones using tone() a callback functions are used. |
44 |
| -// These are also used to display debug information on the serial console |
45 |
| -// Resources are limited on the ATtiny85, so you may need to comment things out to preserve memory. |
46 |
| -bool MyToneCallback(unsigned int frequency, unsigned long length, uint8_t nTrack, uint8_t nVolume) |
47 |
| -{ // the tone callback is called on three occasions |
48 |
| - // 1. play a tone of certain frequency for specified length or indefinitely (len=0) |
49 |
| - // 2. wait for a certain period while tone or silence is played (freq=0, len=msec) |
50 |
| - // 3. stop playing (freq=0; len=0) |
51 |
| - |
52 |
| - if(frequency==0 && length==0) |
53 |
| - { |
54 |
| - //Serial.println(F("shhht")); |
55 |
| - } |
56 |
| - else |
57 |
| - { |
58 |
| - if(frequency>0) |
59 |
| - { |
60 |
| - Serial.print(nTrack); |
61 |
| - Serial.print(F("t:")); |
62 |
| - Serial.print(frequency); |
63 |
| - Serial.print(F(" ")); |
64 |
| - } |
65 |
| - } |
66 |
| - |
67 |
| - if(frequency==0 && length==0) |
68 |
| - { // stop specific track |
69 |
| - noTone(BUZ_PIN); |
70 |
| - } |
71 |
| - else if(frequency>0) |
72 |
| - { // tone |
73 |
| - tone(BUZ_PIN, frequency); |
74 |
| - } |
75 |
| - return(true); // return true to indicate callback made the tone and wants original playTone NOT to continue |
76 |
| -} |
77 |
| - |
78 |
| -// Arduino core has no definition for FPSTR |
79 |
| -// on ESP in wstring.h: #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) |
80 |
| -#if !defined(FPSTR) |
81 |
| -#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) |
82 |
| -#endif |
83 |
| -// Unfortunately the definition above won't compile on Arduino IDE 1.6.7. It will compile in IDE 1.8.2 |
84 |
| -// You can upgrade or remove this code and the use of MyPlayCallback below. |
85 |
| - |
86 |
| -// Callback functions can also be set to indicate start or end of playing the music sequence |
87 |
| -void MyPlayCallback(const char* mml, bool fUseFlash) |
88 |
| -{ // Called prior to start of plsy. Note mml may point to PROGMEM string, depending on call to play or play_P |
89 |
| - Serial.print(F("Play ")); |
90 |
| - //Serial.println(fUseFlash ? FPSTR(mml) : mml); // can't use conditional expression with distinct pointer types |
91 |
| - if(fUseFlash) |
92 |
| - Serial.println(FPSTR(mml)); |
93 |
| - else |
94 |
| - Serial.println(mml); |
95 |
| -} |
96 |
| - |
97 |
| -void MyCompletionCallback(void) |
98 |
| -{ // Called prior when done playing |
99 |
| - Serial.println(" Done!"); |
100 |
| -} |
101 |
| - |
102 |
| -void delayR(uint16_t ms) |
103 |
| -{ // Without interrupts, normal delay will not continue playing. |
104 |
| - // Therefor we regularly need to call continuePlaying(). |
105 |
| - unsigned long ulEnd=millis()+ms; |
106 |
| - while(millis()<ulEnd) |
107 |
| - { |
108 |
| - if(music.isPlaying()) |
109 |
| - music.continuePlaying(); |
110 |
| - delay(1); // on ESP we need to yield to feed the watchdog |
111 |
| - } |
112 |
| -} |
113 |
| - |
114 |
| -/* |
115 |
| -// Star Wars – The Force theme (originally two tracks, only one played) |
116 |
| -const char szPlay[] PROGMEM="v127t100l4o4 r g>c2d.d16+f16d+2<g.l8g>c4.dd+<d+>l12d+cgf2.<g4>c4.l8dd+.<g16>g.d+16>c2<c4l12d+dcg4&gd+c<g4g8.g16>c2"; |
117 |
| -/**/ |
118 |
| - |
119 |
| -/**/ |
120 |
| -// Star Wars Theme (originally three tracks, only one played. Short version is for ATtiny85. |
121 |
| -//const char szPlay[] PROGMEM="T107o6c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>f16e16d16c16<g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16.>c2<g4f16.e16f16.d4<g4g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16."; |
122 |
| -const char szPlay[] PROGMEM="T107o5c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>c16<b16a16g16>f16e16d16c16c16<b16a16g16>c16<b16a16g16>f16e16d16c16<g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16.>c2<g4f16.e16f16.d4<g4g16.g16g16.>c2g2f16.e16d16.>c2<g4f16.e16d16.>c2<g4>d16.c16<b16.>c4<c16.c16c16.c4"; |
123 |
| -/**/ |
124 |
| - |
125 |
| -void setup() |
126 |
| -{ |
127 |
| - Serial.begin(115200); |
128 |
| - Serial.println(F("\n -- mxUnifiedSN76489 MML Music Tone example --")); |
129 |
| - |
130 |
| - // set callback functions |
131 |
| - music.setPlayCallback(MyPlayCallback); |
132 |
| - music.setToneCallback(MyToneCallback); |
133 |
| - music.setCompletionCallback(MyCompletionCallback); |
134 |
| - |
135 |
| - // Start playing some music (if impatient use the short tune of the lower line). |
136 |
| - music.play_P(szPlay); |
137 |
| - //music.play_P(PSTR("T180 L8 CDEC. r CDEC. r EFG. r EFG. r GAGFEC. r GAGFEC. r L4 C<A>C. r C<A>C.")); |
138 |
| - //music.play("T180 L8 CDEC. r CDEC. r EFG. r EFG. r GAGFEC. r GAGFEC. r L4 C<A>C. r C<A>C."); |
139 |
| -} |
140 |
| - |
141 |
| -// the loop function runs over and over again forever |
142 |
| -void loop() |
143 |
| -{ |
144 |
| - if(music.isPlaying()) |
145 |
| - music.continuePlaying(); // Without timer interupts we regularly need to call continuePlaying() |
146 |
| - // To simplify this use the MmlMusicPWM child library |
147 |
| - else |
148 |
| - { |
149 |
| - music.play_P(PSTR("T240 O4 L64 AB>C")); // give a short blurp |
150 |
| - delayR(1000); // use alternative delay to continue playing as needed |
151 |
| - } |
152 |
| -} |
|
0 commit comments