Man, the first and the second week of this year is rough as the weather isn't looking good!
However, after for so many experimentation, I have squeezed out an IIR filter. To try the code, I have used the book "Real time Digital Signal Processing from Matlab to C with the TMS320Cx DSPs", Matlab/Octave and an online C compiler before putting this into the microcontroller:
/******************************************************************************
Online C Compiler.
Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <stdio.h>
float b[2] = {0.9980, -0.9980};
float a[2] = {1.0000, -0.9961};
float array1[8+1] = {0.000 ,0.000, 0.7071, 0.8660, 1.000, 0.8660, 0.7071, 0.000, -0.7071};
float array2[8+1] = {0.000 ,-0.8660, -1, -0.8660, -0.7071, 0.0000, 0.7071, 0.8660, 1.000};
float x[8];
float y1[9] = { 0 };
float y2[9] = { 0 };
int main()
{
for(int i = 1; i <= 8; i++) {
array1[i] = array1[i] + 2.0;
//printf("%f\n", array1[i]);
}
for(int i = 1; i <= 8; i++) {
array2[i] = array2[i] + 2.0;
//printf("%f\n", array1[i]);
}
printf("IIR first order Butterworth, high-pass, cutoff 20Hz:\n");
for(int n = 1; n <= 8; n++) {
y1[n] = -1.000*a[1]*y1[n-1] + b[0]*array1[n] + b[1]*array1[n-1];
}
y2[0] = y1[8];
array2[0] = array1[8];
for(int n = 1; n <= 8; n++) {
y2[n] = -1.000*a[1]*y2[n-1] + b[0]*array2[n] + b[1]*array2[n-1];
}
printf("Array1 and Array2:\n");
for(int i = 1; i <= 8; i++) {
printf("%f, ", y1[i]);
}
for(int i = 1; i <= 8; i++) {
printf("%f, ", y2[i]);
}
return 0;
}
I tested the code with a small float input and output array with 8 + 1 elements (the one (1) is for saving the previous output) and the coefficients are generated using Matlab/Octave:
Fc = 20; % cutoff. Fs = 32000; % sampling rate. [b,a] = butter(1, Fc/(Fs/2), 'high');
After confirming the output, I pasted and modified the code to fit into the microcontroller project. Using the mentioned book as a reference [Chapter 6: Frame Based DSP], the resulting code is this in the XC32 and Bruce Land's DSP routines for the 16.16 fixed point ones:
outputData_fix16[0] = prev_output_value_fix16[0];
inputData[0] = prev_input_value[0];
for (i = 1; i <= BUFFER_LENGTH/2; i++) {
outputData_fix16[i] = multfix16(-1 * coeff_a_fp[1], outputData_fix16[i - 1]) + multfix16(coeff_b_fp[0], short2fix16(inputData[i])) + multfix16(coeff_b_fp[0], short2fix16(inputData[i]));
}
prev_output_value_fix16[0] = outputData_fix16[BUFFER_LENGTH/2];
prev_input_value[0] = inputData[BUFFER_LENGTH/2];
Coefficients:
// Fixed point coefficients for 20hz cutoff 1st order high pass Butterworth filter:
// (in 16.16 format)
fix16 coeff_b_fp[2] = { 65405, -65405 };
fix16 coeff_a_fp[2] = { 65536, -65280 };
// The same coefficients, but in floating point.
float coeff_b[2] = {0.9980, -0.9980};
float coeff_a[2] = {1.0000, -0.9961};
It works... but I gotta need to tune down the amplitude for whatever it is from the input or else the thing wraps around and make awful noises. If I have the saturate algorithm inside, it would sound less unpleasent, but I prefer to keep the audio amplitude in range.
On top of that, I have added class functionality on that filter, but it refuses to work in MPLAB Harmony. Instead, I put aside that class thingy (might be useful for anything 32-bits Arduino-related) and work on the limitations on this platform first!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.