Buzzer
Músicas monofônicas^1 são aquelas que possuem apenas uma única nota tocada por vez, como indicado na partitura a seguir:
ref: Wikipédia
A música monofônica tem o som como a seguir:
Esse tipo de música foi muito utilizado nos primeiros videogames, quando a sintetização de músicas ainda estava no começo. Veja como era feito nos Nintendos, onde já era possível gerar mais de um tom por vez:
Buzzer
Para gerarmos o som, é necessário termos algum dispositivo capaz de movimentar o ar. O buzzer é um dispositivo simples que, a partir de uma bobina (controlada por um terminal), movimenta um disco que, por sua vez, movimenta o ar. Os buzzers podem ser de duas categorias (piezoelétricos):
- Ativo: basta energizar o terminal e o dispositivo vibra automaticamente em uma determinada frequência, muito usado para alarmes.
- Passivo: Um circuito externo (ou microcontrolador) deve gerar a frequência de vibração, sendo usado para gerar som.
Buzzers são diferentes de alto-falantes^2 em vários aspectos (mecânicos, eletromecânicos): não necessitam de tensão negativa; possuem um espectro de operação menor; baixa resistência; baixa potência, etc.
A conexão do buzzer com um microcontrolador se dá por dois pinos: um conectado ao terra (GND) e outro conectado a um pino que o microcontrolador possui controle, conforme ilustração a seguir:
Gerando som
Podemos fazer com que o buzzer oscile em uma determinada frequência. Para isso, basta gerar um sinal de onda quadrada no terminal positivo do dispositivo, o que fará com que o piezo vibre na mesma frequência, gerando o tom desejado.
Notas
As notas musicais são definidas pela frequência principal que emitem: um Dó-4 é definido por 262 Hz, um Lá-4 por 440 Hz e assim por diante (o 4 se refere ao meio do piano). Além da frequência principal, cada instrumento musical emite outras frequências que compõem o som, gerando um timbre único para cada instrumento.
Usaremos a notação americana para as notas:
Dó | Ré | Mi | Fá | Sol | Lá | Sí |
---|---|---|---|---|---|---|
C | D | E | F | G | A | B |
Frequências
Lembre-se que uma onda quadrada pode ser decomposta em infinitas senoides pela transformada de Fourier.
Sendo a componente principal (de maior energia) centrada na frequência da onda quadrada. Portanto, o som que iremos escutar será composto da frequência principal mais as harmônicas.
https://mathworld.wolfram.com/images/eps-gif/FourierSeriesSquareWave_800.gif
Existem diversas maneiras de gerar uma onda quadrada em um pino do microcontrolador. A que estamos sugerindo aqui não envolve nenhum periférico específico do microcontrolador, logo, faremos tudo por código.
Gerando a frequência
Para gerar uma onda quadrada da nota Dó (261,63 Hz), precisamos calcular seu período e definir o tempo em que a mesma ficará em nível lógico alto e baixo (0 e 1):
T = 1 ÷ 261,63
T = 0,0038 s
Na Pico W, programando em C, geralmente utilizamos a função sleep_ms para gerar atraso no código. Precisamos então converter esse valor para milissegundos (dividir por 1000) e também dividir por 2, gerando os respectivos atrasos nos níveis lógicos:
delay = (0,0038 x 1000) ÷ 2
delay ≃ 1,9 ms
while(1){
gpio_put(PIN_BUZZER, 1);
sleep_ms(1.9);
gpio_put(PIN_BUZZER, 0);
sleep_ms(1,9);
}
sleep_us
Como podemos observar, utilizando sleep_ms temos um limite de frequência das notas musicais que podemos alcançar, por dois motivos:
- Essa função é do tipo int, ou seja, dependendo do valor do delay, a parte fracionária será perdida, mantendo somente a parte inteira;
- Para frequências acima de 506 Hz, o delay utilizado no sleep_ms começa a receber valores abaixo de 1, fazendo com que seja necessário utilizar a função sleep_us no lugar da sleep_ms.
TIP
OBS: Não se esqueça de alterar a escala de ms para us: 0,000001s = 0,001ms = 1us
Para o mesmo exemplo com a nota Dó (261,63 Hz), utilizando sleep_us, ficaria:
while(1){
gpio_put(PIN_BUZZER, 1);
sleep_us(1900);
gpio_put(PIN_BUZZER, 0);
sleep_us(1900);
}
Controlando a duração
Agora que sabemos como gerar a frequência, precisamos entender como controlar a duração da mesma.
Por exemplo, para tocar a nota Dó (261,63 Hz) por 2 segundos (2.000.000 us), sabendo que o período total é de 3800 us, precisamos definir quantas vezes é preciso repetir esse ciclo. Basta dividir o tempo desejado pela duração de cada ciclo:
2.000.000 ÷ 3800 ≃ 526 vezes
Ou seja, precisamos repetir esse período 526 vezes, logo:
for(int i = 0; i < 526 ; i++){
gpio_put(PIN_BUZZER, 1);
sleep_us(1900);
gpio_put(PIN_BUZZER, 0);
sleep_us(1900);
}
Música
Por anos fiz aula de sax alto e meu professor dizia que, para começar a tocar uma música, bastava: tocar a nota certa no momento certo e não tocar quando não for para tocar
. Para quem tem prática é fácil, mas para mim não era. Trouxe este assunto para explicar um pouco como iremos reproduzir uma música. Cada música será formada por notas (frequências), pela duração da nota e por um silêncio entre notas (que também tem duração). Toda essa informação está presente na partitura.
Portanto, para reproduzirmos uma música, teremos que, para cada intervalo de tempo:
- Reproduzir uma nota (gerar a frequência da nota no pino do buzzer) ou não tocar nada (pausa)
- Manter a nota/pausa pelo tempo determinado
- Ir para o próximo intervalo de tempo