Prosty metronom dla zestawu Pico Bricks.

Zestawy Pico Bricks są dostępne m. in. tu:
https://botland.com.pl/producent/582-pico-bricks

Zacznijmy od wersji z diodą LED: dioda pokazuje tempo, w czasie gdy przycisk pełni rolę TAP TEMPO i ustawiamy tempo w rytm wciskania tego przycisku.

Wyświetlacz SSD1306 pokazuje aktualny stan BPM tak, jak konsola.

W kolejnym kroku obsługę przycisku przeniesiemy do przerwań.

W pierwszej wersji bez dźwięku, tylko dioda:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <Wire.h>
#include <Adafruit_SSD1306.h>

#define LED 7
#define BUTTON 10

#define LED_TIME 80
#define START_TEMPO 120


Adafruit_SSD1306 display(128, 64, &Wire, -1);

void ssd1306_action()
{
  display.setTextSize(2); // czcionka. Zalecany zakres: 1-2
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("FX Metronome");
  display.display();
}



uint32_t nowMillis, //sysTick
        startLedTime,  //czas pomiaru poczatku oświecenia lub zgaszenia diody
     //   cycleTime, //czas całego cyklu diody
        prevButtonTime, //czas wciśnięcia przycisku do TapTempo
        BPMtime, //milisekundowy odpowiednik przerwy dla danego BPM
        pressDelay; //czas wcisniecia przycisku od jednego do drugiego TAP TEMPO

uint16_t tempo;        

#define SIGNAL_ON 1
#define SIGNAL_OFF 0
uint8_t ledState, //stan diody
        buttonState; //tan buttona




void setup() {
  Serial.begin(9600);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("Nie mozna znalezc wyswietlacza OLED, sprawdz podlaczenie!"));
    while(true);
  }

  display.display();
  delay(2000);
  display.clearDisplay();

  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT);

  ssd1306_action();//z loop tu

  //inne zmienne
  BPMtime = 500; //pol sekundy BMP = 120
  tempo = 120; //120BPM startowe

  //zapalam diode na poczatku i licze jej czas:
  startLedTime = millis();
  digitalWrite(LED, HIGH);
  ledState = SIGNAL_ON;
}



void loop() {
  nowMillis = millis();

  switch (ledState)
  { //maszyna stanow LED
    case SIGNAL_ON:
        if (nowMillis - startLedTime >=  LED_TIME ) //jeśli więcej niż 80ms to zgaś diodę
        {
          startLedTime = nowMillis;
          digitalWrite(LED, LOW);
          ledState = SIGNAL_OFF;
        }
    break;

    case SIGNAL_OFF:
      if (nowMillis - startLedTime >= BPMtime - LED_TIME )
      {
        startLedTime = nowMillis;
        digitalWrite(LED, HIGH);
        ledState = SIGNAL_ON;
      }
    break;
  }

  //TAP TEMPO na guziku
  if (digitalRead(BUTTON) && !buttonState)
  {
    pressDelay = nowMillis - prevButtonTime;
    if (pressDelay < 3000) //tap tempo działa tylko do 3 sek
    {
      BPMtime = pressDelay;
      tempo = 60000 / BPMtime;
    }
    buttonState = SIGNAL_ON;// znaznacz flagę - przycisk wciśnięty
    prevButtonTime = nowMillis;

    Serial.println(tempo);
    display.clearDisplay();
    display.setCursor(0,0);
    display.println(tempo);
    display.display();
  }

  if (!digitalRead(BUTTON) && buttonState)
  { //puszczono przycisk
    buttonState = SIGNAL_OFF;
  }
}

Tagged in:

, ,