Índice:

Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC: 9 etapas
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC: 9 etapas

Vídeo: Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC: 9 etapas

Vídeo: Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC: 9 etapas
Vídeo: WTV020-sd COM PIC: TOCANDO ARQUIVOS DE ÁUDIO | Curso PIC 2024, Julho
Anonim
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC
Reproduzindo arquivos de áudio e som (Wav) com um Arduino e um DAC

Reproduza o arquivo wav de áudio do seu cartão Audino SD. Este Instructable mostrará como um arquivo wav em seu SdCard pode ser reproduzido através de um circuito simples para um alto-falante.

O arquivo wav deve ser mono de 8 bits. Não tive problemas para reproduzir arquivos de 44 KHz.

Embora não seja de alta fidelidade, a qualidade do som é muito satisfatória.

O monitor serial é usado para selecionar o arquivo. Os arquivos devem estar em uma pasta chamada adlog.

Este instrutivo segue de um projeto anterior onde salvei gravações wav no SdCard:

O circuito usa um conversor digital para analógico (DAC) barato de 8 bits e um amplificador de áudio de chip único.

As principais seções para configurar interrupções foram retiradas do excelente artigo de Amanda Ghassaei:

Etapa 1: Requisitos

Requisitos
Requisitos
Requisitos
Requisitos

Arduino- Eu uso o Mega, porém não há razão para que o Uno não funcione.

Leitor SdCard - o programa está configurado para: MicroSD Breakout Board Regulated with Logic Conversion V2

Veja este instrutível para detalhes de configuração do SdCard:

DAC0832 LCN - um excelente conversor digital para analógico de 8 bits - Algumas libras.

LM386 N-1 Op amp - barato como chips

Soquete de chip de 20 vias

Soquete de chip de 8 vias

Fonte de alimentação de 9 volts - uma bateria serve.

Referência de tensão LM336 2,5 V

Capacitor 10uF * 3 (qualquer voltagem superior a 9V)

Resistor de 10 ohm

Capacitor 50nF- (ou em algum lugar perto-47nF, 56nf, 68nf- servirá)

Capacitor 220uF

Alto-falante de 64 ohms

Potenciômetro linear 10K

Cabo para ligar as 8 linhas de dados entre o Arduino e o circuito

No Uno as 8 conexões estão alinhadas, no Mega elas são em pares.

No Mega eu usei um cabo de fita de 10 vias com um conector IDC de 10 vias. (2 fios são sobressalentes)

Conectores de soquete para saída 0V, 9V e DAC

Placa de tira de cobre, solda, fio, cortadores, etc.

Etapa 2: as especificações

As especificações
As especificações

Série definida em 115200 baud.

O suporte está disponível para o Hobbytronics MicroSD Breakout Board usando um Mega. A seleção do chip e outras portas serão alteradas entre Mega e Uno.

Os arquivos Wav devem existir em um diretório chamado adlog- Sinta-se à vontade para nomeá-lo de outra forma e reorganizar a codificação necessária.

O arquivo wav deve ser mono de 8 bits. Eu testei até 44KHz.

O monitor serial exibe os arquivos wav na pasta adlog. Os nomes dos arquivos são enviados da linha de saída do monitor.

O tamanho do arquivo é limitado apenas pelo tamanho do SdCard.

Etapa 3: primeiros passos

Começando
Começando

Conecte o leitor de cartão SD. Estas são as conexões do Mega.

0, 5V

CLK para pino 52

D0 para pino 50

D1 ao pino 51

CS para pino 53

(Consulte o site dos fornecedores para conexão Uno port)

Você vai querer testar se seu cartão funciona neste estágio - use os scripts fornecidos pelo fornecedor.

Precisamos fazer um pequeno circuito

Vamos enviar um fluxo de bytes de áudio do Arduino.

Esses números estão entre 0 e 255. Eles representam a tensão.

O silêncio é 127-128.

255 é o cone do alto-falante rígido em uma direção.

0 é o cone do alto-falante rígido no sentido contrário.

Portanto, o áudio é gravado como números salvos, que criam tensões variáveis, que criam cones de alto-falante em movimento.

Podemos enviar os números de 8 linhas no Arduino, simultaneamente, usando uma "porta".

Se alimentarmos as 8 linhas em um conversor digital para analógico, ele faz o que diz na lata e produz uma tensão analógica que é proporcional ao número digital.

Tudo o que precisamos fazer é colocar a tensão em um pequeno amplificador operacional e, em seguida, em um alto-falante.

Etapa 4: O pequeno circuito

O Pequeno Circuito
O Pequeno Circuito
O Pequeno Circuito
O Pequeno Circuito
O Pequeno Circuito
O Pequeno Circuito
O Pequeno Circuito
O Pequeno Circuito

O LCN DAC0832

Este é um conversor digital para analógico de 8 bits excelente e barato. (DAC)

Ele pode ser totalmente controlado com um conjunto de linhas de coleta de dados e amostras de dados.

Ou pode ser configurado para fazer tudo automaticamente em "Fluxo de operação".

Para citar o manual:

Simplesmente aterrar CS, WR1, WR2 e XFER e vincular ILE alto permite que ambos os registros internos sigam as entradas digitais aplicadas (fluxo direto) e afetem diretamente a saída analógica DAC.

OK, isso é quatro conexões para o conjunto de chips baixo e um definido para 9V - fácil.

Não queremos tensões negativas, então o manual diz que devemos usar o "modo de comutação de tensão" e eles fornecem o diagrama.

Tudo o que precisamos fazer é substituir um pequeno amplificador de áudio em vez do que eles sugerem.

O amplificador de áudio LM386-N

O manual do Amp fornece um diagrama de peças mínimo - fornecendo um ganho de 20 (muito para nós - mas tem um controle de volume).

Tudo o que precisamos fazer é adicionar um capacitor entre o DAC e o amplificador para amplificar apenas os sinais CA.

Devemos também adicionar alguns capacitores próximos ao pino de alimentação de cada um de nossos chips, caso contrário, obteremos zumbidos em nossa alimentação de 9V.

Etapa 5: pegue o ferro de solda

Pegue o ferro de soldar
Pegue o ferro de soldar
Pegue o ferro de soldar
Pegue o ferro de soldar
Pegue o ferro de solda
Pegue o ferro de solda

Como o circuito é simples não pretendo dar uma conta golpe a golpe.

Aqui estão algumas dicas:

  • Prepare um pedaço de placa de tira de cobre com pelo menos 28 por 28 orifícios. (Sim, eu sei que neurocirurgiões podem torná-lo menor)
  • Se você pretende montá-lo com parafusos, permita-os no início!
  • Monte os chips nos soquetes. Insira os chips apenas quando tudo tiver sido verificado.
  • Mantenha os fios de entrada longe da saída.
  • Observe a polaridade correta para os capacitores.
  • Consulte o diagrama para a vista básica da referência de tensão do LM336. A perna de ajuste não é usada e pode ser cortada.
  • Observe a conexão direta ao pino 8 do DAC- É muito útil para testes.
  • Eu conectei ao Audino com cabo de fita e um conector IDC de 10 vias.
  • No Uno, as conexões são em linha reta - você pode descobrir que organizar as 8 conexões de entrada em uma única linha reta permite que você se conecte ao Arduino com um conector de 8 vias comprado e pronto para uso,

Quando estiver pronto, verifique a solda e verifique as lacunas entre as faixas de cobre.

Acho uma lâmina de serra de corte júnior de 36 tpi muito útil para limpar detritos. Eu removo os pinos de localização da lâmina e deslizo a ponta da lâmina no trilho. Obviamente, a lâmina não está em um quadro.

Etapa 6: Testando o DAC

Testando o DAC
Testando o DAC

Deixe a conexão entre o circuito e o Arduino desligada.

Defina o controle de volume em seu circuito para o meio.

Ligue a alimentação de 9 Vcc em seu novo circuito.

Verifique se o circuito está bom - não posso aceitar qualquer responsabilidade pelo seu circuito!

Desligar

Conecte seu circuito ao Arduino.

No Mega, use os pinos 22-29. (PORTA) Não confunda os dois pinos de 5V acima!

No Uno, use os pinos 0-7. Este é o PORTD

Conecte o 0V da sua fonte de alimentação ao 0V do Arduino.

Energizar.

Abra este programa de teste DAC_TEST

Para o UNO, substitua todas as referências a PORTA por PORTD

Substitua DDRA por DDRD - esta instrução configura todas as 8 linhas para saída de uma vez. Este é o registrador de direção de dados.

Defina seu monitor serial em 115200.

Conecte um voltímetro entre a saída DAC e OV

O programa definirá a saída para 255 - todas as linhas ligadas - tensão máxima.

Saída 128 - meia tensão máxima.

Saída 0- tensão zero (ou provavelmente quase zero).

Em seguida, ele será executado em etapas: 1, 2, 4, 8, 16, 32, 64, 128

A tensão deve aumentar continuamente.

Se a voltagem cair enquanto o número aumenta, você provavelmente tem dois dos fios de interconexão invertidos.

Você também deve ouvir o alto-falante clicando silenciosamente conforme a voltagem muda

Etapa 7: ler o cabeçalho Wav

Lendo o cabeçalho Wav
Lendo o cabeçalho Wav

Os arquivos Wav são salvos com uma frequência e tamanho de dados especificados.

Esta informação está contida em um cabeçalho de 44 bytes no início de um arquivo wav.

Embora algum software estenda o cabeçalho (após o byte 35), tornando a localização do tamanho dos dados mais difícil de localizar.

Para ler o cabeçalho, criamos um buffer e copiamos o início do arquivo.

A frequência é armazenada em 4 bytes, começando com 24 bytes no arquivo.

// lê a frequência especificada no cabeçalho do arquivo wav

byte headbuf [60]

tempfile.seek (0);

tempfile.read (headbuf, 60);

retval = headbuf [27];

retval = (retval << 8) | headbuf [26];

retval = (retval << 8) | headbuf [25];

retval = (retval << 8) | headbuf [24];

Serial.print (F ("Frequência do arquivo"));

Serial.print (retval);

A melhor maneira de encontrar as informações sobre o tamanho dos dados é pesquisar a palavra "dados" no cabeçalho.

Em seguida, extraia os 4 bytes seguintes, que compõem o valor longo

retval longo sem sinal;

int mypos = 40;

para (int i = 36; i <60; i ++) {

if (headbuf == 'd') {

if (headbuf [i + 1] == 'a') {

if (headbuf [i + 2] == 't') {

if (headbuf [i + 3] == 'a') {

// finalmente nós temos

mypos = i + 4;

i = 60;

}

}

}

}

}

tempfile.seek (mypos);

retval = headbuf [mypos + 3];

retval = (retval << 8) | headbuf [mypos + 2];

retval = (retval << 8) | headbuf [mypos + 1];

retval = (retval << 8) | headbuf [mypos];

OK, temos o comprimento e a frequência dos dados!

Os dados de áudio seguem os 4 bytes que constituem o valor do comprimento dos dados.

Etapa 8: interromper, interromper…

Interromper, interromper…
Interromper, interromper…

Usamos as informações de frequência para criar uma interrupção de software na frequência necessária ou próxima dela.

A interrupção nem sempre pode ser definida com precisão, mas é suficiente. A freqüência lida do arquivo é passada para a sub-rotina setintrupt.

void setintrupt (float freq) {float bitval = 8; // 8 para temporizadores de 8 bits 0 e 2, 1024 para temporizador 1 byte

setocroa = (16000000 / (freq * bitval)) - 0,5;

// O valor setocroa requer uma subtração de -1. No entanto, adicionando 0,5 rodadas ao 0,5 mais próximo

// A resolução do temporizador é limitada

// Em última análise, determinado pela magnitude do bitval

cli (); // desativa as interrupções // define a interrupção do timer2

TCCR2A = 0; // define todo o registro TCCR2A para 0

TCCR2B = 0; // mesmo para TCCR2B

TCNT2 = 0; // inicializa o valor do contador para 0

// define o registro de comparação de comparação para incrementos de frequência (hz)

OCR2A = setocroa; // = (16 * 10 ^ 6) / (frequência * 8) - 1 (deve ser <256)

// liga o modo CTC

TCCR2A | = (1 << WGM21); // Definir bit CS21 para 8 prescaler

TCCR2B | = (1 << CS21); // ativa a interrupção de comparação do cronômetro

// TIMSK2 | = (1 << OCIE2A); // isso funciona, assim como a seguinte linha

sbi (TIMSK2, OCIE2A); // habilita a interrupção no cronômetro 2

sei (); // habilita interrupções

Leitores mais exigentes terão visto sbi (TIMSK2, OCIE2A)

Eu configurei algumas funções (adquiridas pela Internet) para definir e limpar bits de registro:

// Define para limpar bits de registro # ifndef cbi

#define cbi (sfr, bit) (_SFR_BYTE (sfr) & = ~ _BV (bit))

#fim se

// Define para definir bits de registro

#ifndef sbi

#define sbi (sfr, bit) (_SFR_BYTE (sfr) | = _BV (bit))

#fim se

Essas funções fornecem uma chamada fácil para definir ou limpar a interrupção.

Então a interrupção está em execução, o que podemos fazer?

Etapa 9: interrupções e buffer duplo

Interrupções e buffer duplo
Interrupções e buffer duplo
Interrupções e buffer duplo
Interrupções e buffer duplo

A 22 Khz, um byte de dados de áudio é emitido a cada 0,045 ms

512 bytes (o tamanho do buffer) são lidos em 2,08 ms.

Portanto, o buffer não pode ser lido do SDCard em um ciclo de gravação.

No entanto, 512 bytes são gravados na porta em 23,22 ms.

Portanto, tudo o que temos a fazer é configurar um novo arquivo lido toda vez que o buffer se esvazia e temos tempo suficiente para obter os dados antes que um novo bloco de dados seja necessário … Supondo que usemos dois buffers, esvaziando um à medida que preenchemos o outro.

Este é o buffer duplo.

A leitura do arquivo será retardada pela interrupção repetida, mas será realizada.

Eu configurei dois buffers de 512 bytes chamados bufa e bufb.

Se o sinalizador estiver pronto, lemos do porta, caso contrário, lemos do portb

Quando a posição do buffer (bufcount) atinge o tamanho do buffer (BUF_SIZE 512), definimos um sinalizador chamado readit como true.

A rotina de loop void procura por este sinalizador e inicia uma leitura de bloco:

if (readit) {if (! aready) {

// inicia a leitura do bloco SDCard para bufa

tempfile.read (bufa, BUF_SIZE);

} outro {

// inicia a leitura do bloco SDCard para bufb

tempfile.read (bufb, BUF_SIZE);

}

readit = false;

}

Quando terminar, a rotina sinaliza readit = false.

Dentro da rotina de interrupção, devemos verificar se o loop void terminou, verificando se readit == false.

Sendo este o caso, sinalizamos que outra leitura é necessária e alternamos o sinalizador aready para alternar os buffers.

Se o SDcard ainda estiver lendo, temos que voltar uma leitura (contador--; bufcount--;) e sair da interrupção para tentar novamente mais tarde. (Os cliques no sinal de saída de áudio indicam que isso ocorreu.)

Quando todos os dados são lidos, a interrupção é cancelada, a porta é reconfigurada para o valor de voltagem média de 128 e o arquivo de áudio é fechado.

Antes de executar o script dac2.ino pela primeira vez, defina seu volume para 50%. Isso vai soar muito alto, mas é melhor do que 100%!

Se o controle de volume funcionar ao contrário, troque os fios nas extremidades opostas do potenciômetro de 10K.

Deixe-me saber o que parece.

Recomendado: