3. 非线性误差定义:绝对误差、相对误差、引用误差,以及非线性度的计算方法

各位工程师朋友,咱们今天聊聊传感器里一个绕不开的话题——非线性误差。

说实话,我入行头三年,一直觉得传感器输出嘛,不就是电压跟被测物理量成正比?后来被现实狠狠教育了一顿。有一次做压力传感器标定,数据一出来,我盯着曲线看了半天,心里直犯嘀咕:这玩意儿怎么不是一条直线?

嗯,这就是非线性。今天我把这块掰开了讲清楚。

3.1 误差的三种基本定义

先搞清楚三个基本概念。我个人习惯把它们放在一起对比着记,不容易乱。

3.1.1 绝对误差

定义很简单:测量值减去真值

公式:
Δ = y_meas - y_true

举个例子。你测一个标准5V电压,传感器读出来是4.98V。那绝对误差就是 -0.02V。

注意:绝对误差是有正负号的。正数表示偏大,负数表示偏小。

我在项目中遇到过一件事。有次做温度传感器,绝对误差一直在 +0.5°C 左右飘。我一开始以为是电路噪声,查了两天,最后发现是ADC参考电压漂了。你看,绝对误差能帮你定位问题,但它有个缺点——没法衡量误差相对于测量范围的大小。

3.1.2 相对误差

相对误差 = 绝对误差 / 真值 × 100%

公式:
δ = (Δ / y_true) × 100%

为什么要引入相对误差?你想想看,同样是 0.1V 的绝对误差,测 100V 和测 1V,严重程度能一样吗?

测100V时,相对误差只有0.1%。测1V时,相对误差高达10%。后者基本没法用。

我的经验:做高精度测量时,我习惯同时看绝对误差和相对误差。绝对误差告诉你偏了多少,相对误差告诉你这个偏差能不能接受。

3.1.3 引用误差

这个在工业仪表里用得特别多。引用误差 = 绝对误差 / 量程 × 100%

公式:
γ = (Δ / F.S.) × 100%

其中 F.S. 是满量程(Full Scale)。

为什么不用相对误差?因为当被测值接近零时,相对误差会趋于无穷大,没法用。引用误差用固定的量程做分母,就避免了这个问题。

举个例子。一个量程 0~100°C 的温度传感器,绝对误差是 ±0.5°C。那引用误差就是 ±0.5%。

误差类型 公式 适用场景
绝对误差 Δ = y_meas - y_true 定位具体偏差
相对误差 δ = Δ / y_true × 100% 评估偏差占比
引用误差 γ = Δ / F.S. × 100% 仪表精度等级

3.2 非线性度的计算方法

好,现在进入正题。非线性度,说白了就是传感器的实际输出曲线偏离理想直线的程度。

为什么会这样?因为传感器内部物理机制往往不是完美的线性关系。比如热敏电阻的阻值-温度关系,本身就是指数型的。

3.2.1 非线性度的定义

非线性度 = 实际曲线与拟合直线之间的最大偏差 / 满量程输出 × 100%

公式:
NL = (max|y_actual - y_fit| / F.S.) × 100%

这里有个关键点:拟合直线怎么选?

常用的方法有三种:

  1. 端点连线法:把测量范围两端点连成直线。最简单,但误差可能偏大。
  2. 最小二乘法:让所有数据点到直线的距离平方和最小。最常用,我个人也最推荐。
  3. 最佳直线法:让最大偏差最小化。计算复杂,但精度最高。

避坑指南:我曾经在一个项目中用了端点连线法,结果非线性度算出来只有0.2%,感觉挺好。后来换用最小二乘法一算,实际非线性度是0.8%。为什么?因为端点刚好落在曲线上,掩盖了中间段的偏差。所以,选拟合方法一定要跟应用场景匹配

3.2.2 计算步骤

我一般按这四步走:

  1. 采集数据:在量程内均匀取 N 个点,记录输入 x_i 和输出 y_i。
  2. 拟合直线:用最小二乘法算出斜率 k 和截距 b。
  3. 计算偏差:每个点的偏差 d_i = y_i - (k × x_i + b)。
  4. 找最大偏差:d_max = max|d_i|,然后 NL = d_max / F.S. × 100%。

给你看个实际例子。我做过一个压力传感器,量程 0~10 MPa,采集了5个点:

输入 (MPa) 输出 (mV) 拟合值 (mV) 偏差 (mV)
0 0.0 0.0 0.0
2.5 25.3 25.0 +0.3
5.0 49.8 50.0 -0.2
7.5 75.1 75.0 +0.1
10.0 100.0 100.0 0.0

最大偏差是 0.3 mV,满量程输出 100 mV。非线性度 = 0.3 / 100 × 100% = 0.3%。

3.2.3 代码实现

下面是我常用的 Python 代码片段,用来计算最小二乘法拟合和非线性度:

import numpy as np

def calculate_nonlinearity(x, y):
    # 最小二乘法拟合
    A = np.vstack([x, np.ones_like(x)]).T
    k, b = np.linalg.lstsq(A, y, rcond=None)[0]
    
    # 计算拟合值
    y_fit = k * x + b
    
    # 计算偏差
    deviations = np.abs(y - y_fit)
    max_dev = np.max(deviations)
    
    # 非线性度
    fs = np.max(y) - np.min(y)
    nl = max_dev / fs * 100
    
    return nl, k, b

# 示例数据
x = np.array([0, 2.5, 5.0, 7.5, 10.0])
y = np.array([0.0, 25.3, 49.8, 75.1, 100.0])

nl, k, b = calculate_nonlinearity(x, y)
print(f"非线性度: {nl:.2f}%")
print(f"拟合直线: y = {k:.2f}x + {b:.2f}")

这段代码我用了好多年,基本没出过问题。你直接复制就能用。

3.3 知识体系结构图

下面这张图把本章的核心逻辑串起来了,方便你理解:

非线性误差知识体系 误差定义 绝对误差 相对误差 引用误差 非线性度 端点连线法 最小二乘法 计算步骤:采集数据 → 拟合直线 → 计算偏差 → 找最大偏差 → 计算非线性度 核心要点 • 绝对误差定位偏差,相对误差评估占比,引用误差定义精度等级 • 非线性度 = 最大偏差 / 满量程 × 100%,拟合方法选择影响结果

3.4 实际应用中的注意事项

最后,分享几个我踩过的坑:

  • 采样点要足够多:我曾经只取了3个点算非线性度,结果0.1%,看着很漂亮。后来取了20个点,实际是0.8%。采样点太少会漏掉中间段的偏差。
  • 注意温度影响:传感器的非线性度会随温度变化。我建议在极限温度下也测一遍。
  • 区分静态和动态:上面讲的是静态非线性度。如果传感器在快速变化信号下工作,还要考虑动态非线性度,那是另一个话题了。

我的习惯:每次拿到新传感器,第一件事就是做全量程标定,算非线性度。如果超过规格书标称值,直接退货。别问我为什么,吃过亏的人自然懂。

好了,关于非线性误差的定义和计算方法,就聊到这儿。这些概念是后续做校正的基础,你把它吃透了,后面学起来会轻松很多。


公众号:蓝海资料掘金营,微信deep3321