Go Down

Topic: Troubles playing a non blocking melody. (Read 567 times) previous topic - next topic


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 non blocking. 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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.


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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.


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 :
Code: [Select]
#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()
  pinMode(switchPin, INPUT);   
  pinMode(switchbuzzPin, INPUT);
  for (int i = 0; i<4;i++){
    pinMode(hallPin[i], INPUT);   
    pinMode(buzzPin[i], OUTPUT);

void loop()
   switchState=digitalRead(switchPin);            // Reading switchPin state
   switchbuzzState=digitalRead(switchbuzzPin);    // Reading switchbuzzPin state

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(i);                           // Printing the number of the activated hall sensors
            digitalWrite(buzzledPin[i], LOW);



  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.play(NOTE_F4, 4000);
      if(digitalRead(hallPin[3]) == LOW){
          if(switchbuzzState == LOW){ 
        //digitalWrite(buzzledPin[3], HIGH);
        jingle4.play(NOTE_G4, 4000);


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 !

Go Up