I was wondering if it was possible to play different tunes on separate speakers/buzzers, so I could play more complex songs using similar code to melody.
using similar code to melody.
Can you post the code or a link to it so I can see?
Basically if the code uses delay() then no as this call is blocking, that is it stops anything else working.
If it uses interrupts then you need an interrupt for each buzzer.
what i mean is, if it is possible to modify the melody example sketch so it could play different sets of notes on different speakers at the same time.
``/* Melody
- (cleft) 2005 D. Cuartielles for K3
- This example uses a piezo speaker to play melodies. It sends
- a square wave of the appropriate frequency to the piezo, generating
- the corresponding tone.
- The calculation of the tones is made following the mathematical
- operation:
- timeHigh = period / 2 = 1 / (2 * toneFrequency)
- where the different tones are described as in the table:
- note frequency period timeHigh
- c 261 Hz 3830 1915
- d 294 Hz 3400 1700
- e 329 Hz 3038 1519
- f 349 Hz 2864 1432
- g 392 Hz 2550 1275
- a 440 Hz 2272 1136
- b 493 Hz 2028 1014
- C 523 Hz 1912 956
-
http://www.arduino.cc/en/Tutorial/Melody
*/
int speakerPin = 9;
int length = 15; // the number of notes
char notes[] = "ccggaagffeeddc "; // a space represents a rest
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 300;
void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
void playNote(char note, int duration) {
char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
// play the tone corresponding to the note name
for (int i = 0; i < 8; i++) {
if (names == note) {
_ playTone(tones*, duration);_
_ }_
_ }_
_}_
void setup() {
_ pinMode(speakerPin, OUTPUT);_
_}_
void loop() {
_ for (int i = 0; i < length; i++) {_
_ if (notes == ' ') {_
delay(beats _ tempo); // rest_
* } else {*
playNote(notes, beats * tempo);
* }*
* // pause between notes*
* delay(tempo / 2);*
* }*
}
[/media]
Yes I know what you mean but I don't know what "the melody" sketch is. So if you point me towards it I can look at the code and see if it is written in such a way that it is extensible in the direction you want to go.
I know what he's talking about. Look in the learning section of the website. There is an example called melody, where it plays a song on a piezo.
IOW, the code is here.
Thanks, I would say no because as I suspected at first this code uses delays to generate the tones. Therefore, as the processor is counting down one delay it can't do anything else especially count down another delay at a different value. So this approach to tone generation is not extendible to a polyphonic output.
The way to get a polyphonic output is shown here:-
http://itp.nyu.edu/~gpv206/2007/10/generating_polyphonic_sound_wi_1.html
Also look here:-
http://www.arduino.cc/playground/Main/InterfacingWithHardware#audio_generation
I'm working on something like this at the moment. It is limited to relatively low frequencies though, and I'm not yet sure if it works as I would like. Those examples are way nicer than my way, which is based on counting the time to the next change. I will post more to this thread when I can get to my code.
My home internet's crapped out so I wasn't able to post code on this one. My solution is massively not as elegant as the one Grumpy_Mike linked to. Cheap though.
What I do is replace the playTone function with one that uses the mod operator (%) on the current time (in micros) and half of each signal periods to work out which one of two tones changes next.
That also tells me at what time it does (measured in micros, added to the time of the last change). Then I calculate the next state (by NOT on whichever is next, or both if they are.
This takes a little while, so instead of using delayMicros I do a really short loop that keeps grabbing micros() until it exceeds the next time. Then change the state (as already calculated) and go back around to the beginning again. This isn't as accurate as delayMicros but it's pretty consistent, and avoids the need to compensate for the time spent messing around with mod arithmetic (except at high frequencies, where the processor just can't keep up; but I don't go that high)
If anyone is interested in this approach, let me know and I shall post more details.
I'm using it because I want to be able to make status beeps more or less harmonious - a nice beep if all's well, a nasty screech if things are going pear shaped - but I only want to use two pins and not much external hardware (two RC bandpass filters and an utterly simple opamp mixer).
(edit: corrected insignificant typo)