Find an error in the code

I am making an arduino piano, only 4 buttons work and once.

#define NOTE_A 262
#define NOTE_B 294
#define NOTE_C 330
#define NOTE_D 392
#define NOTE_E 493

const int SPEAKER=13;
const int BUT_A=2;
const int BUT_B=3;
const int BUT_C=4;
const int BUT_D=5;
const int BUT_E=7;

void setup() {
 pinMode(13, OUTPUT);
 pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
   pinMode(4, INPUT_PULLUP);
    pinMode(5, INPUT_PULLUP);
     pinMode(7, INPUT_PULLUP);
}

void loop() {
  while (digitalRead(BUT_A)==1);
tone(SPEAKER, NOTE_A, 30);

 while (digitalRead(BUT_B)==1);
 tone(SPEAKER, NOTE_B, 30);

while (digitalRead(BUT_C)==1);
 tone(SPEAKER, NOTE_C, 30);

 while (digitalRead(BUT_D)==1);
 tone(SPEAKER, NOTE_D, 30);

 while (digitalRead(BUT_E)==1);
 tone(SPEAKER, NOTE_E, 30);

 noTone(SPEAKER);
} 

Careful with the semicolons at the end of the while line. Is that what you want? Wait as long as the pin is high and then issue a sound that will last for 30ms, and go wait for the next button press?

Unless I'm mistaken, it's not your coding but your logic that is flawed.

wait for key A {}
play A
wait for key B {}
play B

It can only monitor one key at a time. So while it is waiting for key A, all the other keys are dead.

You just need to sit back, and think about how to check them one at a time in sequence, but without halting like that.

Then code.

I need me to press the button and there was a sound, but this only works on 4 out of 5 buttons and only once, then I have to restart the program. I do not know how to fix it, but it is very urgent ((((

I don't understand how to fix the error

It may help you to look at your loop function and write out in plain English (or your native language) what you believe each line does. Take into account the hints you've already been given and I'm sure you will find the problem(s).

It should not be necessary to use the noTone() function, since you specify a duration for the tones. The tone() function with duration is non-blocking, it uses a timer to turn off the tone after the proper interval.

What is happening is that, with no buttons pressed, the code executes all the tone() function calls, starting the tone output, but then immediately turns it off with noTone(). When you press a button, it allows the tone immediately prior to the while() to continue for the full 30mS, so you can now hear the tone. The last tone() function call in the loop you will never hear, because it is immediately turned off by the noTone() before the code continues at the start of loop(), so you never hear any output when button A is pressed.

1 Like
while (digitalRead(BUT_A)==1) {
tone(SPEAKER, NOTE_A, 30);
}
 while (digitalRead(BUT_B)==1) {
 tone(SPEAKER, NOTE_B, 30);
}
while (digitalRead(BUT_C)==1) {
 tone(SPEAKER, NOTE_C, 30);
}
 while (digitalRead(BUT_D)==1) {
 tone(SPEAKER, NOTE_D, 30);
}
 while (digitalRead(BUT_E)==1) {
 tone(SPEAKER, NOTE_E, 30);
}
 noTone(SPEAKER);

right?

when you press the last button you issue the tone() command so you get a sound going but micro-seconds laters you call noTone() so you won't be able to hear the sound.

the structure of the code is not really good for an arduino piano... you can't press the last button until you have pressed all the other ones...

there are countless examples on line, here are a couple hits

Why is it so urgent?

Not urgent enough to consider and respond to my suggestions? I didn't post a specific solution because I don't believe you would learn anything from that. But I am convinced that if you think about what I said, research C, and study the flow of your own program you will be able to see and fix the problem yourself.

Try this:

#define NOTE_A 262
#define NOTE_B 294
#define NOTE_C 330
#define NOTE_D 392
#define NOTE_E 493

const int SPEAKER = 13;
#define BUT_A 2
#define BUT_B 3
#define BUT_C 4
#define BUT_D 5
#define BUT_E 7

#define BUT_PRESSED HIGH

const byte BUTTONS[] = { BUT_A, BUT_B, BUT_C, BUT_D, BUT_E };
const int NOTES[] = { NOTE_A, NOTE_B, NOTE_C, NOTE_D, NOTE_E };

void setup() {
  pinMode(13, OUTPUT);

  for (int i = 0; i < sizeof(BUTTONS); i++)
    pinMode(BUTTONS[i], INPUT_PULLUP);
}

void loop() {
  unsigned int note = 0;
  unsigned int divisor = 0;

  for (int i = 0; i < sizeof(BUTTONS); i++) {
    if (digitalRead(BUTTONS[i]) == BUT_PRESSED) {
      note += NOTES[i];
      divisor++;
    }
  }

  if (divisor)
    note /= divisor;

  tone(SPEAKER, note);
}

You might have to change BUT_PRESSED to LOW, can't really see how you wired your buttons. Make sure the buttons are read correctly if it doesn't work (check pin numbers and wiring).
Should also work with multiple button presses.

1 Like

Because there is no wiring diagram.

Ok, from this you have to change BUT_PRESSED to LOW and it should work. Have you tried it?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.