Is There Something Wrong?

I have been making a program which plays Fur Elise with a piezo buzzer when you press one button, and The Entertainer when you press another button. I have used this diagram from SparkFun to assemble my project just removing the LED and 330k resistor and replacing them with a piezo buzzer connecting to pin 8.

Here is my code:

#include "pitches.h"

// notes in the melody:
int melody1[] = {
   NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C4, NOTE_E4, NOTE_A4, NOTE_B4, 0, 
   NOTE_E4, NOTE_GS4, NOTE_B4, NOTE_C5, 0, NOTE_E4, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, 
   NOTE_A4, 0, NOTE_C4, NOTE_E4, NOTE_A4, NOTE_B4, 0, NOTE_E4, NOTE_C5, NOTE_B4, NOTE_A4
};

int melody2[] = {
   NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_C5, NOTE_D5, 
   NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, NOTE_A4, NOTE_G4,
   NOTE_FS4, NOTE_A4, NOTE_C5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_A4, NOTE_D5, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, 
   NOTE_E4, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations1[] = {
   8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 2
};

int noteDurations2[] = {
   8, 8, 8, 4, 8, 4, 8, 3, 8, 8, 8, 8, 8, 8, 4, 8, 4, 3, 8, 8, 8, 4, 8, 4, 8, 2.18, 8, 8, 8, 8, 8, 4, 8, 8, 8, 3, 8, 8, 8, 4, 8, 
   4, 8, 3, 8, 8, 8, 8, 8, 8, 4, 8, 4, 3
};

const int button1 = 2;
const int button2 = 3;
const int piezo = 8;

int buttonState1 = 0;
int buttonState2 = 0;

void setup() {
   // iterate over the notes of the melody:
   

     // to calculate the note duration, take one second
     // divided by the note type.
     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. 

     pinMode(piezo, OUTPUT);
     pinMode(button1, INPUT);
     pinMode(button2, INPUT);
   
}

void loop() {
   for (int thisNote = 0; thisNote < 75; thisNote++) {
    
   int noteDuration1 = 1000 / noteDurations1[thisNote];
   int noteDuration2 = 1000 / noteDurations2[thisNote];
  
   // no need to repeat the melody.
   buttonState1 = digitalRead(button1);
   buttonState2 = digitalRead(button2);
   
   if (buttonState1 == HIGH) {
     tone(8, melody1[thisNote], noteDuration1);
     int pauseBetweenNotes1 = noteDuration1 * 1.30;
     delay(pauseBetweenNotes1); }
   else if (buttonState2 == HIGH) {  
     tone(8, melody2[thisNote], noteDuration2); 
     int pauseBetweenNotes2 = noteDuration2 * 1.30;
     delay(pauseBetweenNotes2); }
   else { }
     // stop the tone playing:
     noTone(8);
     }
}

It hasn’t worked at all with the buzzer playing both the tunes at once and it is quite confusing to figure out. :confused: Can anyone tell me if it is the program’s problem, the assembly or both?

Thank you very much! :smiley:

How do you mean "both at once"? The buzzer can only play one note at a time.

How are the button inputs wired ? Do you have any pulldown resistors on them to hold the inputs in a known (LOW) state ? If not then both inputs could be floating at a HIGH value when the buttons are not pressed.

Consider changing to   pinMode(button1, INPUT_PULLUP); to activate the built in pullup resistors and change the logic and wiring to test for LOW when the button is pressed.

MorganS, I meant that the tunes were mixed together.

UKHeliBob, May I know what I should change in the logic and the wiring?

Thank you! :)

May I know what I should change in the logic and the wiring?

Change the switch wiring so that one side of it is connected to GND and the other to the input pin. That will keep the pin HIGH when not pressed if you use

  pinMode(button1, INPUT_PULLUP);

The pin will go LOW when closed.

Change the program logic from

if (buttonState1 == HIGH)

to

if (buttonState1 == LOW)

and the other similar lines, of course.

You mean you don't want them mixed together? Your specification could be clearer. Do you want to press button 1 and have song 1 play to completion, ignoring all button presses? Or do you want button 2 to be able to interrupt song 1 and start song 2 playing from the beginning? Or does button 2 just switch the songs so the 5th note of song 2 comes after the 4th note of song 1?

MorganS, what I want is button 1 to play Fur Elise and button 2 to play the Entertainer. I won't press either of the buttons when any song is playing and when a button is pressed after , it will play the corresponding song from the beginning

Did you try the changes that I suggested in post #4 ?

Yes I have and it doesn't seem to be working. It only plays Fur Elise and occasionally stops when I press a button a few times. Another of my problems are that my buttons keep popping out of my breadboard. Any way to stop that?

Thanks!

itssohard: Another of my problems are that my buttons keep popping out of my breadboard. Any way to stop that?

If you have those tiny push buttons, no, not really. They're not meant for breadboards, and the squiggly wires are designed to hold the switch in place in a pcb hole. I've had limited success in the past re-shaping the wires with pliers, but it never really worked. Best is to mount them on strip-board and solder wires on the legs and take the wires to the breadboard.

How tiny do you mean? My buttons are square shaped with 1.2cm each side. The pins, wires, whatever you call them were always straight but they are not symmetrical and two of the pins are placed slightly more towards the middle. The pins are 0.4cm long each.

Thanks!

Hi,
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Can you please post a copy of your sketch, using code tags?
They are made with the </> icon in the reply Menu.
See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Also a picture of your project so we can see your layout and buttons.

Thanks… Tom… :slight_smile:

It seems like my buttons don't work as the resistance shown on my multimeter doesn't change when I press them. That affects the result right? By the way, TomGeorge I have just edited my post so it shows the code. The link shows the circuit.

Thanks!

itssohard:
It seems like my buttons don’t work

Are they 4-pin buttons? Those have internal connections across pairs of pins, and each pair is switched to the other pair. Simple way to ensure you switch, is to wire on the diagonals.

pushbutton.jpg

the resistance shown on my multimeter doesn't change when I press them. That affects the result right?

Just a bit !

Yes they are 4-pin buttons. I am trying to wire it diagonally but the buttons still keep popping out. Anybody have any solutions?

Thanks!

Anybody have a solutions?

Establish which 2 pins on the buttons are connected when the button is pressed and solder jumper wires to them. Or do as I did and mount several such buttons on a strip of perf board with a common connection to one side of each switch to go to GND and separate connections to the other pins.

The connections are wired to a short length of single row DIP socket mounted on the perf board to allow connection to the Arduino with jumper wires. No resistors required if you use INPUT_PULLUP in pinMode()

Hi

By the way, TomGeorge I have just edited my post so it shows the code. The link shows the circuit.

Please do not got back and edit code, you have made any replys after your code about correcting your code, now redundant. This means anyone later trying to use this thread to solve their own problem, will be confused by the reference code being lost. You should have simply reposted your code.

A picture of your project will be appreciated please as we need to see your component layout, and components. In particular your pressbuttons.

Thanks .. Tom... :)

UPDATE: I have now wired it so that the 5v wire is on the opposite side and the resistors and wires connected to the pins are diagonal to the ground wire on the other side of the button. It now plays Fur Elise when I press and hold down button 1 and doesn't do anything when I press button 2. It continues where it stops when I press button 1 again. Is there a way to make it so that it plays till the end even if I let go of the button, it will play from the beginning when I press it again, and to make button 2 work.

P.S. TomGeorge, I only edited it so that it showed the code and I didn't modify the code at all. A picture of my circuit isn't very easy to attain as I don't have a device to take the picture on.

Thanks!

Your code looks the same as when I looked at it two days ago.

Ok, so my understanding if your specification is the song must play to completion and all button presses are ignored until it is done. That makes it pretty easy to make the song player into an independent function that just plays and doesn’t need to know how to read the buttons.

void playSong(int OutputPin, int Melody[], int NoteDurations[], int NumberOfNotes){ 
  //Using the supplied output pin, play the song defined by the melody and durations arrays.
  //also needs to know the length of the arrays - assumes they are both the same length.
  for (int ThisNote = 0; ThisNote < NumberOfNotes; ThisNote++) {
    
    int NoteDuration = 1000 / NoteDurations[ThisNote];
    tone(OutputPin, Melody[ThisNote], NoteDuration);
    int PauseBetweenNotes = NoteDuration * 1.30; //not a good idea to multiply an int by a float and store the result in an int, but if it seems to work OK, don't change it
    delay(PauseBetweenNotes);
  }
  noTone(OutputPin);
}

void loop() {
   buttonState1 = digitalRead(button1);
   buttonState2 = digitalRead(button2);

   if (buttonState1 == HIGH && buttonState2 == LOW) {
     playSong(8, melody1, noteDuration1, sizeof(melody1)/sizeof(melody1[0]));
   }

   if (buttonState1 == LOW && buttonState2 == HIGH) {
     playSong(8, melody2, noteDuration2, sizeof(melody2)/sizeof(melody2[0]));
   }

   //If both buttons pressed at once, wait until one is released first, then play the other song.
   
}

This only uses one C ‘trick’. To find out how many elements are in an array, it is necessary to use the length of the array in bytes divided by the length of the first item in the array.