Implementación de filtro digital en C (embebido)

Soy un recién graduado y mi nuevo proyecto en el trabajo consiste en tomar la señal de un micrófono electret y obtener valores SPL para 10 bandas de frecuencia estándar.

La amplificación/acondicionamiento analógico se completó, por lo que ahora estoy tratando de averiguar qué hacer en términos de muestreo/filtrado. Mis bandas de frecuencia son:

  • 31,5, 63, 125, 250, 500, 1000, 2000, 4000, 8000 y 16000 Hz

Decidí que debería poder usar una frecuencia de muestreo de 160 kHz (aparentemente 5-10 * Se recomienda la frecuencia de Nyquist de acuerdo con mis notas anteriores) y usar 10 filtros de paso de banda Butterworth de segundo orden que fueron diseñados usando mkfilter . Después de este punto, no estoy seguro de cómo proceder.

¿Simplemente usaría el filtro de 16kHz en cada muestra, el filtro de 8kHz cada 2 muestras, el filtro de 4kHz cada 4 muestras y así sucesivamente? (Obtengo estos números usando 5* tasa de Nyquist para cada banda, por ejemplo, 1/(8000Hz*2*5)/(1/160000Hz) )? Luego convertiría los valores a una presión y haría los cálculos necesarios para una medición SPL. ¿Hay una mejor manera de abordar esto? ¿Es correcto mi entendimiento?

El hardware con el que estoy trabajando tiene un reloj de 48MHz y 32kB de flash y 4kB de RAM.

Tal vez eche un vistazo a FFT y/o al algoritmo de Goertzel .
"tiene un reloj de 48 MHz" - ¿Y cuánto tiempo tienes para realizar los cálculos? ¿A qué frecuencia necesita nuevos valores de salida?

Respuestas (1)

No, si alimenta una señal que contiene frecuencias de hasta 16 kHz, su filtro deberá muestrear al menos 2*16 kHz para todas las bandas. Si muestrea solo a 160 kHz, tendrá que diseñar cada filtro para esa frecuencia de muestreo.

Puede usar una tasa de muestreo más baja para los filtros de frecuencia más baja, mientras mantiene la tasa de muestreo por encima de la frecuencia más alta presente (¿16 kHz?). Por lo tanto, tomar cada 2 muestras y usar 16 kHz (muestreo de 160 kHz) funcionaría para 8 kHz, pero entra en conflicto con la lógica para elegir un sobremuestreo de 5x en primer lugar (eso no es estrictamente necesario, depende de los componentes de frecuencia más altos) en la señal).

Tenga en cuenta que si extendiera este pensamiento a la banda de 31,5 Hz, usaría cada muestra número 500 == 160k/500 = 320 Hz, lo que no funcionaría con toda la señal ya que contiene componentes hasta (¿y más allá?) 16 kHz .

Diseñar cada filtro para la banda específica no es un problema para mí porque es bastante fácil de hacer con el software que mencioné. ¿Crees que podrías explicar más tu último párrafo? ¿Por qué no está bien usar una frecuencia de muestreo de 320 Hz si intento pasar solo la frecuencia de 32,5 Hz?
Porque si proporciona a ese filtro una señal de entrada que contiene componentes por encima de 160 Hz, se desactivarán. Entonces, por ejemplo, si hay señales de entrada en (320+32,5 = 352,5 Hz), no se distinguirán de las señales reales en 32,5 Hz. Su filtro tiene que muestrear al doble de las señales de ENTRADA, no de la salida.
@LPace; Si usó un banco de filtros FIR, podría usar un paso bajo para extraer siempre la octava más alta, obtener el SPL de eso, muestrear una octava hacia abajo y repetir. Sin embargo, me temo que la memoria RAM de 32 kb podría no ser suficiente para eso.
@ jp314 Eso fue extremadamente útil, gracias por aclararme eso. Así que supongo que tendré que almacenar al menos (1/32,5 Hz o ~30 ms) datos con un muestreo de 160 kHz para obtener un valor RMS preciso de la onda de presión más lenta (requerido para la medición de SPL). Eso equivaldría a casi 5000 muestras.
@Timo Sí, la restricción de RAM me hizo aprender sobre la implementación de IIR que tengo actualmente.