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; } } |