Skip to main content
Added suggested code.
Source Link
Nick Gammon
  • 38.9k
  • 13
  • 70
  • 126

I think your problem now is that you have a floating input for the switch. When I tried your sketch, with a couple of modifications, it worked fine.

My code:

/**************************************/
const int lowestPin = 1;//the lowest one attach to
const int speaker = 13;
int ts = 4;//how many beats you want
int count = 1;
const int keyPin = 12;
int buttonState = 0;
int bpm = 120;
/**************************************/
void setup()
{
  for (int thisPin = 1; thisPin <= ts; thisPin++)
  {
    pinMode(thisPin, OUTPUT); //initialize thisPin as an output
    pinMode(6, INPUT);
  }
  pinMode(keyPin, INPUT_PULLUP);
}

/****************************************/
void loop()
{

  //iterate over the pins
  //turn the led on from lowest to the highest

  if (digitalRead(keyPin) == LOW && ts == 2) {
    ts = 3;
    delay(2000);
  }

  else if (digitalRead(keyPin) == LOW && ts == 3) {
    ts = 4;
    delay(2000);
  }

  else if (digitalRead(keyPin) == LOW && ts == 4)
  {
    ts = 2;
    delay(2000);
  }

  for (int thisPin = 1; thisPin <= ts; thisPin++)
  {

    bpm = pulseIn(6, HIGH);
    //bpm = 1000;

    pinMode(speaker, OUTPUT);
    if (ts > 4)
    {
      if (count > 3)
        for (int a = 4; a <= ts; a++) {
          digitalWrite(a - 3, HIGH);
        }
    }
    else
      digitalWrite(thisPin, HIGH);

    if (count == 1)
      tone(speaker, 1500, 100);
    else
      tone(speaker, 1000, 100);

    unsigned long now = millis ();
    while (millis () - now < (bpm - 52))
      {
      // quit delay if switch pressed
      if (digitalRead(keyPin) == LOW)
        break;
      }
      
    pinMode(speaker, INPUT);
    digitalWrite(thisPin, LOW);

    count++;
    if (count > ts)
      count = 1;

  } // end of for each pin

} // end of loop

Note that the input from the switch is now INPUT_PULLUP which means it is pulled HIGH by an internal resistor. Thus, the tests are now for == LOW rather than == HIGH.

Also, instead of a delay for the timing of the metronome, I changed it to testing millis() and seeing if time is up. Otherwise you have to hold the switch down for the entire time that a cycle repeats.


I think your problem now is that you have a floating input for the switch. When I tried your sketch, with a couple of modifications, it worked fine.

My code:

/**************************************/
const int lowestPin = 1;//the lowest one attach to
const int speaker = 13;
int ts = 4;//how many beats you want
int count = 1;
const int keyPin = 12;
int buttonState = 0;
int bpm = 120;
/**************************************/
void setup()
{
  for (int thisPin = 1; thisPin <= ts; thisPin++)
  {
    pinMode(thisPin, OUTPUT); //initialize thisPin as an output
    pinMode(6, INPUT);
  }
  pinMode(keyPin, INPUT_PULLUP);
}

/****************************************/
void loop()
{

  //iterate over the pins
  //turn the led on from lowest to the highest

  if (digitalRead(keyPin) == LOW && ts == 2) {
    ts = 3;
    delay(2000);
  }

  else if (digitalRead(keyPin) == LOW && ts == 3) {
    ts = 4;
    delay(2000);
  }

  else if (digitalRead(keyPin) == LOW && ts == 4)
  {
    ts = 2;
    delay(2000);
  }

  for (int thisPin = 1; thisPin <= ts; thisPin++)
  {

    bpm = pulseIn(6, HIGH);
    //bpm = 1000;

    pinMode(speaker, OUTPUT);
    if (ts > 4)
    {
      if (count > 3)
        for (int a = 4; a <= ts; a++) {
          digitalWrite(a - 3, HIGH);
        }
    }
    else
      digitalWrite(thisPin, HIGH);

    if (count == 1)
      tone(speaker, 1500, 100);
    else
      tone(speaker, 1000, 100);

    unsigned long now = millis ();
    while (millis () - now < (bpm - 52))
      {
      // quit delay if switch pressed
      if (digitalRead(keyPin) == LOW)
        break;
      }
      
    pinMode(speaker, INPUT);
    digitalWrite(thisPin, LOW);

    count++;
    if (count > ts)
      count = 1;

  } // end of for each pin

} // end of loop

Note that the input from the switch is now INPUT_PULLUP which means it is pulled HIGH by an internal resistor. Thus, the tests are now for == LOW rather than == HIGH.

Also, instead of a delay for the timing of the metronome, I changed it to testing millis() and seeing if time is up. Otherwise you have to hold the switch down for the entire time that a cycle repeats.

Source Link
Nick Gammon
  • 38.9k
  • 13
  • 70
  • 126

You must have resistors in series with the LEDs. See The care and feeding of LEDs. 330 ohms in series with each LED would be about right in your situation.

With no resistors you are drawing far too much current from the output pins. That would drop the voltage and the processor would reset. Thus it goes back to the default of 4 beats per measure.

It also damages both the processor and the LEDs.

You can tell if the processor resets by putting extra code into setup. For example, after setting the pins to outputs:

 for (int i = 0; i < 10; i++)
    {
    digitalWrite (3, HIGH);
    delay (200);
    digitalWrite (3, LOW);
    delay (200);
    }

If you see pin 3 flashing 10 times, you know the processor has reset.