Digitální metronom

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Odpovědět
AnChv37
Příspěvky: 3
Registrován: 27 kvě 2020, 22:02
Reputation: 0

Digitální metronom

Příspěvek od AnChv37 » 27 kvě 2020, 22:26

Metronom.ino
(4.18 KiB) Staženo 134 x
Dobrý den
Jsem nováček zde na fóru i co se týká arduina
A potřebovala bych vaší pomoc.
Snažím se vytvořit jako maturitní práci digitální metronom.
Jedná se o metronom řízený 4-mi tlačítky (-10,-1,+1,+10) a pátým změnou taktu na 3/4, 4/4, 5/4.....
Dále tam mám dvě diody, který by měly blikat, jak tiká buzzer.
Kód mám napsaný, ale netiká mi to.
Kdyby byl někdo hodný a případně se na to koukl byla bych mu velice vděčná.
S případnými dotazy se na mě obracejte, děkuji všem za pomoc

Kód je vložen v příloze

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Digitální metronom

Příspěvek od martinius96 » 28 kvě 2020, 22:45

Ahoj, v tom kóde sú chyby... Nedá sa skompilovať, funkcia handleButtons() nie je ukončená (neviem, kde má končiť).
A sú tam dve ukončovacie zátvorky } } navyše + funkcia showEighths() nie je definovaná... Z tohto pohľadu nemám ako ten program správne vyskladať, lebo neviem čo kde končí a ako to má byť po správnosti zapísané.

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Digitální metronom

Příspěvek od martinius96 » 29 kvě 2020, 12:05

Skúsil som vytvoriť jednoduchú implementáciu podľa vzoru toho pôvodného metronómu, už som našiel aj jeho zdroj: https://github.com/Aemmel/arduino-Proje ... tronom.ino
Pridal som tam debounce pre jednotlivé tlačidlá s dĺžkou 50ms, upravil som logiku celého metronómu a funkcie jeho spúštania.
Nevyužívam tam displej, výpis sa realizuje len na Sériový monitor, v podstate som len zmenit lcd.print na Serial.print...

Čo sa týka logiky, BPM sa dá nastavovať neobmedzene (do limitu int), i keď beep trvá 50ms, teda 200 BPM je v podstate max, respektíve ak je treba vyššie BPM, je nutné skrátiť ten čas beepu. Doplnil som aj takty 3/4, 4/4 (zapnutý natívne), 5/4, medzi ktorými je možné prepínať tým piatym tlačidlom. Dúfam, že som tie takty zapísal dobre, naposledy som mal husle v ruke pred 9 rokmi :lol:

Musel som upraviť aj pinout, nakoľko sa tam využívalo jedno tlačidlo v pôvodnom programe na pine D1 --> TX, teda by mi to blokovalo hardvérovú Sériovú linku. Program som vyskúšal, myslím že ako prototyp je funkčný, ktorý je možné ďalej rozširovať ;) .
Vyskúšaj prosím a daj vedieť, ako to funguje..
Obrázek
Programová implementácia:

Kód: Vybrat vše

//Autor: Martin Chlebovec (martinius96)
//Projekt: Metronóm - UART only
//Revízia: 29. May 2020

//Nastavenie vývodov Arduina k jednotlivým perifériám (Vstupy, výstupy)
const int BUZZER = 9;
const int LED_BLU = 8;
const int LED_RED = 7;
const int BUT_CHANGE_TICK = 6;
const int BUT_plusone = 5;
const int BUT_minusone = 4;
const int BUT_plusten = 3;
const int BUT_minusten = 2;

//Nastavenie počiatočných časových premenných s millis()
unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long lastDebounceTime4 = 0;
unsigned long lastDebounceTime5 = 0;
unsigned long debounceInterval = 50;
unsigned long elapsedInterval = 0;
unsigned long interval = 1000; //interval tikání v milisekundách

//Nastavenie počiatočných stavov tlačidiel
int buttonState1 = HIGH;
int buttonState2 = HIGH;
int buttonState3 = HIGH;
int buttonState4 = HIGH;
int buttonState5 = HIGH;

//Nastavenie posledných stavov tlačidiel
int lastButtonState1 = HIGH;
int lastButtonState2 = HIGH;
int lastButtonState3 = HIGH;
int lastButtonState4 = HIGH;
int lastButtonState5 = HIGH;

//Deklarácia hodnôt frekvencií pre doby + poslednú dobu, rytmus, atď...
const int freqFirst = 1700;
const int freqFourths = 1500;
int rythm = 4;
int freq = 0;
int bpm = 0;
int tick_case = 0;
int actual = 0;

//Defínicia funkcie pre výpis BPM
void showBPM()
{
  // bpm = 60000 / interval;
  Serial.print("BPM: ");
  Serial.println(bpm);
}

//Defínicia funkcie pre výpis rytmusu
void showRythm()
{
  Serial.print("Takt: ");
  Serial.print(rythm);
  Serial.println("/4");
}

//Defínicia funkcie s volaním funkcií pre výpis BPM, rytmusu
void aktualizaceDispleje()
{
  showBPM();
  showRythm();
}

void setup() {
  //počiatočné nastavenie výstupov a vstupov
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_BLU, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(BUT_CHANGE_TICK, INPUT_PULLUP);
  pinMode(BUT_plusone, INPUT_PULLUP);
  pinMode(BUT_minusone, INPUT_PULLUP);
  pinMode(BUT_plusten, INPUT_PULLUP);
  pinMode(BUT_minusten, INPUT_PULLUP);
  Serial.begin(115200);

}

void loop() {
  int reading1 = digitalRead(BUT_plusone);
  int reading2 = digitalRead(BUT_minusone);
  int reading3 = digitalRead(BUT_plusten);
  int reading4 = digitalRead(BUT_minusten);
  int reading5 = digitalRead(BUT_CHANGE_TICK);

  if (reading1 != lastButtonState1) {
    lastDebounceTime1 = millis();
  }

  if (reading2 != lastButtonState2) {
    lastDebounceTime2 = millis();
  }

  if (reading3 != lastButtonState3) {
    lastDebounceTime3 = millis();
  }

  if (reading4 != lastButtonState4) {
    lastDebounceTime4 = millis();
  }

  if (reading5 != lastButtonState5) {
    lastDebounceTime5 = millis();
  }

  if ((millis() - lastDebounceTime1) >= debounceInterval) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;
      if (buttonState1 == HIGH) {
        bpm = bpm + 1; //bmp + 1
        interval = 60000 / bpm;
        freq = freqFirst;
        aktualizaceDispleje();
        digitalWrite(LED_RED, LOW);
        digitalWrite(LED_BLU, HIGH);
        tone(BUZZER, freq);
        actual = 1;
        elapsedInterval = millis();
      }
    }
  }

  if ((millis() - lastDebounceTime2) >= debounceInterval) {
    if (reading2 != buttonState2) {
      buttonState2 = reading2;
      if (buttonState2 == HIGH) {
        bpm = bpm - 1; //bmp - 1
        if (bpm < 0) {
          bpm = 0;
        }
        interval = 60000 / bpm;
        freq = freqFirst;
        aktualizaceDispleje();
        digitalWrite(LED_RED, LOW);
        digitalWrite(LED_BLU, HIGH);
        tone(BUZZER, freq);
        actual = 1;
        elapsedInterval = millis();
      }
    }
  }

  if ((millis() - lastDebounceTime3) >= debounceInterval) {
    if (reading3 != buttonState3) {
      buttonState3 = reading3;
      if (buttonState3 == HIGH) {
        bpm = bpm + 10; //bmp + 10
        interval = 60000 / bpm;
        freq = freqFirst;
        aktualizaceDispleje();
        digitalWrite(LED_RED, LOW);
        digitalWrite(LED_BLU, HIGH);
        tone(BUZZER, freq);
        actual = 1;
        elapsedInterval = millis();
      }
    }
  }

  if ((millis() - lastDebounceTime4) >= debounceInterval) {
    if (reading4 != buttonState4) {
      buttonState4 = reading4;
      if (buttonState4 == HIGH) {
        bpm = bpm - 10; //bmp - 10
        if (bpm < 0) {
          bpm = 0;
        }
        interval = 60000 / bpm;
        freq = freqFirst;
        aktualizaceDispleje();
        digitalWrite(LED_RED, LOW);
        digitalWrite(LED_BLU, HIGH);
        tone(BUZZER, freq);
        actual = 1;
        elapsedInterval = millis();
      }
    }
  }

  if ((millis() - lastDebounceTime5) >= debounceInterval) {
    if (reading5 != buttonState5) {
      buttonState5 = reading5;
      if (buttonState5 == HIGH) {
        tick_case++;
        switch (tick_case) {
          case 0:
            rythm = 4; // 4/4 takt
            break;
          case 1:
            rythm = 5; // 5/4 takt
            break;
          case 2:
            rythm = 3; // 3/4 takt
            break;
          default:
            tick_case = 0;
            rythm = 4;
            break;
        }
        aktualizaceDispleje();
      }
    }
  }

  if (freq != 0 && bpm != 0) {
    if ((millis() - elapsedInterval) >= debounceInterval) { //50ms beep
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_BLU, LOW);
      noTone(BUZZER);
    }
    if ((millis() - elapsedInterval) >= interval) {
      actual++;
      if (actual > rythm) {
        actual = 1;
      }
      if (actual < rythm) {
        freq = freqFirst;
        digitalWrite(LED_RED, LOW);
        digitalWrite(LED_BLU, HIGH);
      }
      if (actual == rythm) {
        freq = freqFourths;
        digitalWrite(LED_RED, HIGH);
        digitalWrite(LED_BLU, LOW);
      }
      tone(BUZZER, freq);
      elapsedInterval = millis();
    }
  }

  lastButtonState1 = reading1;
  lastButtonState2 = reading2;
  lastButtonState3 = reading3;
  lastButtonState4 = reading4;
  lastButtonState5 = reading5;
}

AnChv37
Příspěvky: 3
Registrován: 27 kvě 2020, 22:02
Reputation: 0

Re: Digitální metronom

Příspěvek od AnChv37 » 29 kvě 2020, 12:45

Děkuji moc, metronom funguje skvěle
Jsem tvým velkým dlužníkem ;)

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Digitální metronom

Příspěvek od martinius96 » 29 kvě 2020, 12:55

Možno by bolo ešte vhodné z blokov stlačenia tlačidiel odstrániť

Kód: Vybrat vše

tone(BUZZER, freq);
a nechať to iba v hlavnej logike, kde sa počítajú beepy.
Lebo vždy pri stlačení tlačidla sa ozve aj buzzer, čo môže mať rušivý efekt pre poslucháča...

Avšak potom bude treba na prvý beep čakať do dosiahnutia daného času... (čo je dosť dlhá doba hlavne pri nižších BPM).
Som rád, že to funguje 8-)
Z tých taktov, a vizuálnej logiky, logiky LED-iek som vychádzal z: https://www.youtube.com/watch?v=WvCBQp2wdkw

AnChv37
Příspěvky: 3
Registrován: 27 kvě 2020, 22:02
Reputation: 0

Re: Digitální metronom

Příspěvek od AnChv37 » 02 čer 2020, 06:02

Ahoj, ještě mám jeden dotaz.
červená LED dioda mi pořád svítí a neblika, nevíš čím to je? 🤔 Děkuji moc

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Digitální metronom

Příspěvek od martinius96 » 07 čer 2020, 13:32

Ahoj, máš to zapojené správne? Testoval som to iba na TinkerCade v simulátore. Ale aj podľa programu by to malo blikať... Pretože vždy po beepe sa všetky diódy zhasnú... Mala by ti preto tiež zhasnúť..

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 11 hostů