Arduino传感器滤波算法

1.开发环境

ESP-12F、Arduino、INA226传感器检测电压

2.滑动均值滤波

// 滑动均值滤波
float slideFilter(const float Z)
{
    static const int N = 8;
    static float filterBuff[N];
    static int num = 0;
    static float sum = 0.0;

    if (num < N)
    {
        filterBuff[num] = Z;
        sum += filterBuff[num];
        num++;
        return sum / num;
    }
    else
    {
        sum -= sum / N;
        sum += Z;
        return sum / N;
    }
}

3.一阶互补滤波

// 一阶互补滤波
float firstOrderFilter(const float Z)
{
    static const float alpha = 0.7;
    static float prevData = Z;
    float filterValue = Z * alpha + (1 - alpha) * prevData;
    prevData = filterValue;
    return filterValue;
}

4.卡尔曼滤波

// 卡尔曼滤波
float kalmanFilter(float Z)
{
    static float K = 0;            // 卡尔曼增益
    static float P = 1;            // 估计误差协方差
    static const float Q = 0.0025; // 过程噪声协方差,值增大,动态响应变快,收敛稳定性变差,  Q控制误差,R控制响应速度
    static const float R = 0.2;    // 测量噪声协方差,传感器产生的噪声,值增大,动态响应变慢,收敛稳定性变好
    static float prevData = 0;

    P = P + Q;
    K = P / (P + R);
    Z = prevData + K * (Z - prevData);
    P = (1.0 - K) * P;
    prevData = Z;
    return Z;
}

5.中值滤波 

// 中值滤波
float medianFilter(const float Z)
{
    static const int N = 9;
    static float filterBuff[N];
    for (int i = 0; i < N; i++)
    {
        filterBuff[i] = Z;
    }
    // 将采样值从小到大排序(冒泡排序算法)
    bubbleSort(filterBuff, N);
    return filterBuff[(N - 1) / 2];
}

// 冒泡排序
void bubbleSort(float arr[], int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        bool flag = true; // 没有排序为true,本趟有排序为false
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                flag = false;
                float temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if (flag)
        {
            break;
        }
    }
}

6.完整程序

// 传感器滤波算法测试
#include <Arduino.h>
#include <INA226.h>
#include <Wire.h>

INA226 battery(0x44); // 对象实例化

void initINA226(); // 采样电阻设置0.01,最大电流8A
void ArduinoSheet();
void VofaDebug();

float slideFilter(const float Z);      // 滑动均值滤波算法
float firstOrderFilter(const float Z); // 一阶低通滤波
float kalmanFilter(float Z);           // 卡尔曼滤波
float medianFilter(const float Z);     // 中值滤波
void bubbleSort(float arr[], int n);   // 冒泡排序

int rowNumber = 0;
const int rowCount = 500; // 统计500个数据

void setup()
{
    Serial.begin(115200);
    Wire.begin();
    initINA226();
}

void loop()
{
    // // 记录传感器数据
    // ArduinoSheet();

    // 采用Vofa+进行调试
    VofaDebug();
}

void initINA226()
{
    battery.setMaxCurrentShunt(8, 0.01);
}

/*********************************************************************************************/
void ArduinoSheet()
{
    if (rowNumber < rowCount)
    {
        float initData = battery.getBusVoltage();
        float filterData1 = slideFilter(initData); // 滑动均值滤波
        Serial.print(rowNumber++);                 // 行号
        Serial.print(',');
        Serial.print(initData); // 原始数据
        Serial.print(',');
        Serial.println(filterData1);
    }
}

void VofaDebug()
{
    float initData = battery.getBusVoltage();
    float filterData1 = slideFilter(initData);      // 滑动均值滤波
    float filterData2 = firstOrderFilter(initData); // 一阶互补滤波
    float filterData3 = kalmanFilter(initData);     // 卡尔曼滤波
    float filterData4 = medianFilter(initData);     // 中值滤波
    Serial.printf("%f,%f,%f,%f,%f\n", initData, filterData1, filterData2, filterData3, filterData4);
}

/*********************************************************************************************/

// 滑动均值滤波
float slideFilter(const float Z)
{
    static const int N = 8;
    static float filterBuff[N];
    static int num = 0;
    static float sum = 0.0;

    if (num < N)
    {
        filterBuff[num] = Z;
        sum += filterBuff[num];
        num++;
        return sum / num;
    }
    else
    {
        sum -= sum / N;
        sum += Z;
        return sum / N;
    }
}

// 一阶互补滤波
float firstOrderFilter(const float Z)
{
    static const float alpha = 0.7;
    static float prevData = Z;
    float filterValue = Z * alpha + (1 - alpha) * prevData;
    prevData = filterValue;
    return filterValue;
}

// 卡尔曼滤波
float kalmanFilter(float Z)
{
    static float K = 0;            // 卡尔曼增益
    static float P = 1;            // 估计误差协方差
    static const float Q = 0.0025; // 过程噪声协方差,值增大,动态响应变快,收敛稳定性变差,  Q控制误差,R控制响应速度
    static const float R = 0.2;    // 测量噪声协方差,传感器产生的噪声,值增大,动态响应变慢,收敛稳定性变好
    static float prevData = 0;

    P = P + Q;
    K = P / (P + R);
    Z = prevData + K * (Z - prevData);
    P = (1.0 - K) * P;
    prevData = Z;
    return Z;
}

// 中值滤波
float medianFilter(const float Z)
{
    static const int N = 9;
    static float filterBuff[N];
    for (int i = 0; i < N; i++)
    {
        filterBuff[i] = Z;
    }
    // 将采样值从小到大排序(冒泡排序算法)
    bubbleSort(filterBuff, N);
    return filterBuff[(N - 1) / 2];
}

// 冒泡排序
void bubbleSort(float arr[], int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        bool flag = true; // 没有排序为true,本趟有排序为false
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                flag = false;
                float temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if (flag)
        {
            break;
        }
    }
}

  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值