Introduction
The following article is about my first Arduino library that I have written. NonBlockingRTTTL is a non-blocking arduino library for playing RTTTL data.
EDIT: The NonBlockingRtttl arduino library is now moved to GitHub. Source code can be downloaded from the project’s GitHub page.
EDIT: NonBlockingRTTTL library is now available on the Arduino Library Manager.
Skip to the download section for quick download.
Purpose
Most code that can be found on the internet that allows you to “play” an RTTTL string is build the same way: sequential calls to the tone() function followed by a delay() function. This type of implementation might be good for robots but not for realtime application or projects that needs to monitor pins while the song is playing.
This library is non-blocking which make it suitable to be used by more advanced algorithm. The non-blocking RTTTL library is a port of the RTTTL example from the Tone library.
Quick recall of the RTTTL format
I recently discovered the Ring Tone Text Transfer Language (RTTTL) audio format which is an audio format for storing single tone (monolithic) melodies. Each melody is composed of successive tone frequencies.
The RTTTL format is human readable and usually more compressed than note & duration arrays which helps reduce its memory footprint.
In the arduino world, melodies are usually written as an array of notes (frequencies) followed by the note’s duration (note1, duration1, note2, duration2, … , noteX, durationX).
The format is really suitable for embedded device that are limited in memory which can’t store PCM (wav) or even MP3 data.
Note that RTTTL can also be spelled RTTL (Ringtone Text Transfer Language). According to my Samsung phone, a ringtone can also be spelled as a single word…
More information on the RTTTL format is available on its Wikipedia acticle.
Library features
Possible use are:
- Really small increase in memory & code footprint compared to the usual blocking algorithm.
- Allows your program to read/write IOs pins while playing. Implementing a “stop” or “next song” push buttons is a breeze!
Usage
Call rtttl::begin() to setup the non-blocking RTTTL library. Then call rtttl::play() to update the library’s state and play notes as required.
Use rtttl::done() or rtttl::isPlaying() to know if the library is done playing the given song. Anytime playing, one can call rtttl::stop() to stop playing the current song.
Define RTTTL_NONBLOCKING_INFO to enable the debugging of the library state on the serial port. Use NONBLOCKINGRTTTL_VERSION to read the current version of the library.
Demo
The following demo show how to use the library:
(download the
NonBlockingRtttl demo sample (995 downloads)
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#include <NonBlockingRtttl.h> //project's contants #define BUZZER_PIN 8 const char * tetris = "tetris:d=4,o=5,b=160:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,2a,8p,d6,8f6,a6,8g6,8f6,e6,8e6,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a"; const char * arkanoid = "Arkanoid:d=4,o=5,b=140:8g6,16p,16g.6,2a#6,32p,8a6,8g6,8f6,8a6,2g6"; const char * mario = "mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6"; byte songIndex = 0; //which song to play when the previous one finishes void setup() { pinMode(BUZZER_PIN, OUTPUT); Serial.begin(115200); Serial.println(); } void loop() { if ( !rtttl::isPlaying() ) { if (songIndex == 0) { rtttl::begin(BUZZER_PIN, mario); songIndex++; //ready for next song //play for 5 sec then stop. //note: this is a blocking code section //use to demonstrate the use of stop unsigned long start = millis(); while( millis() - start < 5000 ) { rtttl::play(); } rtttl::stop(); } else if (songIndex == 1) { rtttl::begin(BUZZER_PIN, arkanoid); songIndex++; //ready for next song } else if (songIndex == 2) { rtttl::begin(BUZZER_PIN, tetris); songIndex++; //ready for next song } } else { rtttl::play(); } } |
License
The following code was written by Antoine Beauchamp. The non-blocking RTTTL library is a port of the RTTTL example from the Tone library which is licensed with the MIT License.
The code & updates for the library can be found at http://end2endzone.com.
For the original source code for the RTTTL player see: http://code.google.com/archive/p/rogue-code/wikis/ToneLibraryDocumentation.wiki.
Download
Please note that download links are now deprecated. Binary version of NonBlockingRtttl library can be downloaded from the project’s Release page.
EDIT: NonBlockingRTTTL library can now be installed from the Arduino Library Manager.