Geração de acorde

Desculpa... não expliquei.

Estas macros servem apenas para alterar o estado dum pino. Os timers é algo completamente diferente. No entanto, com estas macros, alterar o estado do pino é muito mais rápido que usar o digitalWrite(). O ponto fraco é que tens de saber usar e configurar os portos e não podes usar os números do Arduino.

Ahh, podes usar isto em variáveis também.

Interessante, sou iniciante ainda no Arduino, você teria algum tutorial sobre isso?
Quando você diz alterar o estado seria a forma com o pino troca a informação?

muda de estado = muda de high para low ou de low para high.

Opa bubulindo, agora eu entendi, mas ainda acho que estou longe de chegar neste ponto, ainda.
Minha dificuldade maior está sendo gerar a onda no formato da imagem que disponibilizei,

Essa imagem é o resultado da somatória das ondas quadradas que formam um acorde Dó maior.
basicamente teria que simular isso no Arduino para gerar um acorde, já que ele trabalha com ondas quadradas.

Nos meus experimentos antigos eu estava tentando usar ondas senoidais =o)

neuron_upheaval - Confesso que eu entendo tanto de física e matemática quanto você de música então acho que empatamos. As fórmulas que postou não chegaram perto do resultado que preciso, gerar um acorde, mas mesmo assim obrigado pela ajuda.
Sobre o Omega, eu não sabia que era o pulso, pensei que você tivesse declarado a variável assim.

Ok...

Assim de repente, o que precisas de entender é:

PWM não vai gerar som. Ou melhor, vai, mas não o som que tu pretendes. O PWM, no entanto, serve para gerar tensões de diferentes níveis, que por sua vez indicam diferentes sons. Se reparares, o PWM é uma onda quadrada, o teu instrumento musical tem senóides (ou sinusóides no dialecto de Portugal).

A série de Fourier indica que a senóide é a onda fundamental, enquanto que qualquer onda quadrada é a soma de várias senóides, logo uma onda quadrada já tem lá várias frequências que tu não queres ouvir (se é que consegues por causa da frequência).

Logo o primeiro passo é gerar um PWM com a maior frequência que puderes, e depois gerares um código que gera uma senóide com esse PWM.

Podes ver isso com a fórmula que o neuron deixou " A sen (2 pi f t)".
Esquece o A, porque neste mundinho não vamos precisar de amplitude. Então, de x em x tempo (t), calculas com aquela fórmula qual o valor que vais meter no circuito de PWM.

Tendo isto, e indo de volta à matemática, tens de ver como calcular (nota, usa inteiros, de preferência pequenos tipo unsigned char) a soma das sinusóides que geram os acordes que pretendes.

Fez algum sentido?

Neste momento, a tua dúvida é "Para que serve então o PWM??".

Ok, o PWM é apenas a forma que os dispositivos digitais têm de criar sinais analógicos (como aqueles que queres ouvir), logo é apenas isso que ele vai estar a fazer... a aproximar a saída digital a uma analógica.

Outra maneira, talvez mais simples, seria usando um amplificador (não no sentido que conheces a palavra amplificador) mas numa montagem somadora. Assim poderias gerar duas senóides dentro do arduino com PWM e enviar isso para o amplificador que somaria as duas ondas.

Não tenho mesmo tempo para me dedicar a isto, o que é uma pena, mas esta é a melhor explicacão que consigo dar agora.

http://elektron.no.sapo.pt/ampop1.htm
http://www.ufrgs.br/eng04030/aulas/teoria/cap_15/circampo.htm
http://www.newtoncbraga.com.br/index.php/matematica-para-eletronica/636-somador-com-amplificador-operacional-m023.html

Nota que o amp-op pode criar distorcões no som que geras... tudo depende da resposta em frequência do mesmo. :wink:

Edit:

Aqui tem outra explicacão.

http://www.ecircuitcenter.com/circuits/opsum/opsum.htm

Bubulindo - Eu consegui sim entender como funciona o PWM e como ele é utilizado para geração de som.
Sei que o Arduino fica ligando e desligando a porta 440 vezes por segundo para gerar uma nota Lá.

Sobre as ondas quadradas e senoidais eu tenho que discordar. Você pode gerar um Lá utilizando uma onda quadrada, senoidal, serra ou quadrada sem graduação, você pode testar isso através do Audacity como eu fiz. A diferença será o tibre da nota, mas, o Lá para um músico com ouvido absoluto (Ouvido absoluto – Wikipédia, a enciclopédia livre) será sempre um Lá, seja ele gerado por uma flauta, um computador ou qualquer coisa. Veja e ouça abaixo:

Lá Senoidal

http://www.flxsys.com.br/_gravar/upload/la_senoidal.mp3 MP3 lá onda senoidal

Lá Quadrado

http://www.flxsys.com.br/_gravar/upload/la_quadrada.mp3 MP3 lá onda quadrada

A grande diferença no som dos instrumentos musicais se dá justamente pela diferença no formato da onda, tanto que em teclados para você gerar sons de instrumentos de sopro são utilizadas ondas quadradas e não senoidais, lendo alguns textos no playground sobre a geração de MIDI li isso. Se ver a documentação sobre PWM e som do Arduino, irá ver que o Arduino sem nada mais só gera ondas quadradas e em meu projeto eu quero usar apenas o Arduino, sem quaquer outro componente.

Sobre as Series de Fourier, eu li e entendi que ela pode ser usada para achar as harmônicas, e estas harmonias formam as progressões harmônicas que determinaram a criação dos acordes. Essas sequencias harmônicas (em musica) são a base para a formação das escalas maiores(harmônicas). Contudo, Fourier também descobriu uma forma de somar as frequências, sejam elas senoidais ou quadradas. O texto abaixo explica certinho fazer a somatória de ondas senoidais e quadradas, pois o método de calculo é diferente:

http://www.seara.ufc.br/tintim/matematica/fourier/fourier2.htm

Nosso colega neuron_upheaval, não está nem um pouco errado em sua forma de pensar e no que postou, mas como o Arduino só gera ondas quadradas, a formula não se aplica, já que é a somatória de ondas senoidais, eu já havia tentado este método e notei que não funciona.

Abaixo segue um exemplo prático da somatória de apenas 2 frequências (Dó e Mi) para formação de um Power Chord Dó, seguem as imagens e sons gerados com o Audacity para exemplificar melhor o meu objetivo e a minha linha de raciocínio atual:

Ondas quadradas de Dó e Mi, visualmente vemos que no Arduino o comportamento seria ligar e desligar a porta 263 vezes por segundo para gerar uma frequência Dó e 329 vezes por segundo para gerar um Mi:

Agora vamos juntar as duas frequências, teoricamente o programa aplica a equação de Fourier para calcular o novo formato de onda.

Resultado da Somatória de ondas:

Som resultante da somatória das ondas quadradas.
http://www.flxsys.com.br/_gravar/upload/power_do.mp3

Como pode observar o Power Chord Dó é um som gerado através de uma onda quadrada, para um músico independente do instrumento será um bicorde de Dó Maior, se quiser poso postar uma combinação com ondas senoidais para ver a diferença visual e auditiva.

Acredito que se eu conseguir fazer a porta PWM se comportar como a imagem da somatória eu conseguirei atingir meu objetivo, resta saber se o Arduino é capas de fazer isso.

eu já tinha visto esses gráficos e fico sempre com a mesma duvida...

o que significa o estado do meio? tu tens pwm on, pwm off e a linha para no meio... como defines isso? e como adaptas isso a um sistema que só tem dois estados?

mas faz assim, encontra um denominador comum nas notas todas que queres, tipo 100 ms ou 20 ms. divide o periodo da onda por esse valor.
cria uma interrupção temporizada com os tais ms, e vai gerando as notas e o resultado assim.

eu meto já um exemplo.

ISR(timer1 ou 2) {


}

//também podes fazer

#define DO 0
#define RE 1
#define MI 2
//...


const unsigned char periodos [] = {10,20,30,40,50,60,70, 80};//na realidade, meios períodos... isto terias de fazer a matemática. É só um exemplo. 
unsigned char onda[8];
unsigned char saidas = 0;
unsigned int tempo = 0;

ISR(timer) { //imaginemos de 10 em 10 ms
unsigned char i;
tempo++; //incrementa o tempo

for (i=0; i<=7; i++ ){ //para as oito notas
    if (tempo % periodos[i] == 0) {
    togBit(saidas, i); // depois o bit i da variavel saidas corresponde à nota com indice i    tens de usar aquelas macros uqe postei para isto. 
    }
}
//isto vai-te dar o estado das várias notas actualizado de x em x tempo (depende de como activares o timer)

loop() {

//imagina que queres do + mi

if ( testBit(saidas, DO) + testBit(saidas, MI))  //podes e deves trocar o mais por || ("ou" lógico, mas fica mais simples de compreender assim talvez. )
    SetBit (PORTO, PINO_DO_PWM);
else
    ClrBit(PORTO, PINO_DO_PWM);
}

}

O problema é que 1/440 dá uns 2 milissegundos... e o arduino talvez não seja tão potente assim. É caso de ver se consegues gerar uma nota com este método.

Bubulindo - Excelente pergunta. "o que significa o estado do meio? tu tens pwm on, pwm off e a linha para no meio... como defines isso? e como adaptas isso a um sistema que só tem dois estados? ", acho que eu sei te explicar o que ocorre.

A subida e descida da linha simbolizam a amplitude, que nós não temos controle no Arduino com pulsos PWM, correto? Mas a linha do meio significa que a Amplitude é 0. A linha do meio então pode ser simulada com PWM off, já que não tem amplitude e não gera som, um problema fácil de solucionar.

Mas, se notar no gráfico de somatória de 3 notas (outro post), irá ver que aparecem degraus acima da linha do meio, teoricamente deve haver uma variação na amplitude para obter o efeito desejado. Neste caso além de gerar os pulsos eu acredito que deva ser controlada a voltagem para simular um aumento e a diminuição da amplitude do pulso, a grosso modo o volume do som, o que acredito não ser possível no Arduino utilizando apenas o hardware da placa.

Pelo que notei a grande diferença da onda senoidal é que para atingir o estado On/Off do PWM a amplitude é diminuída gradualmente até o ponto Off e retorna da mesma forma, isso produz um som mais limpo, como um "tuuuuuuuu" e não os "trutrutrutrutru" de uma onda quadrada.

"O problema é que 1/440 dá uns 2 milissegundos... e o arduino talvez não seja tão potente assim. É caso de ver se consegues gerar uma nota com este método. "

Sobre o texto acima é justamente o que eu imaginei, não sei se o hardware é tão rápido para conseguir executar o pulso, pois ele seria extremamente rápido. Mas o outro desafio é alterar a voltagem do pulso e não liberar sempre os 5V.

Mais uma vez agradeço a ajuda, irei estudar o fonte e fazer uns testes com seu exemplo na semana que vem, ai te conto os resultado.

Desculpe as minhas limitações sobre o assunto pois eu sou autodidata e nunca frequentei aulas sobre o assunto, o que consegui entender até agora foi apenas com o estudo de 2 semanas, se tiver muito fora da realidade uma hora a minha ficha cai com as dicas =o)

spiderpoison:
Bubulindo - Excelente pergunta. "o que significa o estado do meio? tu tens pwm on, pwm off e a linha para no meio... como defines isso? e como adaptas isso a um sistema que só tem dois estados? ", acho que eu sei te explicar o que ocorre.

A subida e descida da linha simbolizam a amplitude, que nós não temos controle no Arduino com pulsos PWM, correto? Mas a linha do meio significa que a Amplitude é 0. A linha do meio então pode ser simulada com PWM off, já que não tem amplitude e não gera som, um problema fácil de solucionar.

Mas, se notar no gráfico de somatória de 3 notas (outro post), irá ver que aparecem degraus acima da linha do meio, teoricamente deve haver uma variação na amplitude para obter o efeito desejado. Neste caso além de gerar os pulsos eu acredito que deva ser controlada a voltagem para simular um aumento e a diminuição da amplitude do pulso, a grosso modo o volume do som, o que acredito não ser possível no Arduino utilizando apenas o hardware da placa.

A amplitude é precisamente o que tu controlas com o PWM. Variando o PWM consegues amplitudes entre 0 e 5 (a tua linha do meio seria 2,5V). Mas depois precisarias de mais lógica para criar a tua onda quadrada ou sinusóidal (como expliquei no post atrás). Se não quiseres controlar amplitude, podes usar o código que postei lá atrás.

Estás a compreender agora o PWM? A sua principal utilizacão é normalmente simular amplitudes diferentes usando apenas sinais digitais.

spiderpoison:
Pelo que notei a grande diferença da onda senoidal é que para atingir o estado On/Off do PWM a amplitude é diminuída gradualmente até o ponto Off e retorna da mesma forma, isso produz um som mais limpo, como um "tuuuuuuuu" e não os "trutrutrutrutru" de uma onda quadrada.

"O problema é que 1/440 dá uns 2 milissegundos... e o arduino talvez não seja tão potente assim. É caso de ver se consegues gerar uma nota com este método. "

Sobre o texto acima é justamente o que eu imaginei, não sei se o hardware é tão rápido para conseguir executar o pulso, pois ele seria extremamente rápido. Mas o outro desafio é alterar a voltagem do pulso e não liberar sempre os 5V.

O microcontrolador corre a 16MHz... isso dá 6,25 * 10^-8. Eu acho que o chip do Arduino consegue cumprir os 2ms, mas o código não deve usar bibliotecas do Arduino (porque são feitas para o pior caso e normalmente duplicam o tempo de ciclo) e tem de ser feito com cuidado... usar registos se possível para algumas tarefas, etc, etc...

Poder variar a amplitude, por exemplo, iria ser um programa complexo de fazer devido a alguma da matemática e ciclos envolvidos... claro que com algumas práticas de programacão a coisa chegava lá.

Qual é o interesse em fazer isto?

Bubulindo - Essa equação complicada que define a amplitude em relação a linha do tempo é justamente a Série de Fourier, que precisa ser adaptada para realizar a somatória das ondas quadradas, através dela em momento X e Y da onda. Mas o processo para portar isso para o Arduino é justamente o que falou, uma matemática extremamente complicada, ao menos para mim. Acredito que eu terei que estudar muito mais tempo para dominar o assunto e fazer o programa sem usar as bibliotecas do Arduino.

Bom, vamos a utilidade do projeto. De inicio digo que sinto uma vontade incontrolável de aprender, então, eu gosto dos desafios mais difíceis que eu posso encontrar, e notei que gerar um acorde só com o arduino seria "o desafio". mas eu também sou músico e a um tempo montei um programa para treinar o ouvido e fazer com que as pessoas desenvolvam um ouvido absoluto, só que este programa gera apenas notas.

A ideia é um programa que treine tanto a capacidade dos músicos aprenderem a reconhecer notas e acordes. Programas assim já existem aos montes para celular e computador, mas, o custo para músicos que ganham uma miséria aqui no Brasil são muito altos.

Com o Arduino eu consegui reduzir o custo do meu projeto a uns 10 dólares, sendo assim qualquer músico interessado pode ter um.

Abaixando o custo eu também pretendo implantar o projeto em algumas escolas de música que trabalham com pessoas carentes aqui na minha cidade, por isso o custo é extremamente importante.

spiderpoison:
Bubulindo - Essa equação complicada que define a amplitude em relação a linha do tempo é justamente a Série de Fourier, que precisa ser adaptada para realizar a somatória das ondas quadradas, através dela em momento X e Y da onda. Mas o processo para portar isso para o Arduino é justamente o que falou, uma matemática extremamente complicada, ao menos para mim. Acredito que eu terei que estudar muito mais tempo para dominar o assunto e fazer o programa sem usar as bibliotecas do Arduino.

Não. Acho que entendeste mal. A série de Fourier explica como decompor uma onda em ondas sinusóidais que, quando somadas, originam a onda original com maior ou menor qualidade mediante o número de harmónicos que somares.
Isto é tudo muito bonito, mas o que te interessa aqui é o pormenor de somar as ondas.
E para isso não precisas de muita matemática. :wink:

Eu, como disse atrás, não tenho mesmo tempo para isto, mas vou tentar arranjar um exemplo nos meus ficheiros lá em casa que use temporizacões. Ainda não tenho a certeza se não conseguirás criar isto com o motor de PWM no Arduino... mas acho que sim. Quando puder vejo e meto aqui.

spiderpoison:
Bom, vamos a utilidade do projeto. De inicio digo que sinto uma vontade incontrolável de aprender, então, eu gosto dos desafios mais difíceis que eu posso encontrar, e notei que gerar um acorde só com o arduino seria "o desafio". mas eu também sou músico e a um tempo montei um programa para treinar o ouvido e fazer com que as pessoas desenvolvam um ouvido absoluto, só que este programa gera apenas notas.

Isso fazes bem. Aprender é útil, quanto mais não seja para falar em festas. :slight_smile: lol

spiderpoison:
A ideia é um programa que treine tanto a capacidade dos músicos aprenderem a reconhecer notas e acordes. Programas assim já existem aos montes para celular e computador, mas, o custo para músicos que ganham uma miséria aqui no Brasil são muito altos.

Se vocês mandassem a música boa que têm para fora do Brasil, talvez não fosse tão mau assim. :wink:
Estou a falar porque em Portugal parece que ninguém conhece os bons músicos Brasileiros. Só os que não conseguem vender no Brasil é que vão para lá. :frowning:

spiderpoison:
Bubulindo - Eu consegui sim entender como funciona o PWM e como ele é utilizado para geração de som.
Sei que o Arduino fica ligando e desligando a porta 440 vezes por segundo para gerar uma nota Lá.

Não; o Arduino não fica ligando e desligando a porta PWM 440 vezes por segundo; a frequência do PWM está próxima aos 500 Hz:

In other words, with Arduino's PWM frequency at about 500Hz, the green lines would measure 2 milliseconds each. A call to analogWrite() is on a scale of 0 - 255, such that analogWrite(255) requests a 100% duty cycle (always on), and analogWrite(127) is a 50% duty cycle (on half the time) for example.

O PWM não serve para gerar os pulsos na frequência que você quer; ele gera, isso sim, um sinal na amplitude que você deseja. A frequência do PWM é fixa, e o que muda é a largura do pulso. Por isso que é chamada de PWM: Pulse Width Modulation, modulação por largura de pulso.

Se você quer que o pulso tenha uma certa frequência, você tem que usar, da forma que bubulindo explicou, um timer e uma interrupção do microcontrolador, caso queira que o seu programa funcione em modo assíncrono, ou usar a forma que eu indiquei no post #9, que é síncrona, isto é, não usa interrupções para fabricar os pulsos.

neuron_upheaval:
Se você quer que o pulso tenha uma certa frequência, você tem que usar, da forma que bubulindo explicou, um timer e uma interrupção do microcontrolador, caso queira que o seu programa funcione em modo assíncrono, ou usar a forma que eu indiquei no post #9, que é síncrona, isto é, não usa interrupções para fabricar os pulsos.

Desculpa a correccão... mas o Arduino pode variar a frequência do PWM. A libraria base, não... mas com um pouco de conhecimento de microcontroladores é fácil de o fazer. Vê o modo CTC. :wink:

Ainda não desisti da ideia de gerar um acorde com o Arduino, consegui montar um modelo de como deve ser o comportamento da onda, falta ver como portar isso para o Arduino.

http://www.flxsys.com.br/curva.php

Toma la. Aqui ja esta tudo feito.
Se quiseres algo mais complicado devias olhar as tecnicas em synths...
Podes tb replicar as frequencias atraves de on/off os pins, mas talvez seja melhor usares AVR C code, ja que precisas de mexer no miolo do codigo que vai contra o que esta nos core

Sei que faz tempo deste post, mas espero ajudar.
O arduino é tudo de bom, mas tb traz um mal. Muitos de seus adeptos não são programadores e ou não conhecem eletronica.Não conseguem entender o seu hardware e software.
Todo processador trabalha os códigos em fila, ou seja sequencia.
Mas isto é contornavel, se vc precisa que mais de uma coisa acontece ou processe ao mesmo tempo, no software vc é obrigado a programar Threads para que estes eventos trabalhem em paralelo.
Sou programador Senior em Delphi e utilizo muito Thread em Delphi.
Como se faz isso? Tb não sei!
Em C, por não conhecer a linguagem a fundo, ainda estou aprendendo.
Achei uma biblioteca do Ivan Seidel, resolveu meu problema em 50% mas ainda não está como quero.
Espero ter ajudado.
Abraços.

Threads é uma maneira de resolver problemas... Mas não este problema.

Amigos,
Gostaria usar o arduíno para identificar uma nota musical pela sua frequência?
Poderiam me ajudar? Que sensor de som seria possível realizar este projeto?