Troubles playing a non blocking melody.

Hi there.

I am currently working on a project where I need 4 different buzzers to play simultaneously a 4 notes melody . Initially I though it would be easy..it is not.

I understood pretty fast that the Arduino board, due to timer limitations, is not capable of playing tones simultaneously on numerous buzzers. To go pass this issue, I used the Tone Library made by Bhagman: http://forum.arduino.cc/index.php/topic,6940.0.html.

Now I have an issue with playing a melody rather than a simple note. A melody has pausing times between notes, the issue is I need the arduino to be constantly checking conditions. Basically, I need to play a melody that is [u]non blocking[/u]. Sadly delay and while are blocking fuctions.. could anyone help me with this ?

Thank you in advance for your help.

Take a look at my post "piano tones micros" from last summer. It reads button presses to select the note created - you could change that to be time based instead for playing the notes. Instead of button presses, have an array that you sample every 1/16 frequency or something that is read and holds the appropriate on/off flag for the notes for that time period.

It is possible to play 4 notes at a time by using millis() actually using micros(). No tone library. I'm working on an organ to play one octive. Kinda got put on the back burner. I have it playing 5 now. However this is done with buttons. What is your method to enter the notes in the Arduino? I define the frequencies in a array, but you will also need the time for the notes to play and/rest.

My code from last summer was for 13 notes. I have a link to a youtube video showing 8 at once, all the buttons I had at the time.

Thank you for your responses. It seems that the solution is in the micros(), blink without delay way of coding. Your example “Piano Tunes” is interesting, i will try to adapt it to my problem.

Here you have a picture of my wiring (the hall effect sensors are also wired up to an ardumotor shield and fans, it’s offtopic) :

Here is my current code :

#include <Tone.h>


const int hallPin[4] = {6,7,8,9};        // Pins attributed to hall effect sensors
const int buzzPin[4] = {40,42,44,46};    // Pins attributed to buzzers
const int buzzledPin[4] = {41,43,45,47}; // Pins attributed to Leds for the buzzers

//switches initialisation
const int switchPin = 24;                // Pin attributed to the global on/off switch
const int switchbuzzPin = 32;            // Pin attributed to the buzzers on/off switch

int switchState= 0;                      // Initialisation of the global on/off switch
int switchbuzzState =0;                  // Initialisation of the buzzer on/off switch

// Definition of the tones
Tone jingle1;
Tone jingle2;
Tone jingle3;
Tone jingle4;


void setup()
{
  Serial.begin(9600);
  
  pinMode(switchPin, INPUT);    
  pinMode(switchbuzzPin, INPUT);
  for (int i = 0; i<4;i++){
    pinMode(hallPin[i], INPUT);   
    pinMode(buzzPin[i], OUTPUT); 
    pinMode(buzzledPin[i],OUTPUT);
  }  
}


void loop()
{ 
   switchState=digitalRead(switchPin);            // Reading switchPin state
   switchbuzzState=digitalRead(switchbuzzPin);    // Reading switchbuzzPin state
   
     
   Serial.print("switchbuzzState:");
   Serial.print(switchbuzzState);

      
if (switchState == HIGH)                         // Checking if global switch is ON
 {
    int Counter = 0;
    for (int i=0;i<4;i++)
    {
      if (digitalRead(hallPin[i]) == LOW )         // Checking which hall effect sensor is activated
      {
        digitalWrite(buzzledPin[i], HIGH); 
        Counter++ ;        // Incrementing the counter
        //digitalWrite(buzzledPin[i], HIGH); 
        Serial.print("id:");
        Serial.print(i);                           // Printing the number of the activated hall sensors
      }
      else{
            digitalWrite(buzzledPin[i], LOW); 
       
    }
    }


 
    Serial.print("Counter:");
    Serial.print(Counter);       
  


    Serial.println();
    

  
  if(switchbuzzState == LOW){                    // Checks if the buzzers on/off switch is ON
   
      if(digitalRead(hallPin[0]) == LOW){        // Checks if hall sensor 1 is activated
        if(switchbuzzState == LOW){  
        //digitalWrite(buzzledPin[0], HIGH); 
        jingle1.begin(buzzPin[0]);               // Prepares buzzer 1 to play
        jingle1.play(NOTE_C4, 4000);        // Orders buzzer 1 to play C4 during 4 sec 
       
      //  jingle1.play(NOTE_D4, 2000 );   
      //  jingle1.play(NOTE_F4, 1000);  
      //  jingle1.play(NOTE_G4, 1500);
        }
      }
      if(digitalRead(hallPin[1]) == LOW){        // Checks if hall sensor 2 is activated
        if(switchbuzzState == LOW){  
        //digitalWrite(buzzledPin[1], HIGH); 
        jingle2.begin(buzzPin[1]);               // Prepares buzzer 2 to play
        jingle2.play(NOTE_D4, 4000);             // Orders buzzer 2 to play D4 during 4 sec
        }
      }
      if(digitalRead(hallPin[2]) == LOW){
          if(switchbuzzState == LOW){  
        //digitalWrite(buzzledPin[2], HIGH); 
        jingle3.begin(buzzPin[2]);
        jingle3.play(NOTE_F4, 4000);
          }
      }
      if(digitalRead(hallPin[3]) == LOW){
          if(switchbuzzState == LOW){  
        //digitalWrite(buzzledPin[3], HIGH); 
        jingle4.begin(buzzPin[3]);
        jingle4.play(NOTE_G4, 4000);
          }
      }      
  }
 }
else{
}

}

At this point, with the Tone Library, I am able to play a note on each of the 4 buzzers simultaneously but not a melody.
Moreover after 3 plays, the circuit seems to freeze… The buzzers and switches are not responding anymore. Any idea on that ?

I will look deeper into the micros() solution .

Thank you !