在做的项目中需要通过PWM驱动IGBT来控制负载功率,如果PWM频率很高,电流采样基本不受影响。但是IGBT的开关频率高会引起更多的开关损耗,所以降低了PWM频率,但此时电流会是接近于PWM信号的波形,无法准确采集。所以硬件上增加了RC低通滤波,截止频率在5Hz以下,然后软件上通过低通滤波算法进一步将电流拉平。
实测在ADC 1K的采样频率下,电流采样滞后在600ms以内。
下面是C#的实现代码
// 定义低通滤波器的结构体
struct LowPassFilter
{
public float alpha; // 滤波器系数
public float previousOutput; // 上一次的输出值
};
// 初始化或更新低通滤波器的函数
void updateLowPassFilter(out LowPassFilter filter, float cutoffFrequency, float sampleRate)
{
// 计算时间常数 tau
float tau = 1.0f / (2.0f * 3.1415926f * cutoffFrequency);
// 计算采样周期 T
float T = 1.0f / sampleRate;
// 计算滤波器系数 alpha
filter.alpha = T / (T + tau);
//filter.alpha = 1.0f / (1 + tau * sampleRate);//这一行其实上面两行推导出来的
filter.previousOutput = 0.0f; // 可以选择重置上一次的输出
}
// 处理低通滤波器的函数
float processLowPassFilter(LowPassFilter filter, float input)
{
// 根据IIR低通滤波器的公式计算当前输出
float output = filter.alpha * input + (1.0f - filter.alpha) * filter.previousOutput;
// 更新上一次的输出值
filter.previousOutput = output;
// 返回当前的输出值
return output;
}
函数调用:
float Value = 0;
private void button1_Click(object sender, EventArgs e)
{
LowPassFilter filter1 = new LowPassFilter();
LowPassFilter filter2 = new LowPassFilter();
Random random = new Random();
int Cnt = 0;
int Cnt_2 = 0;
float Cnt_3 = 50;
float sampleRate = 1000; // 示例采样率
float outputSignal_1 = 0;
float outputSignal_2 = 0;
// 初始化滤波器,设置截止频率
updateLowPassFilter(out filter1, 1, sampleRate); // 1Hz截止频率 // 改变截止频率
updateLowPassFilter(out filter2, 1, sampleRate * 10); // 改变截止频率为10Hz
while (Cnt <= 12000)
{
Cnt++;
//delayUs(100);//假装延时100us,模拟单片机的采样间隔
Cnt_2++;
if (Cnt_2 >= 100)
{
Cnt_2 = 0;
//Cnt_3 = 50 + random.Next(-40,40);
Cnt_3 -= 0.5f;
}
if (Cnt_2 >= Cnt_3)//模拟不同占空比的PWM
{
Value = 8.5f + (float)random.NextDouble() / 10.0f;
}
else
{
Value = 1.5f + (float)random.NextDouble() / 10.0f;
}
if (Cnt_2 % 10 == 0)
{
outputSignal_1 = processLowPassFilter(filter1, Value);
filter1.previousOutput = outputSignal_1;
}
outputSignal_2 = processLowPassFilter(filter2, Value);
filter2.previousOutput = outputSignal_2;
this.chart1.Series[0].Points.AddY(Value);
this.chart1.Series[1].Points.AddY(outputSignal_1);
this.chart1.Series[2].Points.AddY(outputSignal_2);
}
}
运行效果图:
可以看到滤波器2的曲线响应速度是快于滤波器1的,也就是采样速度越快,越精确,响应越快