Ir ao conteúdo
  • Cadastre-se

16F628A c/ 24LC512 playback 16KHz audio


Posts recomendados

Eae galera, estou com um problema e não sei se tem solução, é o seguinte, fiz um programinha aqui pra testar playback de sons no pic, minha 1ª ideia foi usar o Cartão SD(tudo em RAW data) fiz tanto no proteus como na pratica e funcionou parcialmente, porque demorava pra ler de bloco em bloco, eu lia 1 bloco e tinha um delay de 5ms e isso ficou ruim, parti pra EEPROM e escolhi a 24LC512 que é a unica que tem onde moro, porém a velocidade dela de operação é de 400KHz comparado ao Cartão SD que é de 20MHz(velo maxima) e com isso usando a EEPROM um simples "Oi" que tinha 500ms se tornou um som de 2s aproximadamente, sim horrivel. E queria saber se estou fazendo algo errado para reproduzir o som ou o que posso usar de fácil acesso no mercado para armazenar esse som? Estou usando a frequencia máxima do PIC(20MHz). Sei que tem a linha 25LCXXX que é mais rápida trabalha em 20MHz também seria o ideal eu acredito, ja pesquisei rios na internet e nada, se alguém que já testou algo assim pudesse me ajudar seria otimo :D.

 

Codigo(no CCS C) atual para leitura da EEPROM:

#include <16F628A.h>#fuses HS#fuses NOMCLR#fuses NOWDT#fuses NOPUT#fuses PROTECT#fuses NOBROWNOUT#fuses NOLVP#fuses CPD#use delay(clock=20000000)#include <24512.c>int16 length = 23790;int16 i;void main(){   setup_ccp1(CCP_OFF);   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);   setup_timer_1(T1_DISABLED);   //setup_timer_2(T2_DIV_BY_4,55,1);   setup_timer_2(T2_DISABLED,0,1);   setup_comparator(NC_NC_NC_NC);   setup_vref(FALSE);      set_tris_a(0b00000000);   set_tris_b(0b00000000);   output_a(0b00000000);   output_b(0b00000000);      init_ext_eeprom();      delay_ms(500);   for(i=0;i<length;i++)   {      output_b(read_ext_eeprom(i));   }   while(True){}}

valeu,

Victor Migliatti.

Link para o comentário
Compartilhar em outros sites

O primeiro erro foi usar o CCS,que  não sabe trabalhar com pointers.

O segundo é que você tem que fazer a leitura dos bytes SEQUENCIALMENTE,acho que terá que programar manualmente.

O terceiro é que usando o CCS,terá que usar FASTIO.

O quarto erro é que usando CCS,terá que usar um sample rate de 8 KHZ.

Como esta gravando o áudio?

Link para o comentário
Compartilhar em outros sites

Converti o arquivo WAV em Raw no audacity, renomeei o arquivo em .bin e gravei usando o gravador da elnec. Eu testei o simple rate em 8KHz e deu certo porém a qualidade obviamente acaba sendo um defeito. Quando eu usava o SD usei o MikroC Pro pra gravar todo o conteudo nele via RS232.

 

Att,

Victor.

Link para o comentário
Compartilhar em outros sites

valeu mesmo cara. Sequencial realmente melhorou muuito. Você me recomendaria outro Compilador C? Ou definitivamente mudar para ASM?? Pois quando eu começei, estudei o ASM para aprender como funciona o uC, os bancos e tal, mas preferi o C pelo tempo que se leva produzindo o código.

 

Att,

Victor.

Link para o comentário
Compartilhar em outros sites

Para este projeto recomendaria ASM.

Se voce não se importar,posta o código com leitura sequencia para o pessoal aqui usar.

Eu tenho um projeto que usa C18,olhando seu código,usando sequencial,talvez melhore o código.

Não utilizei o CCS,mas o algorítmico para leitura sequencial a 400KHZ,seria assim em C18;

    StartI2C();    WriteI2C(0b10100000); //ENDEREÇO I2C DA EEPROM    WriteI2C(Addr_Hi2);   //PARTE ALTA DO ENDEREÇO INICIAL     WriteI2C(Addr_Low2);  //PARTE BAIXA DO ENDERÇO INICIAL    StartI2C();	    WriteI2C(0b10100001); //INICIANDO ESCRITA//LOOPING COMEÇA AQUI,AJUSTAR QUANTIDADE DE BYTES LIDOS EM SEQUENCIA    buff = ReadI2C();     //INICIANDO LEITURA DIRETA//SAIDA PARA O PORT       //SAIDA DOS BYTES DE AUDIO P/ UM PORT//LOOPING TERMINA AQUI      StopI2C();             //LEITURA TERMINA AQUI    IdleI2C();            //  ""  
Link para o comentário
Compartilhar em outros sites

Problema nenhum.. O codigo ficou assim:

#include <16F628A.h>#fuses HS#fuses NOMCLR#fuses NOWDT#fuses NOPUT#fuses PROTECT#fuses NOBROWNOUT#fuses NOLVP#fuses CPD#use delay(clock=20000000)#use i2c(master, fast, sda=PIN_A1, scl=PIN_A0)#use fast_io(A)#use fast_io(B)int byte_atual = 0;int16 length = 23790;int16 i;#separatevoid le_eeprom(){   i2c_start();   i2c_write(0xa0);   i2c_write(0);   i2c_write(0);   i2c_start();   i2c_write(0xa1);   for(i=0;i<length;i++)   {      byte_atual = i2c_read();      output_b(byte_atual);   }   i2c_stop();}void main(){   setup_ccp1(CCP_OFF);   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);   setup_timer_1(T1_DISABLED);   setup_timer_2(T2_DISABLED,0,1);   setup_comparator(NC_NC_NC_NC);   setup_vref(FALSE);      set_tris_a(0b00000000);   set_tris_b(0b00000000);   output_a(0b00000000);   output_b(0b00000000);      output_float(PIN_A0);   output_float(PIN_A1);      delay_ms(500);   le_eeprom();   while(True){}}

valeu mesmo vtrx você me ajudou muuito!

 

Att,

Victor.

Link para o comentário
Compartilhar em outros sites

Não tinha reparado isso, mas por padrão ele é habilitado, por isso que i2c_read() sem nada funcionou..  Se alguém quiser saber, sobre o DAC eu utilizei o Weighted DAC R-2R-4R-8R-16R-32R-64R-128R o som ficou melhor do que eu esperava fica melhor ainda colocando um capacitor non polarized de 1uf no positivo do falante e no negativo ou um low pass filter que resolve a chiadera(pouca mas tem).

 

Att,

Victor.

Link para o comentário
Compartilhar em outros sites

Aproveitando o tópico, @eletronicav, não entendi muito bem a lógica que você usou pra reproduzir o som. Do jeito que você lê o byte da memoria já manda direto pra porta, tipo, sem uma conversão de digital pra analógico, pwm, etc? Usou um buzzer ou alto-falante mesmo? Conectado direto na porta?

Link para o comentário
Compartilhar em outros sites

Aproveitando o tópico, @eletronicav, não entendi muito bem a lógica que você usou pra reproduzir o som. Do jeito que você lê o byte da memoria já manda direto pra porta, tipo, sem uma conversão de digital pra analógico, pwm, etc? Usou um buzzer ou alto-falante mesmo? Conectado direto na porta?

 

extamente, eu leio o byte da memoria e mando direto pra porta 8bits e no DAC(conversor de digital para analogico) eu utilizei o Weighted DAC igual a esse da imagem porém de 8-bit, apenas acrescentando mais 2 resistores com valores de R*64 e R*128. Na saida utilizei um falante simples porém mesmo a saida variando de 0v a 5v não tem força suficiente para tocar, então precisa de um amplificador simples, no meu caso usei um LM comum de 0.5W e foi mais que suficiente.

04273.png

 

PS.: O valor do resistor não importa muito desde q seja fiel à multiplicação R*(x), não precisa ser exato mas quanto mais proximo melhor o som e menos chiado. O valor inicial de R pode ser qualquer um, no meu caso utilizei 100R pois se tivesse utilizado valor maior teria q usra no final resistores acima de 1M e nao tinha ai vai do que voce achar melhor.

 

Att,

Victor.

Link para o comentário
Compartilhar em outros sites

extamente, eu leio o byte da memoria e mando direto pra porta 8bits e no DAC(conversor de digital para analogico) eu utilizei o Weighted DAC igual a esse da imagem porém de 8-bit, apenas acrescentando mais 2 resistores com valores de R*64 e R*128. Na saida utilizei um falante simples porém mesmo a saida variando de 0v a 5v não tem força suficiente para tocar, então precisa de um amplificador simples, no meu caso usei um LM comum de 0.5W e foi mais que suficiente.

04273.png

 

PS.: O valor do resistor não importa muito desde q seja fiel à multiplicação R*(x), não precisa ser exato mas quanto mais proximo melhor o som e menos chiado. O valor inicial de R pode ser qualquer um, no meu caso utilizei 100R pois se tivesse utilizado valor maior teria q usra no final resistores acima de 1M e nao tinha ai vai do que voce achar melhor.

 

Att,

Victor.

Bom.

Duas informações:

1 - Ao invés de usar esta topologia de resistores, existe uma outra bem mais simples. Ela só possui dois valores de resistores R e 2R.

Pesquise por DAC R 2R. Na saída é que coloque um operacional, mas coloque a saída da malha resistiva na entrada positiva do operacional. Na entrada negativa coloque um resistor de valor R até a saída Assim o ganho será 1 e não interferirá na rede resistiva. Seria bom incluir um filtro passa baixas frequências, para retirar as comutações, apesar de não serem audíveis.

Veja um exemplo neste link:

http://www.paulotrentin.com.br/eletronica/conversor-dac-atraves-da-rede-de-escada-r2r/

2 - Agora é que vem o quente.

Há algum tempo, decidi fazer um tutorial em assembly com uma comunicação I2C entre o PIC e uma memória EEPROM 24C65. Obviamente que o tutorial pode funcionar com outras capacidades de memória. O detalhe é que neste tutorial eu procurei fazer as rotinas o mais rápidas possíveis.

Há um procedimento para se ler e escrever na memória EEPROM 24Cxxx. Se você seguir este procedimento, deve poder ler com uma velocidade maior.

Outro detalhe é que no Proteus não funcionou. Parece que há, ou havia um bug no Proteus. Eu montei e funcionou.

O trabalho, além de explicar o funcionamento da comunicação, possui diversas opções de transferência de bytes. Lendo o tutorial dá para entender do que estou informando.

O trabalho é composto por dois arquivos. Um em pdf, que contém a parte teórica, como cheguei nas diversas rotinas e muitos exemplos, que abrangem quase a totalidade das opções de transferência de bytes.

O outro arquivo é em asm, que deve ser aberto no MPLAB. Ele contém os exemplos da parte teórica. Usa um LCD 2x16 para informar do resultado dos testes realizados.

Deixei em assembly e não em binário, para poder se ter acesso às rotinas e poder ser modificado à vontade.

Vou criar um tópico com o tutorial. Caso seja de interesse, dê uma estudada. Vale a pena.

MOR_AL

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Legal heim, fiquei curioso agora kk. Realmente o proteus pra isso deixa a desejar, também tive problemas em testar com ele, no começo nao funcionava nada e na verdade tudo estava funcionando ¬¬. Sobre o DAC eu ja conhecia R/2R, até montei porém ficou muito ruim o som, dai montei este outro que também era muito mais fácil pra montar na mão e no final acabou com a metade de componentes porque os valores que eu "escolhi" acabaram sendo os tradicionais do mercado então na questão dos valores diferenciados não tive problema. E outro problema era que o único amp. op. que eu tinha precisava de fonte simétrica e eu não tenho, dai uma vantagem pra mim usar esse outro DAC, porque ele não precisa de operacional o que facilitou pra mim. Realmente o R/2R é mais fácil mas não quis perder tempo procurando o erro, pensava que era a fonte mas não era, tanto que eu liguei todos os resistores do R/2R pro terra e coloquei no osciloscópio e continuou essa interferência, dai desisti do R/2R e montei esse outro.

 

valeu.

Link para o comentário
Compartilhar em outros sites

 

use PWM,é mais simples a interface.

No começo eu usava R2R,mas depois acabei por usar PWM.

 

Mais simples sim, mas vamos a algumas considerações, para um som com qualidade razoavel o ideal é que a a frequência da portadora do PWM seja bem superior a máxima frequência do sinal de voz que voce queira reproduzir, tipicamente usa - se uma frequência cerca de 10x superior, por exemplo, se quiser reproduzir um sinal de voz amostrado a 8KS/s (ou seja 4KHz a bem grosso modo) teras que usar um PWM com frequencia de portadora de pelo menos uns 80KHz.

Vale lembrar que além da frequência e portadora, resolução do PWM também é importante, de nada adiante tem a portadora altissima, se teu pWM conegue representar 30 niveis de tensão média (apos passagem pelo filtro passa baixas), reprodução de voz fica excelente quando se tem 16bits disponiveis, no caso do PIC a porta CCP so consegue oferecer 10bits com uma frequência relativamente baixa, ou seja é bom estudar o uso de um DAC para a economia nao acabar saindo cara (considerar o uso de um DAC serial como o MCP4921, também é boa opção).

Para processadores com desempenho menor como 8bits, eu prefiro o uso de D/A paralelos, em circuitos integrados, ou implementados em montagens como o ponderado usado pelo amigo @eletronicav ou o R-2R apresentado pelo colega @MOR, a vantagem é que você pode trabalhar com uma frequência de portadora proxima a taxa de amostragem do teu sinal, demandando menos processamento, ou mesmo gasto desnecessario de um timer que poderia servir para temporizar o a amostragem do conversor A/D. É comum ver projetistas usando esse D/A mas esquecendo - se de conceitos importantes sobre processamento numerico de sinais, em especial na hora da reconstrução, fazendo com qu o uso desse tipo de conversor tenha desempenho sofrível.

Para melhor desempenho, após o conversor D/A é importante;

- Fonte ratiométrica, ou seja a fonte da tensão de referencia do D/A tem que ser a mesma de toda a cadeia de processamento do sinal;

 

- Desacomplamento da fonte usada para alimentar o microcontrolador da fonte usada para alimentar o D/A (um capacitor tanque local, perto do pino de fonte do D/A ja da uma grande diferença).

- Esse é mais critico, um bom filtro após do D/A, esse filtro é tomado por filtro de reconstrução, é um filtro passa baixas, mas se bem projetado o mesmo, deve eliminar do espectro do sinal a portadora da taxa de amostragem, além disso, esse filtro ajuda na remoção de grande parte de ruído de quantização que todo e qualquer D/A possui, de forma que as transições entre duas amostras são suavizadas, 

termino esse post com um pouco de literatura sobre reconstrução de sinais digitais para analogico:

 

http://www.qsl.net/py4zbz/teoria/recons.htm

 

http://pessoal.utfpr.edu.br/janeczko/index_files/pds/capitulo2.pdf

 

http://www.ni.com/white-paper/3016/pt/

Abs

Link para o comentário
Compartilhar em outros sites

Boa @victhor393

 

 

 

20 KHz vai ficar com um som muito ruim, a frequência de Nyquist para uma taxa de amostragem de 20 KSa/s é 10 KHz. Pra voz até que funciona, mas pra qualquer outra coisa, esqueça.

 

além do seu comentário existe um porém,  o critério de Nyquist so é válido quando o sinal é constuiído por uma senoíde, nesse caso nao existe perda de informação, porém no mundo real isso praticamente nao existe, o que faz com que precisemos de taxas de amostragens bem maiores que a máxima banda desejada, além de um bom filtro anti-aliasing.

 

 

 

Eu ensinei esta técnica a alguns fóruns,mas não precisa ser 10x,sendo inaudível ao ouvido humano ja é o suficiente,que no caso seria 20000 Hz de frequência máxima,acima disto é desperdício de recursos.

O fato da frequênncia da portadora nao ser audível é critério necessário, mas não suficiente para correta amostragem ou reconstrução de um vetor de dados, veja que uma frequência de amostragem menor que a necessaria vai causar no processo de reconstrução o efeito de aliasing do sinal que pode cair em banda audível e por fim prejudicar a qualidade final da gravação. vale lembrar que cada instante do periodo do sinal de PWM representa 1 ponto no sinal amostrado, e se o periodo do PWM for muito grande no momento em que ocorrer uma transição brusca de amplitude, o proprio filtro de reconstrução nao irá fazer com exito o efeito de averaging entre um ponto e outro do sinal de audio, causando aquele efeito de metalização no som.

Para soluções baseadas em streams de 1bit eu prefiro utilizar conversao sigma delta, com ela é possivel utilizar taxas de amostragem, além disso o procedimento sigma-delta faz com que todo ruido fora da banda de interesse seja deslocado para banda de amosragem, milhoes de vezes superior, sem contar que como o stream de dados tem uma frequência máxima muito maior, o filtro de reconstrução fica muito mais simples de projetar.
 

http://www.ti.com/lit/an/slyt076/slyt076.pdf 

Ai em cima, uma nota de aplicação da TI, que ensina passo a passo como fazer, eu particularmente prefiro fazer esse tipo de coisa em assembly.

Abs.

Link para o comentário
Compartilhar em outros sites

Para o tópico em sí,não esta saindo um pouco do assunto?

Tudo que posto tenho o Hardware funcionando,neste caso é um projeto que fiz a alguns anos mas vou 'reconstruir' a placa que usa um 18F2550 e PWM com áudio muito bom para a aplicação do tópico.

Como ja deve ter visto,minha primeira experiência com WAV e um simples PIC,foi feito ha um tempo e, ASM;

 

 

Os detalhes estão na descrição,5KHZ de áudio,PIC a 4MHZ mas usando DAC resistivo.

A versão com PWM e USB usa o mesmo algorítmico,sendo que a portadora é de 4x a amostragem,que é em 8KHZ.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...