I am working on a STM32F446RE project. I sense a sinewave of 50 Hz in ADC (alpha) and I want to create an identical sinewave as the first one but shifted by 90 degrees (beta).
I tried to implement it with two methods. The one that works better is with Hilbert:
#define M 63 // filter order
float hilbert_coeffs[M+1];
void init_hilbert_coeffs() {
for (int i = 0; i <= M; i++) {
if (i == M/2) {
hilbert_coeffs[i] = 0.0;
} else {
float n = i - M/2;
hilbert_coeffs[i] = 1.0/(M_PI*n);
}
}
}
float hilbert_filter(float x) {
static float x_buffer[M+1];
static int x_buffer_index = 0;
float y = 0.0;
x_buffer[x_buffer_index] = x;
for (int i = 0; i <= M; i++) {
y += hilbert_coeffs[i]*x_buffer[(x_buffer_index+i)%(M+1)];
}
x_buffer_index = (x_buffer_index + 1) % (M+1);
return y;
}
The problem is that the higher the order of the filter, the worse the signal becomes. For a 90 degree shift the order should be 63, but the signal gets chunky and the magnitude gets a bit bigger. For example: I want this: sine
And with Hilbert I get this: hilebrt_sine
If I use lower order filter then I don't have 90 degrees phase shift. I the other method that I tried was with storing the first sinewave and use mod: beta = alpha_LUT[(i + (NS/4)) % NS]; where NS are the elements of the array. But I want to avoid storing the alpha signal because I sense it in real time and use alpha and beta for another process (alpha-beta to dq0).
Do you know any alternatives to how I can achieve this?
Thank you!