Arduino + Piezo Speaker = Super Mario!
by Tiago Gala
Some time ago I decided to put my Arduino into the music business! I had this piezoelectric buzzer lying around and it was time to give it a trial run so I googled around and found this in the Arduino Forum and decided to give it a go, but the code on the website had a kind of “dirty” look so I rewrote it bearing optimization and code-size in mind. Next follows the Fritzing layout, video and code:
//Definição dos periodos para cada nota (*0.0000001) #define C 1911 #define C1 1804 #define D 1703 #define Eb 1607 #define E 1517 #define F 1432 #define F1 1352 #define G 1276 #define Ab 1204 #define A 1136 #define Bb 1073 #define B 1012 #define c 955 #define c1 902 #define d 851 #define eb 803 #define e 758 #define f 716 #define f1 676 #define g 638 #define ab 602 #define a 568 #define bb 536 #define b 506 #define p 0 //pausa int speaker = 6; //porta do arduino long vel = 20000; void setup() { pinMode(speaker, OUTPUT); delay(2000); } int melod[] = {e, e, e, c, e, g, G, c, G, E, A, B, Bb, A, G, e, g, a, f, g, e, c, d, B, c}; int ritmo[] = {6, 12, 12, 6, 12, 24, 24, 18, 18, 18, 12, 12, 6, 12, 8, 8, 8, 12, 6, 12, 12, 6, 6, 6, 12}; void loop() { for (int i=0; i<42; i++) { int tom = melod[i]; int tempo = ritmo[i]; long tvalue = tempo * vel; tocar(tom, tvalue); delayMicroseconds(1000); //pausa entre notas! } delay(1000); } void tocar(int tom, long tempo_value) { long tempo_gasto = 0; while (tempo_gasto < tempo_value) { digitalWrite(speaker, HIGH); delayMicroseconds(tom / 2); digitalWrite(speaker, LOW); delayMicroseconds(tom/2); tempo_gasto += tom; } }
Basically what’s being done is to output a HIGH signal half of the note’s period (the inverse of frequency) and then a LOW for the same amount of time, thus creating a square wave with the note’s corresponding frequency (it’s called PWM – Pulse Width Modulation, if the HIGH and LOW times are the same, it’s said that the duty-cycle is 50%), this HIGH/LOW cycle repeats until the time calculated for that note to be heard is over. At the end of each sound there is a gap of 1000 µseconds (1 milisecond) to make two notes distinguishable if they happen to have the same frequency. Note periods are defined in the anglo-saxonic notation to simplify and standardize note entering. Note duration isn’t related to the relative value of each note (as it would be expected in true musical notation: quarter = 4, a sixteenth = 16) but instead to the duration of the note in µseconds according to the formula: time_µseconds = value * note_span, so if value is 20 000, a note with a note_span = 12 has a duration of 20 000 * 12 = 240 000 µseconds.
In the mean time I already transcribed a few kind of well known songs into this notation, to hear them you just need to swap it’s array name for the equivalent melod[] and ritmo[]:
int peergynt_m[] = {G, E, D, C, D, E, G, E, D, C, D, E, D, E,G, E, G, A, E, A, G, E, D, C}; int peergynt_r[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 16}; int smoke_m[] = {E, G, A, E, G, Bb, A, E, G, A, G, E}; int smoke_r[] = {12, 12, 18, 12, 12, 6, 18, 12, 12, 18, 12, 24}; int natal_m[] = {G, A, G, E, G, A, G, E, c, c, A, B, B, G, A, G, A, c, B, A, G, A, G, E}; int natal_r[] = {12, 4, 8, 16, 12, 4, 8, 16, 12, 4, 16, 12, 4, 16, 12, 4, 8, 8, 8, 8, 12, 4, 8, 16}; int LTS_m[] = {Bb, G, G, Bb, G, G, Bb, ;G, G, Bb, G, G, Bb, G, C, G, Bb, G, G, Bb, G, G, Bb, G, G, Bb, G, G, Bb, G, F, D, F, D, G, F, D, C, Bb, G, Bb, C, C1, C, Bb, F, D, Bb, G, F, D, C, Bb, D, C, Bb, G} ; int LTS_r[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
As a final note, I’m sorry but the name of some variables in the code is in Portuguese, it’s old code and I don’t feel like going through it and risk adding bugs. You might have to tweak vel variable to get the correct speed for your song. As a challenge, try to find what songs I have written in this last part of the code! As a bigger challenge, write your own pieces of awesome PWM music and share them with everyone =)
The piezo speaker is mostly use in Telephone sets now your experiment successfully work that you connect with your arduino device to make it music device.
In file included from D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/Arduino.h:190,
from sketch_aug10a.cpp:29:
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:26: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:27: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:28: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:29: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:30: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:31: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:32: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:33: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:34: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:35: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:36: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:37: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:38: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:39: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:40: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:41: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:46: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:54: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:62: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:69: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:76: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:83: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:90: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:97: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:104: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:112: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:121: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:128: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:136: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:144: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:156: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WCharacter.h:163: error: expected ‘,’ or ‘…’ before numeric constant
In file included from D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/Arduino.h:191,
from sketch_aug10a.cpp:29:
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:65: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:97: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:98: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:108: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:117: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:144: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:195: error: expected ‘,’ or ‘…’ before numeric constant
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/WString.h:196: error: expected ‘,’ or ‘…’ before numeric constant
In file included from D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/Print.h:27,
from D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/Stream.h:26,
from D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/HardwareSerial.h:27,
from D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/Arduino.h:192,
from sketch_aug10a.cpp:29:
D:\Arduino\arduino-1.0\hardware\arduino\cores\arduino/Printable.h:36: error: expected ‘,’ or ‘…’ before numeric constant
It looks like something might be wrong with your software, can you use/compile any of the examples offered by the Arduino IDE?
This code worked for me.
http://pastebin.com/UhsHePFv
The name of the #defines are too short. This can cause strange problems which appear inconsequently.
Rename the defines to something like tone_e, tone_b, tone_ab, etcetera; or work without the defines and replace the characters in the array by the corresponding value.
It works for me! (Well, at least the compiler error disappeared, I couldn’t check it if it worked at all since I killed my piezo speaker)
Thanks, this was useful
I killed my last and only piezo speaker with my soldering iron, so don’t worry about my code modification killing yours.
add all the defines under setup section, then it will work fine
I meant move, not add
[…] Arduino projects to consider where they used a piezo speaker to beep out a tune electronically: https://therandombit.wordpress.com/2011/11/21/arduino-piezo-speaker-super-mario/ and http://www.instructables.com/id/How-to-easily-play-music-with-buzzer-on-arduino-Th/. The […]