Go Down

Topic: Troubles playing a non blocking melody. (Read 1 time) 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

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131