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%
这里有个关键点:拟合直线怎么选?
常用的方法有三种:
- 端点连线法:把测量范围两端点连成直线。最简单,但误差可能偏大。
- 最小二乘法:让所有数据点到直线的距离平方和最小。最常用,我个人也最推荐。
- 最佳直线法:让最大偏差最小化。计算复杂,但精度最高。
避坑指南:我曾经在一个项目中用了端点连线法,结果非线性度算出来只有0.2%,感觉挺好。后来换用最小二乘法一算,实际非线性度是0.8%。为什么?因为端点刚好落在曲线上,掩盖了中间段的偏差。所以,选拟合方法一定要跟应用场景匹配。
3.2.2 计算步骤
我一般按这四步走:
- 采集数据:在量程内均匀取 N 个点,记录输入 x_i 和输出 y_i。
- 拟合直线:用最小二乘法算出斜率 k 和截距 b。
- 计算偏差:每个点的偏差 d_i = y_i - (k × x_i + b)。
- 找最大偏差: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 知识体系结构图
下面这张图把本章的核心逻辑串起来了,方便你理解:
3.4 实际应用中的注意事项
最后,分享几个我踩过的坑:
- 采样点要足够多:我曾经只取了3个点算非线性度,结果0.1%,看着很漂亮。后来取了20个点,实际是0.8%。采样点太少会漏掉中间段的偏差。
- 注意温度影响:传感器的非线性度会随温度变化。我建议在极限温度下也测一遍。
- 区分静态和动态:上面讲的是静态非线性度。如果传感器在快速变化信号下工作,还要考虑动态非线性度,那是另一个话题了。
我的习惯:每次拿到新传感器,第一件事就是做全量程标定,算非线性度。如果超过规格书标称值,直接退货。别问我为什么,吃过亏的人自然懂。
好了,关于非线性误差的定义和计算方法,就聊到这儿。这些概念是后续做校正的基础,你把它吃透了,后面学起来会轻松很多。
公众号:蓝海资料掘金营,微信deep3321