算法步骤
1. 声明变量
* notchQueue:滤波器队列
* notchData:滤波器数据
* pbuffer:滤波器延时缓存
* index:滤波器队列指针
* ctx_flag:滤波器稳定性计数器
* ctx_c_threshold:滤波器稳定性阈值
* l:滤波器队列长度
在函数开始,声明所有需要使用的变量。
2. 循环左移,插入datum
将notchQueue队列的第一个元素移出,并将datum插入到队列尾部。
3. 判断滤波器稳定性
如果相邻元素的差值的绝对值小于阈值,则认为滤波器稳定。
4. 更新滤波器数据
如果滤波器稳定,则更新滤波器数据。
计算滤波器数据:
- 将notchQueue队列中的所有元素求和
- 将notchQueue队列的第一个元素减去最后一个元素
- 将求和结果除以队列长度
更新pbuffer数据:
- 将notchQueue队列的中间元素减去滤波器数据
5. 返回滤波后的数据
#define notchFilter50hzLength 10
typedef struct
{
int flag;
int c_threshold;
float notchQueue[notchFilter50hzLength + 2];
float notchData[notchFilter50hzLength];
float pbuffer[notchFilter50hzLength];
int index;
int l = notchFilter50hzLength;
} NotchFilter_50hz_CTX;
void move_left(float *data, int n)
{
// 向左移动数据,data[0] = data[1],...
int i = 0;
for (i = 0; i < (n - 1); i++)
data[i] = data[i + 1];
}
void move_left(float *data, int n, float new_data)
{
// 向左移动数据,data[0] = data[1],...
move_left(data, n);
data[n - 1] = new_data; // 更新最后一个元素
}
// 初始化函数NotchFilter_50hz_init,用于初始化ctx变量
void NotchFilter_50hz_init(NotchFilter_50hz_CTX *ctx)
{
int *ctx_flag = &(ctx->flag);
int *ctx_c_threshold = &(ctx->c_threshold);
// 初始化ctx_c_threshold为18,ctx_flag为1
ctx->c_threshold = 18;
ctx->flag = 1;
// 初始化notchData,pbuffer,notchQueue
int i = 0;
for (i = 0; i < ctx->l; i++)
{
ctx->notchData[i] = 0;
ctx->pbuffer[i] = 0;
ctx->notchQueue[i] = 0;
}
ctx->notchQueue[ctx->l] = 0;
ctx->notchQueue[ctx->l + 1] = 0;
// 初始化index为0
ctx->index = 0;
}
float NotchFilter_50hz(NotchFilter_50hz_CTX *ctx, float datum)
{/**
函数NotchFilter_50hz用于处理50赫兹滤波器,参数ctx为上下文指针,datum为数据,channelNumber为通道号
@param ctx 上下文指针
@param datum 数据
@return 滤波后的数据
**/
// 声明变量notchQueue,notchData,pbuffer,index,ctx_flag,ctx_c_threshold
float(*notchQueue) = ctx->notchQueue;
float(*notchData) = ctx->notchData;
float(*pbuffer) = ctx->pbuffer;
int *index = &(ctx->index);
int *ctx_flag = &(ctx->flag);
int *ctx_c_threshold = &(ctx->c_threshold);
int l = ctx->l;
// 循环左移,插入datum
move_left(notchQueue, l + 1, datum);
if (*index == l - 1)
*index = 0;
// 计算两个相邻元素的差值
float DifferA = notchQueue[l - 1] - notchQueue[0];
float DifferB = notchQueue[l] - notchQueue[1];
// 如果差值的绝对值小于阈值,则认为滤波器稳定
if (fabsf(DifferA - DifferB) < (float)(*ctx_c_threshold))
{
// 滤波器稳定,重置计数器
(*ctx_flag) = (*ctx_flag) - 1;
// 如果计数器为0,则更新滤波器数据
if ((*ctx_flag) == 0)
{
// 计算滤波器数据
(*ctx_flag) = 1;
float sum = 0;
for (int i = 0; i < l; i++)
sum = sum + notchQueue[i];
float differ = notchQueue[l - 1] - notchQueue[0];
notchData[l / 2 - 1] = (sum - differ) / l;
// 更新pbuffer数据
pbuffer[*index] = notchQueue[l / 2 - 1] - notchData[l / 2 - 1];
}
else
// 滤波器数据不变
notchData[l / 2 - 1] = notchQueue[l / 2 - 1] - pbuffer[*index];
}
else // 滤波器不稳定,重置计数器
(*ctx_flag) = l - 1;
// 更新滤波器数据
notchData[l / 2 - 1] = notchQueue[l / 2 - 1] - pbuffer[*index];
// 返回滤波后的数据
float result = notchQueue[l / 2 - 1] - pbuffer[*index];
*index = *index + 1;
return result;
}