Crie seu filtro digital com a placa Curiosity da Microchip

filtro digital

Olá caro leitor, apesar do grande advento de microcontroladores de 32 bits com preços em queda, contendo periféricos especiais além de arquiteturas otimizadas para processamento digital de sinais (filtros, transformadas, cálculo vetorial, controladores), ainda é muito comum recorrer a processadores menores de 8 bits pelos mais diversos motivos:

  • Mesmo com preços em queda, soluções em 8 bits em alguns casos são mais atrativas em preço;
  • Simplicidade, um processador maior de 32 bits oferece uma curva maior de aprendizado;
  • Estabilidade, por estarem no mercado há mais tempo, ferramentas para microcontroladores de 8 bits estão mais maduras e testadas.

Fato, é que quando o assunto é processamento de sinais, o projetista fica sem opções tendo muitas vezes que migrar para um chip com maior poder de processamento pois precisa das características de tempo real, além dos diversos aceleradores para filtrar algum sinal no domínio digital. A Microchip anunciou recentemente a sua família de microcontroladores PIC, a adição de novos processadores dos chamados enhanced mid range. Os PIC16F161x possuem, além do novo núcleo com instruções otimizadas para programação em C, os chamados independent core peripherals, entre eles o acelerador matemático MATH, que implementa funções de multiplicação e adição em regime 16 por 16 bits, além de acumulação com até 35 bits. Mas o mais interessante é que esse periférico implementa também um completo controlador proporcional-integral-derivativo levando apenas 7 instruções para efetuar o cálculo total.

Neste artigo não vamos explorar o PID (pois não teria a menor graça no momento, ja está tudo pronto), mas com a placa Curiosity da Microchip modificaremos a operação do acelerador MATH de forma que consigamos implementar um calculador de equação de diferenças para implementação de filtros digitais entre 2 e 4 ordem que são perfeitos para tratar diversos tipos de sinais.

O hardware utilizado

Adquiri recentemente uma placa de desenvolvimento Curiosity da Microchip. Queria avaliar os microcontroladores PIC atuais e para minha agradável surpresa vi que o processador alvo da placa é justamente um que continha o acelerador MATH. Logo, por que não usar esse kit? Pois além de tudo pode ser adquirido por $20 no Microchip Direct e o preço final ficou U$$ 65 dólares com frete + R$ 110 de impostos, por isso recomendo sua busca em algum distribuidor nacional. A curiosity é vista na figura 1 abaixo:

curiosity
Figura 1 : Aspecto da placa curiosity

Entrar em detalhes sobre os componentes desse kit foge ao escopo deste artigo. Para mais informações a respeito do kit, sugiro a leitura da série de artigos sobre essa placa do colega Fabio Souza, onde ele explica o que o kit contém, bem como o preparo para desenvolver aplicações com essa placa.

Filtro digital num Microchip sem ser dsPIC ou PIC24? Como isso?

Um fato interessante é que a Microchip possui microcontroladores que são, digamos, adequados para efetuar tarefas comuns de processamento digital de sinais. O core de 16 bits do PIC24 já oferece muita coisa como multiplicador 17×17 de 1 ciclo de clock, além de unidades de divisão. O set de registradores é grande suficiente para computar um pequeno filtro digital de segunda ordem sem maiores problemas. Já o core do dsPIC fornece um hardware dedicado ao processamento digital de sinais, contendo, além dos itens mencionados no seu colega de 16 bits, um set de instruções para realizar a maioria das operações para tratamento de sinais digitais como multiplicador e acumulador (o conhecido MAC), saturação, unidade de endereçamento, gerenciador de loops por hardware (sim, ele faz for e while sem gastar CPU) e muito mais coisas. Então o que nos levaria a usar um pequeno micro de 8 bits que nem multiplicação por hardware faz? 

Como já mencionamos na introdução, esse pequeno processador que vem embarcado na placa Curiosity possui uma coisa que seus dois colegas não: simplicidade de desenvolvimento (menor curva de aprendizado) e menor preço. É comum em aplicações que exijam algum tratamento digital em sinais elementares (filtragem ou controle por exemplo). Utilizar um processador maior que o necessário (até mesmo em termos de se deixar uma folga) resulta em maior gasto, complexidade de hardware e terminais inutilizados.

Ok, legal, mas ainda não devo ter respondido a pergunta do leitor. Vamos lá! Se consultarmos o datasheet veremos que esse microcontrolador que vem na Curiosity faz parte de uma família voltada para controle digital, contendo, além de geradores de PWM e periféricos independetes da CPU, o mesmo tem um acelerador matemático para implementação de um controle PID, chamado MATH. Mais detalhes dele podem ser vistos aqui.

Legal, você deve estar se perguntando, mas onde que um controlador PID por hardware pode ajudar se queremos na verdade um filtro digital? Oras, quem leu alguns dos meus artigos sobre controle PID, sabe que uma de suas modelagens é um caso especial de um filtro digital de segunda ordem conhecido como 2p2z, onde temos um pólo em 1.0 e outro na origem (em 0.0). O que a Microchip fez? Implementou o mesmo algoritmo por hardware, e foi mais longe, adicionou 2 modos extras de funcionamento! Infelizmente o PID por hardware não possui a opção de configurar os coeficientes que são os pólos da função de transferência 2p2z, entretanto o MATH permite que o configuremos em modo de multiplicação sinalizada com acumulação, e é nesse modo que o configuraremos, obtendo-se assim uma unidade de multiplicação e acumulação que completa a operação em 2 ciclos de máquina. Para fins de comparação, processadores de 32 bits que não possuem set especificos para processamento digital de sinais podem levar para a mesma operação de 3 a 7 ciclos de máquina!

Tendo a unidade de multiplicação e acumulação (com um belo acumulador de 35 bits, mais que suficiente para saturar o resultado), vamos fazer uso das novas instruções dos chamados enhaced core PIC16. Tratam-se dos mesmos microcontroladores já “velhos de guerra”, mas com um set de 49 instruções otimizado para programação em C, o que significa que programá-los em assembly também se tornará uma tarefa bem prazerosa (código fácil de otimizar). Não se preocupe caro leitor, apenas o trecho de filtragem das amostras foi escrito em assembly, o restante da aplicação foi feita em C, um belo filtro digital capaz de processar sinais a taxa de amostragem de 8KHz (sendo taxas superiores possíveis de serem executar).

O projeto do filtro

Bem, agora que já sabemos que nossa pequena placa Curiosity irá dar conta do recado, precisamos escolher um filtro digital legal pra se testar nela. Vamos projetar um pequeno filtro passa baixas do tipo Butterworth, velho conhecido e que atende requisitos de limpeza de sinal oferecendo uma boa rampa de atenuação e ganho constantes em toda banda de passagem. Como nosso filtro é de segunda ordem, vamos utilizar um de também segunda ordem, a resposta típica de um filtro desses pode ser vista na curva de Bode abaixo.

filtro-digital-curva-de-Bode-filtro-Butterworth-segunda-ordem
Figura 2 : Curva de Bode para um filtro Butterworth de segunda ordem

Explicar detalhes de como modelar um filtro analógico para digital está fora do escopo deste artigo, mas você pode encontrar um bom texto introdutório que fiz há alguns meses aqui. Abaixo projetamos um pequeno filtro digital passa baixas com frequência de corte em 550Hz, com taxa de amostragem de 8kHz. Vejamos então sua função de transferência.

Eq. 1 – Função de transêferencia do filtro digital

A equação pra quem leu a série sobre DSP (que está parada eu admito, mas prometo retoma-la) é bem trivial, é um caso de filtro com dois pólos e dois zeros, como já mencionamos antes. Infelizmente não é possível configurar o acelerador MATH do microcontrolador de forma que possamos variar o valor dos pólos, caindo sempre no caso especial de um controlador PID. Para tal modificamos sua operação para funcionar como uma unidade que multiplica e acumula perfeita para a resolução de equações lineares de diferenças. Assim tomando a transformada Z inversa vamos obter tal equação:

Eq. 2 : Equação linear de diferenças do filtro digital
Eq. 2 : Equação linear de diferenças do filtro digital

Com essa equação convenientemente programada a placa Curiosity será capaz de filtrar sinais com frequências acima dos 550Hz, com uma atenuação bem agressiva, a partir do ponto de -3dB. Além disso o filtro possui um ganho de 0.50, isso se fez necessário para contornar as limitações da implementação dos coeficientes em formato de ponto fixo 1.15 sem que se perca resolução. Caso o leitor deseje é possível relizar uma implementação com ganho unitário bastanto rotacionar para esquerda a amostra do filtro antes dela ser colocada no DAC (dentro da rotina de interrupção).

O Firmware do filtro digital

Realizar um filtro digital já é um ganho e tanto para um microcontrolador de 8 bits que possui baixo custo, porém de nada adianta gastar toda a largura de banda da CPU apenas para realizar a filtragem. É fato que o algoritmo do filtro digital levou cerca de 6uS para processar, sendo suficientemente rápido, caso seja o desejo do leitor de filtrar um sinal de 8kHz em tempo real (delay de sinal da entrada para a saída nulo). Porém, em aplicações de processamento de voz, ou um decodificador DTMF por exemplo, não precisam de tamanho esforço computancional, aliás se o sinal alvo de processamento digital não for um de sistema de controle, dificilmente será necessário recorrer a técnicas de processamento amostra a amostra. Para filtrar bem o sinal e ainda deixar CPU de sobra para outras tarefas, utilizamos uma técnica de armazenamento chamada de ping-pong buffer, sendo duas estruturas dessas, uma para coletar amostras do A/D e outra para alimentar o D/A periodicamente (a cada 8kHz). A estrutura típica de um ping-pong buffer pode ser verificada na figura 3.

filtro-digital-ping-pong-buffer
Figura 3 : Aspecto do ping-pong buffer

Como o próprio nome sugere, a grande vantagem dessa estrutura é que enquanto um bloco está cheio e sendo processado, o outro vai enchendo de forma que ao passo que isso venha a ocorrer o buffer previamente processado é liberado para que seja preenchido por um novo conjunto de amostras (ou alimente o DAC com amostras) enquanto o novo bloco é processado, e seus dados são copiados ao outro bloco previamente livre. Essa estratégia tem um grande valor no microcontrolador, pois a rotina de interrupção responsável por reproduzir o sinal no DAC e coletar dados do A/D fica leve e enxuta, importunando a CPU apenas quando um novo bloco está cheio. Como a ISR ocorre a cada 8kHz (ou 125 us), com um buffer de 64 amostras por bloco o evento de buffer cheio irá acontecer em aproximadamente 64 * 125us = 8ms. Ou seja, no intervalo de 8ms a CPU deve dar conta de processar um bloco de 64 amostras (no caso o buffer chamado de inativo), copiar para o ping-pong de saída e o deixar disponível para alimentar o DAC também a cada ocorrência da ISR. Somando isso com o baixo overhead do filtro digital, que é de 64 * 6us = 384us, esse é o tempo levado para que isso ocorra, ou seja, temos aí livre para implementar outras tarefas um total de aproximadamente 7,34ms mais de 84% da CPU livre para outros processamentos (daria até pra colocar mais filtros ou mesmo um algoritmo de Goertzel). Abaixo temos o trecho de código mais hardcore, que é a unidade de multiplicação e acumulação para um filtro digital de segunda ordem.

O código é auto explicativo. Como todo bom filtro, zera o acumulador e carrega toda a matriz de estados do filtro (aqui aparece a vantagem dos microcontroladores enhanced core, com o uso das instruções MOVIW e MOVWI). Em seguida o processador MATH é acionado em um total de 5 vezes sendo 1 para cada operação de multiplicação e acumulação, levando 2 ciclos de clock por operação. Também importante vejamos como ficou a cara do arquivo principal main.c.

Em main.c temos apenas três funções, dada a simplicidade da aplicação de demonstração. A função UpdateTick é chamada externamente pelos arquivos gerados pelo Code Configurator, utilizado para configurar e inicializar todos os periféricos utilizados nesse experimento. Em caso de dúvidas sugiro a leitura deste texto do amigo Fábio Souza onde ele ensina passo a passo como usar essa ferrameta. UpdateTick é usado para gerar uma base de tempo de 1ms, que é usada para piscar um dos LEDs da placa a uma taxa constante (cerca de 100ms em cada estado). A função SignalProcessEngine também é chamada externamente a cada interrupção gerada pelo A/D, a sua função é justamente coletar a última conversão feita e ao mesmo tempo alimentar o DAC com o buffer ping-pong ativo. Caso o buffer corrente esteja cheio, um evento de buffer cheio é gerado e a ISR direciona as amostras e alimentação do DAC para o próximo buffer que já estará livre. Em main, que é a função principal, o bloco mais importante é que contém o teste da variável shouldFilter. Caso essa variável esteja em verdadeiro (recebeu evento de buffer cheio),  a aplicação pega o buffer, que agora é chamado por inativo, previamente cheio pela ISR, e dispara a filtragem no bloco de 64 amostras, para em seguida copiar o bloco filtrado dentro do buffer por enquanto inativo do DAC. E assim o ciclo se repete. Ao final da rotina main existe um timer virtual que a cada 100ms muda o estado do LED D4 na placa Curiosity. Esse LED é bem útil pois informa se o programa está rodando corretamente. Assim sendo, essa é a aplicação. Extremamente simples.

Resultados

O resultado dessa aplicação é do tipo que só é bem entendido se mostrado o que realmente acontece com o sinal que entra na saída da Curiosity. Para tal injetamos um sinal senoidal com frequência variável de 10 a 2kHz no pino RA1, correspondente ao canal 1 do conversor A/D desse PIC. Em RA0 temos saída do DAC onde capturamos o sinal de saída com o osciloscópio. Adotamos o pino do DAC de um capacitor de 10nF que em conjunto com a impedância de saída do DAC forma um filtro passa baixa com corte próximo a 4kHz funcionando assim como filtro de reconstrução, eliminando o efeito do retentor de ordem zero que o DAC causa no sinal. O caro leitor vê neste vídeo a amplitude do sinal variando apenas em função da frequência do sinal de entrada. Veja que ele se mantém constante até perto de 500Hz onde começa a decair e em 550Hz temos o ponto de -3dB que indica a frequência de corte atenuando de 6 em 6 dB até o ponto que a partir de 1.5kHz quase não temos sinal na saída. Gostaria de lembrar o leitor que ao testar essa aplicação, que desconecte da placa (após gravar o microcontrolador) os pinos RA0 e RA1, pois os pinos de gravação do debugger in circuit da Curiosity interfere no comportamento das funções analógicas do microcontrolador, principalmente o DAC. Esse possui uma impedância de saída elevada, fazendo com que qualquer carga adicional que não seja a ponta de prova do osciloscopio cause interferência no ganho DC do sistema (atenua ainda mais o sinal do DAC).

Conclusão

A Microchip acertou em cheio, tanto na ferramente de desenvolvimento que é a Curiosity, com baixo custo, e feita para prototipação, bem como acertou com essa nova linha de microcontroladores enhanced core, com diversos periféricos independentes da CPU, entre eles um acelerador matemático que não só faz aquilo que promete bem feito (controle PID) mas que permite explorar outros campos do processamento digital de sinais com um pouco de criatividade e leitura do manual do microcontrolador. Espero que o leitor tenha gostado dessa solução pequena mas notável com um 8 bits. Então é isso, até a próxima.

Links úteis:

[1] – Repositório com o firmware para gravação no PIC

Referências

[1] – Microchip PIC16F1619

[2] – Microchip Curiosity development board

[3] – Microchip 16 bits MCU & DSCs

[4] – OPPENHEIM, Alan V. – Digital Signal Processing – 1st Ed.

[5] – Arquitetura enhanced mid range Microchip

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Software » Crie seu filtro digital com a placa Curiosity da Microchip
Comentários:
Notificações
Notificar
guest
3 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Rafael Gebert
Rafael Gebert
05/02/2016 11:50

Olá Felipe! Excelente artigo!
Discordo apena sobre a questão de custo… consultei na digikey e constatei que os PIC24 (USD0.9) estão mais baratos que os PIC16 (USD1.3)… Existem alguns motivos para isso (inclusive o tipo de tecnologia entre os PIC16 e PIC24) mas principalmente porque a microchip tem muito interesse que o pessoal migre para essa arquitetura.
Além do mais o PIC24 é mais vantajoso por fazer laços por hardware (como você mesmo comentou) e porque o FCY dos PIC24 é /2 enquanto que o FCY dos PIC16 é por /4.
Obrigado!

Felipe Neves
Felipe Neves
Reply to  Rafael Gebert
06/02/2016 13:19

Rafael, obrigado por ler o artigo. Entendo que comparado a processadores mais proximos como o PIC24 por exemplo o custo em um primeiro momento pareça desinteressante, concordo que a CPU dos 24 é muito mais poderosa (aliás creio que uma das mais poderosas do range de 16bits). Mas veja que o custo próximo mas com uma simplicidade maior no desenvolvimento inicial pode tornar o uso do irmão menor da Microchip, mais interessante do que encarar uma curva de aprendizado quase alinhada na horizontal,rs. E falando em CPU, nao citei isso no artigo, mas veja que se compararmos puramente as arquiteturas… Leia mais »

Rafael Gebert
Rafael Gebert
Reply to  Felipe Neves
11/02/2016 16:19

Olá Felipe! Realmente a diferença de custo é bem pequena mas isso me chamou a atenção porque o normal seria pré-supor que um micro mais poderoso seria mais caro (só que não heheheh)!
E claro que os PIC16 são super simples e robustos, afinal não é a toa que eles são os micros mais vendidos no mundo todo!
Sim, os PIC24 possuem o REPEAT por hardware além de várias outras ferramentinhas que fazem dele até mais poderoso que outras arquiteturas mais famosas.
😉

Talvez você goste:

Séries

Menu