Arduino metronom - Düğmeye basıldığında zaman imzasını değiştirin

/**************************************/
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);
}

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

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



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

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

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

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

    bpm = pulseIn(6, HIGH);

    pinMode(13, 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(13, 1500, 100);
    else
      tone(13, 1000, 100);

    delay(bpm - 52);
    pinMode(13, INPUT);
    digitalWrite(thisPin, LOW);


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


  }

}

Arduino Uno'yu kullanarak 4 metrelik bir metronom yapmaya çalışıyorum, her LED bir ritim. Düğmeye her basışımda zaman imzasını değiştirmek istiyorum, böylece ölçüm başına farklı atım sayısı vardır, ancak düğmeye bastığım zaman, kod başına ölçüm başına 2 ve 3 atım için bir kez çalışır ve sonra geri döner. varsayılan değerine göre, ölçü başına 4 atış.

Bazen rastgele düğmeye basmadan bile değişiyor. 10 yerine 220 ohm rezistans kullanıyorum, çünkü 10 220'den daha rasgele başlar.

Metronome project picture

1
Bu LED'lerde direnç yok
katma yazar Joshua, kaynak
Bu LED'lerle seri olarak direnç var mı?
katma yazar Nick Gammon, kaynak

1 cevap

LED'lerle seri halde dirençlere sahip olmalısınız. LED’lerin bakımı ve beslenmesi bölümüne bakın. Her bir LED ile seri olarak 330 ohm, durumunuzda doğru olacaktır.

Dirençsiz olarak, çıkış pinlerinden çok fazla akım çekiyorsunuzdur. Bu gerilimi düşürür ve işlemci sıfırlanır. Bu nedenle, ölçü başına 4 atımın varsayılan değerine geri döner.

Ayrıca, hem işlemciye hem de LED'lere zarar verir.

İşlemcinin setup 'a fazladan kod ekleyerek sıfırlanıp sıfırlanmadığını anlayabilirsiniz. Örneğin, pimleri çıkışlara ayarladıktan sonra:

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

Pin 3'ün 10 kez yanıp söndüğünü görürseniz, işlemcinin sıfırlandığını bilirsiniz.


Sanırım şu anki sorunun, anahtar için değişken bir girişin olması. Çiziminizi denediğimde, birkaç değişiklikle, iyi sonuç verdi.

Benim kod:

/**************************************/
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

Şalterden gelen girişin INPUT_PULLUP olduğuna dikkat edin, bu dahili bir direnç tarafından HIGH çekildiği anlamına gelir. Bu nedenle, testler artık == HIGH yerine == LOW içindir.

Ayrıca, metronomun zamanlaması için bir gecikme yerine, millis() testini ve zamanın dolup dolmadığını görmek için değiştirdim. Aksi halde, bir döngünün tekrar ettiği süre boyunca düğmeyi basılı tutmanız gerekir.

1
katma
Şimdi dirençlere sahibim, düğme hala zaman imzasını değiştirmiyor. Bunu farklı şekilde nasıl bağlayabilirim veya kodu değiştirebilirim?
katma yazar Joshua, kaynak
Değiştirilen cevaba bakınız.
katma yazar Nick Gammon, kaynak