Arduino metronom - Schimbarea semnăturii de timp la apăsarea butonului

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


  }

}

Încerc să fac un metronom folosind Arduino Uno, cu 4 LED-uri, fiecare LED este un bate. Vreau să schimb semnătura de timp de fiecare dată când apăs butonul, astfel că există un număr diferit de bătăi pe măsură, dar când apăs butonul, rulează codul pentru 2 și 3 bătăi pe măsură o dată și apoi se întoarce la default, 4 batai pe masura.

Uneori, chiar se schimbă fără a apăsa butonul, aleatoriu. Folosesc un resistor de 220 ohmi în loc de 10, deoarece 10 începe mult mai aleator decât 220.

Metronome project picture

1
Nu există rezistoare cu acele LED-uri
adăugat autor Joshua, sursa
Aveți rezistoare în serie cu acele LED-uri?
adăugat autor Nick Gammon, sursa

1 răspunsuri

Trebuie să aveți rezistențe în serie cu LED-urile. Consultați Îngrijirea și alimentarea LED-urilor . 330 ohmi în serie cu fiecare LED-uri ar fi exact în situația dumneavoastră.

Cu nici o rezistență nu trageți prea mult curent de la pinii de ieșire. Asta ar scădea tensiunea și procesorul ar fi resetat. Astfel, se întoarce la default de 4 batai pe măsură.

Deteriorează, de asemenea, atât procesorul, cât și LED-urile.

Puteți afla dacă procesorul se resetează prin adăugarea unui cod suplimentar în setup . De exemplu, după setarea pinilor la ieșiri:

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

Dacă vedeți pinul 3 care clipește de 10 ori, știți că procesorul a fost resetat.


Cred că problema dvs. acum este că aveți o intrare plutitoare pentru comutator. Când am încercat schița dvs., cu câteva modificări, a funcționat bine.

Codul meu:

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

Rețineți că intrarea de la comutator este acum INPUT_PULLUP ceea ce înseamnă că este tras HIGH de către un rezistor intern. Astfel, testele sunt acum pentru == LOW mai degrabă decât == HIGH .

De asemenea, în loc de o întârziere pentru sincronizarea metronomului, l-am schimbat la testarea millis() și am văzut dacă timpul este în sus. În caz contrar, trebuie să țineți comutatorul în jos pentru întreaga perioadă în care se repetă un ciclu.

1
adăugat
Acum că am rezistoare, butonul încă nu schimbă semnătura de timp (ts). Cum pot să fac acest lucru în mod diferit sau să schimb codul?
adăugat autor Joshua, sursa
Consultați răspunsul modificat.
adăugat autor Nick Gammon, sursa