
// Lógica do metrônomo
unsigned long agora = millis();
if (tocando) {
if (agora - ultimaBatida >= intervalo) {
ultimaBatida = agora;
// chame a função a ser realizada a cada atividade períodica ('tone' no caso do metrônomo)
}
}Do ponto de vista do desenvolvimento, essa versão se destaca pela facilidade de adaptação e experimentação. Parâmetros como o valor mínimo e máximo de BPM podem ser ajustados diretamente no código, permitindo que o mesmo projeto seja adaptado a diferentes contextos musicais, níveis técnicos ou objetivos de estudo. Essa característica torna o metrônomo analógico uma ferramenta flexível, tanto para uso musical quanto para fins didáticos, ao evidenciar a relação direta entre código, comportamento do sistema e resultado musical.
// ---------- codigo 1 - 3.1 metronomo analogico
int bpm = 60;
int bpmMaximo = 120;
int bpmMinimo = 30;
bool tocando = false;
void atualizarIntervalo() {
intervalo = 60000 / bpm;
}
void loop() {
// Leitura do potenciômetro e mapeamento para BPM
int leituraPot = analogRead(potPin);
bpm = map(leituraPot, 0, 1023, bpmMinimo, bpmMaximo);
atualizarIntervalo();
}// ---------- codigo 2 - 3.2 metronomo digital
void atualizarLCD() {
lcd.setCursor(0, 1);
lcd.print("BPM:");
if (bpm < 100) lcd.print(" ");
lcd.print(bpm);
lcd.print(tocando ? " PLAY " : " PAUSE");
}
// Dentro do LOOP:
// Ajuste de BPM
if (botaoCima) {
bpm += 10;
if (bpm > bpmMaximo) bpm = bpmMaximo;
atualizarLCD();
delay(150); //debounce
}
else if (botaoBaixo) {
bpm -= 10;
if (bpm < bpmMinimo) bpm = bpmMinimo;
atualizarLCD();
delay(150); //debounce
}
else if (botaoDireita) {
bpm += 1;
if (bpm > bpmMaximo) bpm = bpmMaximo;
atualizarLCD();
delay(150); //debounce
}
else if (botaoEsquerda) {
bpm -= 1;
if (bpm < bpmMinimo) bpm = bpmMinimo;
atualizarLCD();
delay(150); //debounce
}
// Play / Pause
if (botaoSelect && !ultimoEstadoSelect) {
tocando = !tocando;
atualizarLCD();
if (!tocando) {
digitalWrite(LEDdisplay, HIGH); // no pause, LED fica aceso
}
delay(150); //debounce
}
// Play / Pause
if (botaoSelect && !ultimoEstadoSelect) {
tocando = !tocando;
atualizarLCD();
}Assim como na versão analógica, o metrônomo digital fornece feedback sonoro por meio de um buzzer e também oferece uma referência visual do pulso. Nesta implementação, a indicação visual é realizada utilizando o próprio LED integrado ao shield de display e botões, dispensando componentes externos adicionais. Esse LED é sincronizado com cada batida do metrônomo, funcionando como um indicador visual direto do pulso para o músico.

// ---------- codigo 3 - 3.3 metronomo servo
// Config do Servo Motor
#include <Servo.h>
const int servo = 9;
Servo myservo;
int direita = 100;
int esquerda = 80;
bool servoNaDireita = false;
void servo_direita(){
myservo.write(direita);
}
void servo_esquerda(){
myservo.write(esquerda);
}
// Dentro do LOOP:
// Acionamento por switch
bool estadoPlayPause = digitalRead(botaoPlayPause);
if (estadoPlayPause == LOW) {
if (agora - ultimaBatida >= intervalo) {
ultimaBatida = agora;
tone(buzzerPin, 1000, 100); // bip
// Movimento tipo pêndulo
if (servoNaDireita) {
servo_esquerda();
servoNaDireita = false;
}
else {
servo_direita();
servoNaDireita = true;
}
}
}Tecnicamente, essa adaptação exige modificações pontuais no código. A função responsável por acender o LED passa a controlar o movimento do servo, enquanto a lógica de acionamento por botão é substituída por uma chave do tipo switch. A estrutura de temporização baseada em millis() — núcleo do metrônomo — permanece inalterada, reforçando a ideia de que a lógica musical e temporal é independente da interface física escolhida.
Controle Analógico

Controle Digital

Controle Analógico + Movimento pendular

Controle analógico:
// Definição de Pinos
const int buzzerPin = 11; // buzzer passivo
const int botaoPlayPause = 10; // botão
const int potPin = A0; // potenciômetro
const int ledPin = 12; // LED + resistor
// Configurações do Metrônomo
int bpm = 60;
int bpmMaximo = 120;
int bpmMinimo = 30;
bool tocando = false;
unsigned long ultimaBatida = 0;
unsigned long intervalo = 60000 / 60;
// Controle do LED
bool ledAtivo = false;
unsigned long tempoLed = 0;
const unsigned long duracaoLed = 50;
// Atualização do Intervalo
void atualizarIntervalo() {
intervalo = 60000 / bpm;
}
// Controle de Play e Pause
bool ultimoEstadoPlayPause = HIGH;
// ----- SETUP -----
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(botaoPlayPause, INPUT_PULLUP);
pinMode(potPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // LED começa apagado
}
// ------ LOOP -----
void loop() {
// Leitura do potenciômetro e mapeamento para BPM
int leituraPot = analogRead(potPin);
bpm = map(leituraPot, 0, 1023, bpmMinimo, bpmMaximo);
atualizarIntervalo();
// Botão PLAY / PAUSE
bool estadoPlayPause = digitalRead(botaoPlayPause);
if (estadoPlayPause == LOW && ultimoEstadoPlayPause == HIGH) {
tocando = !tocando;
delay(300); // debounce simples
}
ultimoEstadoPlayPause = estadoPlayPause;
// Lógica do metrônomo
unsigned long agora = millis();
if (tocando) {
if (agora - ultimaBatida >= intervalo) {
ultimaBatida = agora;
tone(buzzerPin, 1000, 100); // bip de 100 ms
// LED pisca na batida
digitalWrite(ledPin, HIGH);
ledAtivo = true;
tempoLed = agora;
}
}
// Desliga o LED após o pulso
if (ledAtivo && (agora - tempoLed >= duracaoLed)) {
digitalWrite(ledPin, LOW);
ledAtivo = false;
}
}
// Configurações do Display LCD Shield 16x2 com Teclado para Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
const int LEDdisplay = 10;
const int botaoAnalogico = A0;
// Definição de Pinos
const int buzzerPin = 3; // Buzzer passivo
// Configurações do Metrônomo
int bpm = 60;
int bpmMaximo = 120;
int bpmMinimo = 30;
bool tocando = false;
unsigned long ultimaBatida = 0;
unsigned long intervalo = 60000 / 60;
// Controle do LED
bool ledApagadoNaBatida = false;
unsigned long tempoLed = 0;
// Atualização do LCD
void atualizarLCD() {
lcd.setCursor(0, 1);
lcd.print("BPM:");
if (bpm < 100) lcd.print(" ");
lcd.print(bpm);
lcd.print(tocando ? " PLAY " : " PAUSE");
}
// Controle de Play e Pause
bool ultimoEstadoSelect = HIGH;
// ----- SETUP -----
void setup() {
lcd.begin(16, 2);
pinMode(buzzerPin, OUTPUT);
pinMode(botaoAnalogico, INPUT);
pinMode(LEDdisplay, OUTPUT);
digitalWrite(LEDdisplay, HIGH); // LED começa aceso
lcd.setCursor(0, 0);
lcd.print("Metronomo");
lcd.setCursor(0, 1);
lcd.print("BPM:");
lcd.print(bpm);
lcd.print(" PAUSE");
}
// ------ LOOP -----
void loop() {
// Leitura dos botões
int leitura = analogRead(botaoAnalogico);
bool botaoCima = (leitura >= 100 && leitura < 200);
bool botaoBaixo = (leitura >= 200 && leitura < 400);
bool botaoDireita = (leitura >= 0 && leitura < 100);
bool botaoEsquerda = (leitura >= 400 && leitura < 600);
bool botaoSelect = (leitura >= 600 && leitura < 800);
// Ajuste de BPM
if (botaoCima) {
bpm += 10;
if (bpm > bpmMaximo) bpm = bpmMaximo;
atualizarLCD();
delay(150); //debounce
}
else if (botaoBaixo) {
bpm -= 10;
if (bpm < bpmMinimo) bpm = bpmMinimo;
atualizarLCD();
delay(150); //debounce
}
else if (botaoDireita) {
bpm += 1;
if (bpm > bpmMaximo) bpm = bpmMaximo;
atualizarLCD();
delay(150); //debounce
}
else if (botaoEsquerda) {
bpm -= 1;
if (bpm < bpmMinimo) bpm = bpmMinimo;
atualizarLCD();
delay(150); //debounce
}
// Play / Pause
if (botaoSelect && !ultimoEstadoSelect) {
tocando = !tocando;
atualizarLCD();
if (!tocando) {
digitalWrite(LEDdisplay, HIGH); // no pause, LED fica aceso
}
delay(150); //debounce
}
ultimoEstadoSelect = botaoSelect;
// Lógica do metrônomo
unsigned long agora = millis();
intervalo = 60000 / bpm;
if (tocando) {
if (agora - ultimaBatida >= intervalo) {
ultimaBatida = agora;
tone(buzzerPin, 1000, 100);
// LED apaga na batida
digitalWrite(LEDdisplay, LOW);
ledApagadoNaBatida = true;
tempoLed = agora;
}
}
// LED acende após a batida
if (ledApagadoNaBatida && (agora - tempoLed >= 100)) {
digitalWrite(LEDdisplay, HIGH);
ledApagadoNaBatida = false;
}
}
Controle Analógico + Pêndulo por servo motor
// Config do Servo Motor
#include <Servo.h>
const int servo = 9;
Servo myservo;
int direita = 100;
int esquerda = 80;
bool servoNaDireita = false;
void servo_direita(){
myservo.write(direita);
}
void servo_esquerda(){
myservo.write(esquerda);
}
// Definição de Pinos
const int buzzerPin = 12; // buzzer passivo
const int botaoPlayPause = 10; // switch
const int potPin = A0; // potenciômetro
// Config do Metrônomo
int bpm = 60;
int bpmMaximo = 120;
int bpmMinimo = 30;
bool tocando = false;
unsigned long ultimaBatida = 0;
unsigned long intervalo = 60000 / 60;
// --------- SETUP ---------
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(botaoPlayPause, INPUT_PULLUP);
pinMode(potPin, INPUT);
myservo.attach(servo);
}
// --------- LOOP ---------
void loop() {
// Leitura do potenciômetro e mapeamento para BPM
int leituraPot = analogRead(potPin);
bpm = map(leituraPot, 0, 1023, bpmMinimo, bpmMaximo);
intervalo = 60000 / bpm;;
unsigned long agora = millis();
// Acionamento por switch
bool estadoPlayPause = digitalRead(botaoPlayPause);
if (estadoPlayPause == LOW) {
if (agora - ultimaBatida >= intervalo) {
ultimaBatida = agora;
tone(buzzerPin, 1000, 100); // bip
// Movimento tipo pêndulo
if (servoNaDireita) {
servo_esquerda();
servoNaDireita = false;
}
else {
servo_direita();
servoNaDireita = true;
}
}
}
}
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!