传感器过采样

通常我们认为:如果你的尺子最小刻度是 1mm,你就绝对读不出 0.1mm 的长度。 但在信号处理里,我们能! 只要你的手“抖”得够均匀。

这是一个非常反直觉,但却让电子工程师为之着迷的魔法,叫做 “过采样技术” (Oversampling)。

一、 核心原理:为什么平均能增加精度?

假设你有一个 10 位的 ADC,它的电压测量范围是 0~5V。

  • 最小刻度 (LSB): $\approx 5\text{mV}$。
  • 现状: 只要电压在 3.000V 到 3.004V 之间,ADC 读出来的数永远是 3.000V。你丢失了小数点后的精度。

1. 静态测量(失败)

如果你测一个 3.002V 的真实信号。

  • 第 1 次测:3.000V
  • 第 100 次测:3.000V
  • 平均值: 3.000V。
  • 结论: 无论你平均多少次,精度没变,还是丢失了 0.002V。

2. 动态测量(过采样成功!)

现在,我们在信号上叠加一点白噪声(或者信号本身自带噪声),让信号在 3.002V 上下抖动,抖动幅度大约 5mV。这就意味着,信号有时候会瞬间跳过 3.0025V 这个门槛(ADC 四舍五入的边界)。

  • 真实情况: 信号在抖动,有 40% 的概率跳到了 3.005V 以上(被 ADC 读作 3.005V),有 60% 的概率在下面(被 ADC 读作 3.000V)。
  • 测量 10 次的结果:
    • 3.000, 3.000, 3.005, 3.000, 3.005, 3.000, 3.005, 3.000, 3.000, 3.005
    • (6 个 3.000,4 个 3.005)
  • 算平均值:$$\frac{(6 \times 3.000) + (4 \times 3.005)}{10} = \mathbf{3.002V}$$

见证奇迹:虽然你的 ADC 每次只能读 3.000 或 3.005,但通过平均,你竟然算出了 3.002V 这个本来读不出来的数值!

这就是过采样的本质:利用噪声(抖动),把“看不见的小数位”转化为了“出现的概率”,再通过统计平均把它还原出来

二、 那个“4 倍 = 1 位”的公式是怎么来的?

这里有一个非常漂亮的数学推导(信噪比公式)。

  1. 信号 (Signal) 的累加特性:
    • 如果你把 4 个样本相加。信号是同相位的(直流或慢变信号)。
    • 总信号强度 = $4 \times S$。
  2. 噪声 (Noise) 的累加特性:
    • 白噪声是随机的(不相关)。统计学告诉我们,随机噪声相加,不是线性增加,而是按平方根增加
    • 总噪声强度 = $\sqrt{4} \times N = 2 \times N$。
  3. 信噪比 (SNR) 的变化:$$\text{新的SNR} = \frac{\text{总信号}}{\text{总噪声}} = \frac{4S}{2N} = 2 \times \frac{S}{N}$$
    • 结论: 采样次数翻 4 倍,信噪比翻 2 倍。
  4. 位数的含义:
    • 在二进制里,翻 2 倍 = 增加 1 位 (1 bit)。
    • 比如:二进制 11 (3) $\to$ 左移一位/乘 2 $\to$ 110 (6)。 最终公式: 想要增加 $w$ 位分辨率,需要的过采样倍数 $f_{os}$ 是:$$f_{os} = 4^w$$
  • 增加 1 位 (分辨率翻倍): 需要 $4^1 = 4$ 倍采样。
  • 增加 2 位 (分辨率 x4): 需要 $4^2 = 16$ 倍采样。
  • 增加 3 位 (分辨率 x8): 需要 $4^3 = 64$ 倍采样。
  • 增加 4 位 (分辨率 x16): 需要 $4^4 = 256$ 倍采样。

三、 一个必须满足的“坑”:抖动 (Dithering)

你可能注意到了,我刚才强调了一个前提:必须有噪声。如果你的信号非常非常干净,就像一潭死水,完全不抖动(或者噪声小于 0.5 LSB)。

  • 那么无论你采多少次,读数永远是固定的。平均值也变不了。
  • 这时候,过采样失效。

工程师的骚操作: 在高端仪器设计中,如果信号太干净,我们甚至会故意人为注入一点白噪声(这一步叫 Dithering / 抖动),然后再进行过采样。

  • 第一步: 加噪声(把信号弄脏)。
  • 第二步: 快速采样(捕捉概率)。
  • 第三步: 求平均(把噪声滤掉,同时提取出高精度信号)。

这就像为了把地扫干净,先把灰尘扬起来再吸走一样,听起来疯狂,但非常有效。

四、案例代码

我们可以用几行 Python 代码来验证这个“4 倍定律”。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np

# 1. 设定真实电压 (这是上帝视角,ADC不知道)
true_voltage = 3.14159  # 我们想测出小数点后5位
adc_resolution = 1.0    # ADC只能分辨整数 (0, 1, 2, 3, 4...)

# 2. 模拟单次测量 (1000次)
# 如果没有噪声,np.round(3.14159) 永远是 3.0
measurements_raw = np.round(np.full(1000, true_voltage))
print(f"单次测量平均值 (无噪声): {np.mean(measurements_raw)}")
# 结果: 3.0 (误差巨大)

# 3. 模拟过采样 (加入噪声 + 平均)
# 增加 4 位分辨率 -> 需要 4^4 = 256 倍过采样
n_samples = 256
noise_level = 0.5 # 噪声必须足够跨越量化台阶

# 进行 100 组实验
results = []
for _ in range(100):
    # 模拟采集 256 个点,每个点都带有随机噪声
    samples = true_voltage + np.random.normal(0, noise_level, n_samples)
    # 模拟 ADC 的量化过程 (强制变成整数)
    digitized_samples = np.round(samples)
    # 过采样核心:求平均
    avg_result = np.mean(digitized_samples)
    results.append(avg_result)

print(f"过采样({n_samples}倍)测量平均值: {np.mean(results):.4f}")
# 结果通常是: 3.14xx (非常接近真实值!)

程序输出

1
2
单次测量平均值 (无噪声): 3.0
过采样(256)测量平均值: 3.1372

小结

  • 过采样 (Oversampling) 是用“时间换精度”的策略。
  • 代价: 你的 ADC 速度要非常快。
    • 为了得到 1 个高精度的 10Hz 数据,你可能需要让 ADC 以 2560Hz 的速度狂奔。
  • 公式: $4^n$。每多采 4 倍,分辨率加 1 位。
  • 灵魂: 噪声 (Noise)。在这里,噪声不是敌人,而是帮我们“撬开”精度大门的助攻手。

思考🤔

这和前面讲的调制与解调非常的相似

Licensed under CC BY-NC-SA 4.0