Definição de números de ouvido: implementação no Arduino

Neste artigo, continuarei a incorporar minha inspiração no trabalho de laboratório nº 3 já na glândula. Estamos falando sobre a detecção de um dígito pelo som no modo de discagem por tom no Arduino usando o algoritmo de Goertzel.

Para implementar isso, usei o Arduino UNO, um microfone de eletreto ( adafruit ) e uma tela 8x8 com o driver MAX7219.

Plano de ação


  • Discretize um número suficiente de amostras (usando o programa do artigo anterior, eu estava convencido de que 256 é suficiente).
  • Encontre as amplitudes da resposta de frequência correspondente às frequências desejadas que codificam os caracteres.
  • Os dois valores máximos da amplitude fornecerão os índices de linha e coluna do caractere desejado, por exemplo, a figura 3 se parece.
    imagem

Implementação


Antes de iniciar uma implementação, respondemos à pergunta - o Arduino UNO terá desempenho suficiente para nós?

Frequência de clock: 16MHz
Um ciclo de amostragem leva 13 ciclos de relógio
Valor do Prescaler que fornece a maior precisão: 128

Acontece 16 MHz / 13/128 ~ 9615 Hz - a frequência de amostragem desejada, o que significa que você pode trabalhar com frequências de até 4,8 kHz.

Ajuste ADC


Existem vários modos de operação ADC, os mais interessantes estão listados abaixo (uma lista completa na folha de dados da palavra-chave ADCSRB)

  • leitura única - usando o método analogRead (), mas é uma chamada de bloqueio que leva 100 µs e, usando-o, é impossível fornecer uma taxa de amostragem constante
  • modo de execução livre - nesse modo, o próximo ciclo de amostragem começa imediatamente após o final do anterior e a freqüência máxima de amostragem é fornecida
  • overflow do temporizador - a amostragem começa com o overflow do temporizador, permitindo ajustar a frequência de amostragem

Código de configuração ADC, para simplificar, usei o modo de execução livre.

ADMUX = 0; // Channel sel, right-adj, use AREF pin ADCSRA = _BV(ADEN) | // ADC enable _BV(ADSC) | // ADC start _BV(ADATE) | // Auto trigger _BV(ADIE) | // Interrupt enable _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz ADCSRB = 0; // Free-run mode DIDR0 = _BV(0); // Turn off digital input for ADC pin TIMSK0 = 0; // Timer0 off 

Processamento de sinal


Assim que o conjunto completo de amostras é digitado, desligamos a interrupção pelo ADC e calculamos a amplitude do espectro usando o algoritmo de Goertzel. Não competirei na descrição do algoritmo com este recurso exaustivo, mas darei minha implementação:

 void goertzel(uint8_t *samples, float *spectrum) { float v_0, v_1, v_2; float re, im, amp; for (uint8_t k = 0; k < IX_LEN; k++) { float cos = pgm_read_float(&(cos_t[k])); float sin = pgm_read_float(&(sin_t[k])); float a = 2. * cos; v_0 = v_1 = v_2 = 0; for (uint16_t i = 0; i < N; i++) { v_0 = v_1; v_1 = v_2; v_2 = (float)(samples[i]) + a * v_1 - v_0; } re = cos * v_2 - v_1; im = sin * v_2; amp = sqrt(re * re + im * im); spectrum[k] = amp; } } 

Senos e cossenos foram previamente calculados para amostras correspondentes às frequências desejadas. A versão completa do código está aqui .

Conclusões


Mais importante ainda, os recursos do Arduino UNO são suficientes para o processamento de som simples.


A principal lição que aprendi que o ADC é uma coisa sensível, depois de reconhecer e enviar o personagem para o console com sucesso, passei uma semana depurando-o para trabalhar com a tela, porque liguei o terra do microfone e o max7219 e todas as amostras se transformaram em ruído imediatamente.

Poderia ter sido melhor? Sim, seria mais correto selecionar a frequência de amostragem e o número de amostras para que as frequências desejadas coincidissem com a rede de amostragem, isso impediria a propagação do espectro. Esses parâmetros já são f = 8 kHz, N = 205; nesse caso, você precisa executar o ADC não no modo de execução livre, mas o estouro do timer e a diferença seriam óbvias.



O curso está chegando ao fim, mas ainda há muitas idéias.
Obrigado pela atenção.

Source: https://habr.com/ru/post/pt432498/


All Articles