Two Speakers at the same time

Hi all, first time here =)

I’m EXTREMELLY noob with Arduino, just learning the basics by now so, please, sorry for stupid questions… but anyway, here is my problem:

I’m trying to make a simple thing here: With 2 speakers, I want to make one of them play a note… With a potenciometer, I’ll control the 2nd speaker and, when you get the same note of the 1st speaker, a LED lights.
The problem I’m having is that it seems that I can’t make both speakers play at the same time :~ … Using the same code, if I make one of them play, it works… changing the code to make just the other one plays, works fine as well… If I put both, just one of them is played.

I’m using Notes library
Here’s the code (sorry, it’s a shitty code, I’m still learning hehe :P):

#include <notes.h>

#define WLED 53 //a LED to light when you "tune"
#define BUZZ_1 8 //speaker where you try to "tune"
#define BUZZ_2 2 //speaker that plays the note you want to "tune"
#define KNOB 15 //the potenciometer

int nota;
  
void setup()
{

  pinMode(KNOB, INPUT);
  pinMode(WLED, OUTPUT);
  pinMode(BTN, INPUT);
  pinMode(BUZZ_1, OUTPUT);
  pinMode(BUZZ_2, OUTPUT); 

//to generate a random note 
  randomSeed(analogRead(0));
  nota = random(1023);
  //speaker 2 - I know it's probably in the wrong place, I'll comment later
  tone(BUZZ_2, nota);
}

void loop()
{
 int pot = analogRead(KNOB);
 int mapPot = map(pot, 0,1023,0,1023); //this map is useless here, I'm just leaving it in case I want to make it easier or harder to find the right note)

 
 //LED
 if (mapPot >= nota-5 && mapPot <= nota+5) {
   digitalWrite(WLED, HIGH);
 }
 else {
   digitalWrite(WLED, LOW);
 }
 
// speaker_1 
  tone(BUZZ_1, pot);
 
}

So, first both speakers lines [ tone(BUZZ_1, pot); and tone(BUZZ_2, nota); ] where in the loop, which I thought that might be the problem. I tried to put it out of the loop, but it didn’t work.

I’m supposing there is something wrong with my code… The connections are ok, since separately, the speakers work.
I’m using an Arduino Mega (ATmega 1280) and connecting one speaker in pwn 2 and the other in pwn 8…

Sorry again for stupid “grammar” on my code… Any help is OVERLY appreciated :D!

oh.......... thanks =)!

It could be done with bit-banging (and probably also using two PWM pins but I’m not quite as familiar with that).

For example, this generates a tone without using the Tone library:

// alarm frequency
#define FREQUENCY 600  // Hz
#define PERIOD 500000L / FREQUENCY  // (1 / frequency) * 1e6 / 2

#define BUZZER1 5   // D5
#define BUZZER2 6   // D6

void setup ()
{
  pinMode (BUZZER1, OUTPUT);
  pinMode (BUZZER2, OUTPUT);
}

void beep (const byte pin, const long period, const int duration)
{

  for(int i = 0 ; i < duration ; i++)
  {
    // on
    digitalWrite (pin, HIGH);
    delayMicroseconds(period);
    // off
    digitalWrite (pin, LOW);
    delayMicroseconds(period);
  }

  digitalWrite (pin, LOW);

}  // end of beep

void loop ()
{
beep (BUZZER1, PERIOD, 200);
delay (200);

beep (BUZZER2, PERIOD / 2, 200);  // octave higher
delay (200);
}

Now, combine that with the techniques in “blink without delay” (example supplied with the IDE) and you could have two speakers playing different tones simultaneously!

Thanks Nick =)! It's 2:50 now here and I'll go to sleep but I'm eager to try it tomorrow =))! Thx a lot ^^!

Here is an example, using the Timer class I wrote a while back:

#include <Elapsed.h>  // see: http://www.gammon.com.au/Arduino/Elapsed.zip

// alarm frequency
#define FREQUENCY 600  // Hz
#define PERIOD 500000L / FREQUENCY  // (1 / frequency) * 1e6 / 2

#define BUZZER1 5   // D5
#define BUZZER2 6   // D6

void setup ()
{
  pinMode (BUZZER1, OUTPUT);
  pinMode (BUZZER2, OUTPUT);
}

static Elapsed t1, t2;

void loop ()
{

  if (t1.intervalUs () > PERIOD)
    {
    digitalWrite(BUZZER1, !digitalRead (BUZZER1)); 
    t1.reset ();
    }

 if (t2.intervalUs () > PERIOD / 2)
    {
    digitalWrite(BUZZER2, !digitalRead (BUZZER2)); 
    t2.reset ();
    }
    
}  // end of loop

It works (both speakers play at once at different frequencies) but sounds a bit rough. That may be acceptable. If not, better work out how to get two PWM outputs along the lines of how the Tone library does one of them.

Also, sampling the pot (which itself takes time) will make my version sound worse.

Multiple outputs... http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation

Much better solution!

#include <Tone.h>

Tone tone1;
Tone tone2;

void setup()
{
  tone1.begin(5);
  tone1.play(NOTE_A4);
  tone1.begin(6);
  tone1.play(NOTE_A5);
}

void loop()
{
}

That sounds great, and would let you test the pot in loop without affecting the sound quality.

Thanks Nick =)!

With this last code, the two speakers play the given notes but now I’m having a problem setting the pot to control the notes of the speaker. It seems to play a random tone and I can’t control it with the pot.

Here’s the code:

#include <Tone.h>

#define WLED 10
#define BUZZ_1 8
#define BUZZ_2 2
#define BTN 22
#define KNOB 15

Tone tone1;
Tone tone2;

int note;

void setup()
{
  pinMode(BUZZ_1, OUTPUT);
  pinMode(BTN, INPUT);
  pinMode(KNOB, INPUT);
  Serial.begin(9600);
  
  randomSeed(analogRead(0));
  int note = random(1023);
  
  tone1.begin(BUZZ_2);
  tone1.play(note);   //Here it's working
}

void loop()
{
  int botao = digitalRead(BTN);
  int pot = analogRead(KNOB);
  int mapPot = map(pot, 0,1023,0,1023);

//DEBUG
  if (botao == 1) {
    Serial.println(note);
  }
  else {
    Serial.println(mapPot);
  }

//SPEAKER_1  
  tone1.begin(BUZZ_1);
  tone1.play(pot); 
  
}

I tried moving up to the void setup() but it didn’t work as well =(!

I'm trying another code just trying to make the pot controls the speaker, but I can't do it also :(!

If I put the tone1.play() in the loop, it doesn't seem to work as it should... In the setup it works fine. But how do I control it with the pot?

  int mapPot = map(pot, 0,1023,0,1023);

I don't think I've ever seen map misused like this before...

I don’t think I’ve ever seen map misused like this before…

As KE7GKP said, I’m just putting this to tweak the numbers in case I need to change the map… Just to make it easier… It is, indeed, being wasted as it is now, but makes it easier to adjust things if needed :slight_smile:

Sorry, forgot the code:

#include <Tone.h>

#define BUZZ_1 8
#define KNOB 15

Tone tone1;
Tone tone2;

int note;

void setup()
{
  pinMode(BUZZ_1, OUTPUT);
  pinMode(KNOB, INPUT);
  Serial.begin(9600);
  
  randomSeed(analogRead(0));
  int note = random(1023);

  tone1.begin(BUZZ_1);
  tone1.play(pot); 
}

void loop()
{
  int pot = analogRead(KNOB);
  int mapPot = map(pot, 0,1023,0,1023);
  
}

Now here is the part I’m stucked. I don’t know how to make the pot control the note. The way I was doing it (with the tone()) worked, but I couldn’t use 2 speakers… through this tone1.play() I’m able to play to tones, one in each speaker, but I don’t know how to make the pot control the note of the speaker…

[I know this code is not working, since the int “pot” is not defined yet when used in the setup, but putting the tone1.play(pot) in the loop doesn’t work very nicely as well]

#define KNOB 15

  int pot = analogRead(KNOB);

So, do you know what pins the analogRead function works on? Hint, pin 15 isn't one of them.

So, do you know what pins the analogRead function works on? Hint, pin 15 isn't one of them.

Yes I do, but I'm using Arduino Mega 1280, so there is the analog pin 15, it's not the digital pin 15... As I said, I made the pot work using the notes.h library (which I can't make 2 speakers work simultaneously). Do I have to say to the program that it's the analog pin 15, not the digital pin?

but I'm using Arduino Mega 1280

I guess I missed that.

Do I have to say to the program that it's the analog pin 15, not the digital pin?

No. The analogRead function only works on analog pins. So, if you have the pot connected to analog pin 15, the value should be being read.

How DO you have the pot wired? If you print the value read from the pot, does it match your expectations/pot position?

Yes, it matches... The pot is supposedly working correctly. But using it in this environment of the Tone library makes it not to work. I'm wondering if there's any sort of conflict within the Arduino sending signals to the devices....

This works fine for me:

#include <Tone.h>

#define BUZZ_1 6
#define KNOB A0

Tone tone1;
Tone tone2;

void setup()
{
  pinMode(BUZZ_1, OUTPUT);
  pinMode(KNOB, INPUT);

  tone1.begin(BUZZ_1);
  tone1.play (440);
}

void loop()
{
  int pot = analogRead(KNOB);
  tone1.play (440 + pot);
}

As I turn the knob, the output tone varies smoothly.

Yeeey!! Thanks, using this code you posted it worked fine =)))!!

But now I’m with another problems :(!!!

The random number that will set the note of one of the speakers… Let me put the code and explain the problem:

#include <Tone.h>

#define BTN 22
#define WLED 10

#define BUZZ_1 8
#define BUZZ_2 2
#define KNOB 15


Tone tone1;
Tone tone2;


void setup()
{
  Serial.begin(9600);
  
  randomSeed(analogRead(0));
  int randNote = random(1023);  
  
  pinMode(WLED, OUTPUT);
  pinMode(BUZZ_1, OUTPUT);
  pinMode(BUZZ_2, OUTPUT);
  pinMode(KNOB, INPUT);


  tone1.begin(BUZZ_1);
  tone1.play (randNote);
  
  Serial.println(randNote);
  
  tone2.begin(BUZZ_2);
  tone2.play(440);
}

void loop()
{
  int pot = analogRead(KNOB);
  tone2.play (pot);
 

//this is  the part where, if you adjust the pot to the right frequency, it'll light a White LED to show you that you actually got it right. 
  if (pot >= randNote-5 && pot <= randNote+5) {
    digitalWrite(WLED, HIGH);
  }
  else {
    digitalWrite(WLED, LOW);
  }
  
  
//DEBUG
  int botao = digitalRead(BTN);
  if (botao == 1) {
    Serial.println(randNote);
  }
  else {
    Serial.println(pot);
  }
  
}

Now, the problem is that, if I try to compile this code, it says that “randNote” was not declared in this scope (in this case, in the first randNote in void loop()). If I declare int randNote; in the loop, the random number given to me is aways 0. If I use int randNote = random(1023); it’'ll, obviously, give me a random number every loop and different from the one given in the void setup() …

So now, how do I make the random note given in the setup be used in the loop to check if you get the correct frequency in the pot?
Since we get in the second page, I’ll say what my sketch project is about again:

I want one speaker to play a random note. With a potenciometer, you’ll have to adjust a second speaker to play the same note playing in the first one. When you get it right, a LED will light to show you that you got it correct (in other words, the LED is a visual feedback for you to train your ear and know you got the correct frequency).

void setup()
{
  Serial.begin(9600);
  
  randomSeed(analogRead(0));
  int randNote = random(1023);

In the above randNote has a "scope" of setup only. Thus it doesn't exist outside setup. You need to make it global, and set its value in setup:

int randNote;

void setup()
{
  Serial.begin(9600);
  
  randomSeed(analogRead(0));
  randNote = random(1023);

It's important that you remove "int" from the front of the line that gets the randNote value, or you will have two different randNote variables.

Oh finally!!! It worked correctly, just the way I wanted :D!!!!!!!!!! Thank you a lot!!!!!!!!! =)!