Digital Pins Problem

Hi !!!
I am building a laser harp project and at first i was using one and only speaker.My project has 6 laser strings so it has to play six notes. I decided to connect 6 speakers,one for each one of the lasers so that every speaker plays only one note.The problem is that i can't use more than three digital pins.How i understood that ??? In the code below as you see i am using pins 3-8 one for each speaker.
when i run the program the only speakers that producing the tones are the first three (pin 3, pin 4 and pin 5).But if i change the code like the one that is on the right again only the first three pins are working (pin 3,pin 8 amd pin 7).Why this is happening ????

void setup(void)
{
  Serial.begin(9600);

  aSpeaker1.begin(3); // first speaker at digital pin 3                           aSpeaker1.begin(3);
  aSpeaker2.begin(4); // second speaker at digital pin 4                       aSpeaker2.begin(8);
  aSpeaker3.begin(5); // third speaker at digital pin 5                          aSpeaker3.begin(7);
  aSpeaker4.begin(6); // fourth speaker at digital pin 6                         aSpeaker4.begin(6);
  aSpeaker5.begin(7); // fifth speaker at digital pin 7                            aSpeaker5.begin(5);
  aSpeaker6.begin(8); // sixth speaker at digital pin 8                           aSpeaker6.begin(4);
}

Here is the full source code of my project

#include <Tone.h>

int notes[] = { NOTE_A3,
                NOTE_B3,
                NOTE_C4,
                NOTE_D4,
                NOTE_E4,
                NOTE_F4,
                NOTE_G4 };
int lightPin1 = 0;  //define a pin for Photo resistor
int lightPin2 = 1;  //define a pin for Photo resistor
int lightPin3 = 2;  //define a pin for Photo resistor
int lightPin4 = 3;  //define a pin for Photo resistor
int lightPin5 = 4;  //define a pin for Photo resistor
int lightPin6 = 5;  //define a pin for Photo resistor

int reading;
// You can declare the tones as an array
Tone aSpeaker1;
Tone aSpeaker2;
Tone aSpeaker3;
Tone aSpeaker4;
Tone aSpeaker5;
Tone aSpeaker6;

void setup(void)
{
  Serial.begin(9600);

  aSpeaker1.begin(3); // first speaker at digital pin 3
  aSpeaker2.begin(4); // second speaker at digital pin 4
  aSpeaker3.begin(5); // third speaker at digital pin 5
  aSpeaker4.begin(6); // fourth speaker at digital pin 6
  aSpeaker5.begin(7); // fifth speaker at digital pin 7
  aSpeaker6.begin(8); // sixth speaker at digital pin 8
}

void loop(void)
{
  reading = analogRead(lightPin1);
  if(reading < 50) // when the laser hits the photoresistor the value of the photoresistor goes to 280 and when not hit goes to 20. 
  {                    // So if reading goes under 50 (that means that the laser beam is interupted) 
    aLaser1.play(130,400); // produce 130 Hz for 400 msecond to the first speaker.
  }
  
  reading = analogRead(lightPin2);
  if(reading < 50) 
  {
    aLaser2.play(140,400);
  }
  
  reading = analogRead(lightPin3);
  if(reading < 50) 
  {
    aLaser3.play(160,400);
  }
  
  reading = analogRead(lightPin4);
  if(reading < 50) 
  {
    aLaser4.play(170,400);
  }
  
  reading = analogRead(lightPin5);
  if(reading < 50) 
  {
    aLaser5.play(190,400);
  }
  
  reading = analogRead(lightPin6);
  if(reading < 50) 
  {
    aLaser6.play(200,400);
  }
  
       
}

The best way to chop this in 1/2 is to print out the values you are getting to the serial monitor.

Also - I would remove the if statements and just test them all with very simple code and see if that works.

void loop(void)
{
    aSpeaker1.play(130,400); // produce 130 Hz for 400 msecond to the first speaker.
    aSpeaker2.play(140,400);
    aSpeaker3.play(160,400);
    aSpeaker4.play(170,400);
    aSpeaker5.play(190,400);
    aSpeaker6.play(200,400);
       
}

Using this technique, you should be able to determine if the problem is a limit or code logic / values being read, etc.

marklar:
The best way to chop this in 1/2 is to print out the values you are getting to the serial monitor.

Also - I would remove the if statements and just test them all with very simple code and see if that works.

void loop(void)

{
    aSpeaker1.play(130,400); // produce 130 Hz for 400 msecond to the first speaker.
    aSpeaker2.play(140,400);
    aSpeaker3.play(160,400);
    aSpeaker4.play(170,400);
    aSpeaker5.play(190,400);
    aSpeaker6.play(200,400);
       
}



Using this technique, you should be able to determine if the problem is a limit or code logic / values being read, etc.

Nope same thing happens only the first three are playing

How about this .. do they play?

void loop(void)
{
    aSpeaker4.play(170,400);
    aSpeaker5.play(190,400);
    aSpeaker6.play(200,400);
       
}

marklar:
How about this .. do they play?

void loop(void)

{
   aSpeaker4.play(170,400);
   aSpeaker5.play(190,400);
   aSpeaker6.play(200,400);
     
}

Same thing again.

The problem is when i declare the pins for each speaker.
It uses the first three pins that i have them in Bold (pin 3 ,pin 4 and pin 5)

void setup(void)
{
Serial.begin(9600);

aSpeaker1.begin(3); // first speaker at digital pin 3 **
** aSpeaker2.begin(4); // second speaker at digital pin 4 **
** aSpeaker3.begin(5); // third speaker at digital pin 5

aSpeaker4.begin(6); // fourth speaker at digital pin 6
aSpeaker5.begin(7); // fifth speaker at digital pin 7
aSpeaker6.begin(8 ); // sixth speaker at digital pin 8
}

If i change the declaration of the pins to the following , again it uses the first three pins (pin 8 ,pin 7 amd pin 6)

void setup(void)
{
Serial.begin(9600);

aSpeaker1.begin(8 ); // first speaker at digital pin 8 **
** aSpeaker2.begin(7); // second speaker at digital pin 7 **
** aSpeaker3.begin(6); // third speaker at digital pin 6

aSpeaker4.begin(5); // fourth speaker at digital pin 5
aSpeaker5.begin(4); // fifth speaker at digital pin 4
aSpeaker6.begin(3); // sixth speaker at digital pin 3
}

If i have three speakers connected to 8 ,7 and 6 pins they produce sound ,but if i take the cable from pin 7 and connect it to pin 4 or 3 or 5 only the speakers at pin 8 and 7 will continue playing

Same thing again.

Does that mean they did or did not play. Same thing could be "first three played" or could be "those three didn't play, just like last time" .. so please clarify.

I thought the tone library could only handle three notes at a time anyway? Have you seen somewhere where it says different?

From this document ....
http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation#Ugly_Details

You can output the tones on any pin (arbitrary). The number of tones that can be played simultaneously depends on the number of hardware timers (with CTC capability) available on the microcontroller.

ATmega8: 2 (timers 2, and 1)
ATmega168/328: 3 (timers 2, 1, and 0)
ATmega1280: 6 (timers 2, 3, 4, 5, 1, 0)
The timer order given above is the order in which the timers are allocated. Timer 0 is a sensitive timer on the Arduino since it provides millis() and PWM functionality.

Does this mean you can run 3 on a 328 and 6 on a mega?

@polonos13: I'm guessing you are using a Duemilanove or an Uno. These boards use the '328 chip. This means that you will only be able to have 3 tones declared at any time. You have two options: either get a board with a '1280 chip, or get a second '328 board. In the latter case, you'll have to communicate with the second controller the tones you want it to play. I can help you with that.

@marklar: Indeed. The timers will ONLY be used for Tone, though. This means that if you use all of the timers, you won't be able to use millis(), PWM, etc...

@Grumpy_Mike: The Tone library is pretty straightforward. One OCx output per timer (in CTC mode), so if the controller has 3 timers, 3 tones, and likewise for the '2560 with 6 timers, 6 tones.

b

I ve figured how to make my laser harp playing a little better than before.You see my problem was that when i had one speaker for producing the notes,when i interrupt one and only laser beam the tone played well.But when i was interrupting two laser beams at the same time the notes for each interrupted beam was played at the same time from the one and only speaker and the mixing of the two tones was awfull. Now i 've conncted 3 speakers and i have 6 laser beams. The first laser goes with speaker 1 ,the second laser goes with speaker 2 ,the third laser goes with speaker 3, the fourth lase goes with speaker 1, the fifth laser goes with speaker 2 and the sixth laser goes with speaker 3.The only problem is when i hit at the same time the laser 1 and 4 together or the laser 2 and 5 together or the laser 3 and 6 together because these pairs are using the same speaker. So i've changed my source code a little and if one of the 3 combinations comes up a totally different sound is played by the speaker connected with the pair.

#include <Tone.h>

int lightPin1 = 0;  //define a pin for Photo resistor
int lightPin2 = 1;  //define a pin for Photo resistor
int lightPin3 = 2;  //define a pin for Photo resistor
int lightPin4 = 3;  //define a pin for Photo resistor
int lightPin5 = 4;  //define a pin for Photo resistor
int lightPin6 = 5;  //define a pin for Photo resistor

int reading;
int reading2;

// You can declare the tones as an array

Tone aLaser1;
Tone aLaser2;
Tone aLaser3;
Tone aLaser4;
Tone aLaser5;
Tone aLaser6;

void setup(void)
{
  Serial.begin(9600);
  aLaser1.begin(3);
  aLaser2.begin(4);
  aLaser3.begin(5);
}

void loop(void)
{
  reading = analogRead(lightPin1);
  if(reading < 50) 
  {
    aLaser1.play(130,400);
  }
  
  reading = analogRead(lightPin2);
  if(reading < 50) 
  {
    aLaser2.play(140,400);
  }
  
  reading = analogRead(lightPin3);
  if(reading < 50) 
  {
    aLaser3.play(160,400);
  }
  
  reading = analogRead(lightPin4);
  if(reading < 50) 
  {
    aLaser1.play(170,400);
  }
  
  reading = analogRead(lightPin5);
  if(reading < 50) 
  {
    aLaser2.play(190,400);
  }
  
  reading = analogRead(lightPin6);
  if(reading < 50) 
  {
    aLaser3.play(200,400);
  }
  
  
  ////////////////////////////////////////////////////
  //         This is the code for the combinations          //
  //////////////////////////////////////////////////// 

  reading = analogRead(lightPin6);
  reading2 = analogRead(lightPin3);

  while(reading < 50 && reading2 < 50) 
  {
    aLaser3.play(220,400);
    
       reading = analogRead(lightPin6);
       reading2 = analogRead(lightPin3);
       if(reading >50 || reading2 >50)
       aLaser3.stop();
  }
  
  
  reading = analogRead(lightPin5);
  reading2 = analogRead(lightPin2);
  while(reading < 50 && reading2 < 50) 
  {
    aLaser2.play(240,400);
    
       reading = analogRead(lightPin5);
       reading2 = analogRead(lightPin2);
       if(reading >50 || reading2 >50)
       aLaser2.stop();
  }
  
  
  reading = analogRead(lightPin4);
  reading2 = analogRead(lightPin1);
  while(reading < 50 && reading2 < 50) 
  {
    aLaser1.play(260,400);
    
       reading = analogRead(lightPin4);
       reading2 = analogRead(lightPin1);
       if(reading >50 || reading2 >50)
       aLaser1.stop();
  }
       
}//void loop