Índice:

QuickFFT: FFT de alta velocidade para Arduino: 3 etapas
QuickFFT: FFT de alta velocidade para Arduino: 3 etapas

Vídeo: QuickFFT: FFT de alta velocidade para Arduino: 3 etapas

Vídeo: QuickFFT: FFT de alta velocidade para Arduino: 3 etapas
Vídeo: EasyFFT: Fast Fourier Transform (FFT) for Arduino 2024, Novembro
Anonim
QuickFFT: FFT de alta velocidade para Arduino
QuickFFT: FFT de alta velocidade para Arduino

O Arduino típico tem memória RAM e poder de processamento limitados, e FFT é um processo de computação intensiva. Para muitas aplicações em tempo real, o único requisito é obter frequência com amplitude máxima ou necessário para detectar picos de frequência.

Em uma das minhas instruções, preparei um código para FFT que pode ser encontrado aqui: EasyFFT

Este código foi capaz de executar FFT de até 128 amostras no Arduino nano. Um número de amostra maior do que esse não é possível devido à memória limitada do Arduino. Eu modifiquei um pouco a função para melhorar a velocidade e reduzir o consumo de memória. Essa modificação permite que o Arduino execute FFT cinco vezes mais rápido e consome quase metade da memória. Este Instructable não cobre o Trabalho da FFT, referências para ele podem ser encontradas no EasyFFT.

Etapa 1: Trabalhando

Trabalhando
Trabalhando
Trabalhando
Trabalhando
Trabalhando
Trabalhando
Trabalhando
Trabalhando

A função FFT típica é modificada para melhorar a velocidade com menor precisão. Conforme mostrado na imagem, um sinal de teste precisa ser multiplicado por formas de onda seno ou cosseno. Esses valores podem estar entre 0 e 1, portanto, fazer a multiplicação flutuante é uma obrigação. no Arduino, a multiplicação flutuante é lenta em comparação com as operações de inteiros.

Nesta função, a onda seno / cosseno é substituída por uma onda quadrada. Como temos que multiplicar um sinal de teste por uma onda quadrada que pode ter valor 0, 1 ou -1. Devido a isso, podemos substituir a multiplicação flutuante pela simples adição ou subtração de inteiros. Para o Arduino, a adição ou subtração de inteiros é cerca de 5 vezes mais rápida. Isso torna a resolução cerca de 5 vezes mais rápida.

Devido a essa modificação, agora os valores de bin de frequência podem ser armazenados como um inteiro (que antes era flutuante) e temos outra vantagem de menor consumo de memória. No Arduino Nano, int consome 2 bytes de memória enquanto float consome 4 bytes de memória. Devido a esta vantagem no novo código, somos capazes de executar FFT para quase 256 amostras (anteriormente 128 amostras).

No FFT normal, precisamos armazenar o valor do seno para tornar uma solução mais rápida. Na nova função, como não precisamos mais dos valores de seno / cosseno, podemos eliminá-los e economizar memória.

Implementação:

A implementação dessa função é direta. Podemos simplesmente copiar a função no conjunto de código. Esta função pode ser executada usando o comando abaixo:

float f = Q_FFT (dados, 256, 100); Na função Q_FFT, dados: este termo é uma matriz com valores de sinal, o tamanho de amostra recomendado é 2, 4, 8, 32, 64, 128, 256, 512, … em diante. se o tamanho da amostra não pertencer a esses valores, será recortado para o lado inferior mais próximo dos valores. por exemplo, se o tamanho da amostra for 75, o FFT será realizado para 64 números de amostras. O número máximo do tamanho da amostra é limitado pela RAM disponível no Arduino.

O segundo termo especifica o número de amostras em uma matriz e o último termo é a frequência de amostragem em Hz.

Etapa 2: Código

Esta seção explica a modificação feita no código EasyFFT que precisa ser mantida em mente ao fazer modificações no código, 1. Como explicado antes, aqui os inteiros são usados para fazer FFT. Int no Arduino é um número de 16 bits e pode conter valores de -32768 a 32768. sempre que o valor desse int exceder esse intervalo, ele causará o problema. para eliminar este problema após cada cálculo de nível. se algum valor exceder 15.000 matrizes completas serão divididas por 100. isso evitará o estouro do int.

2. Cálculo da amplitude: para calcular a amplitude, as partes real e imaginária precisam ser quadradas e a raiz quadrada da soma é necessária. quadrada e a raiz quadrada da função é demorada. para tornar o processo mais rápido, este código simplesmente fará algumas das magnitudes das partes reais e imaginárias. Isso é certamente menos preciso e pode levar a conclusões erradas em alguns casos. você pode escolher retornar ao método Normal para cálculo de magnitude, mas isso levará mais tempo e você também precisará fazer alguns arranjos para armazenar esses números.

3. Este código não possui um módulo para detecção de múltiplos picos. Ele simplesmente escolherá o valor com amplitude máxima (excluindo o primeiro número que é DC offset). Se você precisar de vários picos, pode consultar o código EasyFFT e fazer as modificações necessárias aqui. Nesse caso, alguma matriz / variável também precisa ser declarada como uma variável global.

4. A função contém a seguinte linha:

unsigned int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

declarar as variáveis acima como uma variável global (colando-as no início do código) economizará 1 milissegundo em cada execução.

5. Ao contrário da função EasyFFT, onde os 5 picos principais foram armazenados na matriz predefinida. Esta função retornará um valor flutuante. este valor representa a frequência com amplitude máxima em Hz. Portanto, a representação do código será mais ou menos assim.

float f = Q_FFT (dados, 256, 100);

6. Detecção de pico: uma vez que a frequência com amplitude máxima é encontrada, esta função usa uma amplitude de frequência imediatamente anterior e posterior para calcular os resultados precisos. A amplitude usada neste cálculo também é a soma do módulo (não a raiz quadrada da soma dos quadrados)

se Fn for a frequência com amplitude máxima, a frequência pode ser calculada a partir da fórmula abaixo.

Fn real = (A n-1 * Fn-1 + An-1 * Fn-1 + An-1 * Fn-1) / (An-1 + An + An + 1)

onde An é a amplitude de n a frequência e Fn-1 é o valor da frequência.

Etapa 3: Resultados:

Resultados
Resultados
Resultados
Resultados

O tempo de resolução é mostrado na comparação da imagem acima com EasyFFT. Velocidade mostrada com a comparação.

Para dados de amostra com 3 ondas sinusoidais com frequências diferentes, é mostrado. O resultado do QuickFFT é comparado com a saída do Scilab. Como podemos ver na imagem, 3 picos com amplitude máxima combinam com a saída do Scilab. No entanto, a saída consiste em muito ruído, o que pode ser enganoso para alguns aplicativos. Portanto, é aconselhável verificar o código corretamente antes de se inscrever em seu aplicativo.

Espero que você tenha achado este código útil para o seu projeto. Em caso de dúvida ou sugestão, por favor, comente.

Recomendado: