4、数据采集入门:使用Arduino IDE读取传感器模拟信号、串口监视器查看原始数据、理解ADC转换

4.1 从传感器到数字信号:我们到底在做什么?

好,咱们正式开始动手了。前面几章讲了振动传感器的原理、选型,现在终于要让它「开口说话」了。

你想想看,传感器输出的信号是什么?是电压。比如你轻轻敲一下车架,传感器就输出一个2.3V的电压;用力砸一下,可能就跳到4.1V。但Arduino这个「大脑」不认识电压,它只认识0和1组成的数字。

所以我们需要一个翻译官——ADC(模数转换器)。说白了,就是把连续的电压值,变成离散的数字值。我个人习惯把ADC比作「一把尺子」:尺子上的刻度越密,量出来的东西就越精确。

核心概念:Arduino Uno的ADC是10位的,意味着它能将0-5V的电压范围分成2^10=1024个等级。所以读取到的数值范围是0-1023。

4.2 硬件连接:别把线插反了

先别急着写代码,咱们把物理连接搞定。我在项目中遇到过好几次学员把VCC和GND接反,结果传感器直接冒烟——嗯,那味道挺难忘的。

振动传感器(以SW-420或ADXL335为例)一般有3个引脚:

  • VCC:接Arduino的5V或3.3V(看传感器规格)
  • GND:接Arduino的GND
  • OUT(或DO/AO):模拟输出接Arduino的A0引脚

警告:千万不要把5V接到3.3V的传感器上!我曾经有个学员把5V接到了3.3V的ADXL335上,芯片直接烫手。记住:先看数据手册,再接线。

4.3 写代码:让Arduino开始「听」振动

打开Arduino IDE,新建一个文件。咱们写一个最简单的程序,让Arduino每隔100毫秒读取一次A0引脚的电压值。

void setup() {
  // 初始化串口通信,波特率设为9600
  Serial.begin(9600);
  // 设置A0为输入模式(其实默认就是输入,但写上更规范)
  pinMode(A0, INPUT);
}

void loop() {
  // 读取A0引脚的模拟值(0-1023)
  int sensorValue = analogRead(A0);
  
  // 将原始值发送到串口
  Serial.println(sensorValue);
  
  // 稍微延时一下,别刷太快
  delay(100);
}

这段代码很简单,但有几个细节我想强调一下:

  • analogRead()返回的是0-1023的整数,不是电压值
  • Serial.println()会在末尾加换行,方便在串口监视器里看
  • delay(100)控制采样频率,太快了串口会卡死

4.4 串口监视器:你的第一双「数字眼睛」

代码写好了,点击上传。上传成功后,点击Arduino IDE右上角的「串口监视器」按钮(那个放大镜图标)。

你会看到什么?一串数字在疯狂滚动:

512
513
511
789
1023
512
511
...

为什么会这样?当你静止不动时,传感器输出一个稳定的中间值(比如512左右)。当你敲击桌面时,数值会突然跳高(比如跳到1023),然后迅速回落。

小技巧:在串口监视器右下角选择「9600波特」,和代码里的Serial.begin(9600)保持一致。如果选错了,你会看到一堆乱码——别慌,改回来就行。

4.5 理解ADC转换:从电压到数字的「翻译过程」

咱们刚才看到的512、1023这些数字,到底对应多少电压?

公式很简单:

电压值 = (读取值 / 1023) × 参考电压

比如Arduino Uno的参考电压默认是5V,那么读取到512时,实际电压就是:

512 / 1023 × 5V ≈ 2.5V

读取到1023时,电压就是5V(满量程)。

咱们可以改一下代码,直接输出电压值:

void loop() {
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.0);
  
  Serial.print("原始值: ");
  Serial.print(sensorValue);
  Serial.print("  电压: ");
  Serial.println(voltage);
  
  delay(100);
}

现在串口监视器里会显示类似这样的内容:

原始值: 512  电压: 2.50
原始值: 789  电压: 3.86
原始值: 1023 电压: 5.00

重要理解:ADC的精度取决于位数。10位ADC(0-1023)对于检测「有没有振动」完全够用。但如果你要分析振动的细微波形(比如轴承磨损),可能需要12位甚至16位的ADC。我在做共享单车项目时,10位ADC足够判断「车被推走了」还是「车被砸了」。

4.6 避坑指南:我踩过的那些坑

做数据采集这么多年,有些坑我替你们踩过了:

  • 参考电压不稳定:Arduino的5V引脚如果供电不足,参考电压会漂移。我建议用analogReference(INTERNAL)切换到内部1.1V参考,更稳定。
  • 采样频率太快:analogRead()一次大约需要100微秒。如果你不加delay(),串口会瞬间被数据淹没。我曾经试过不加延时,结果串口监视器直接卡死。
  • 信号抖动:传感器在静止时,数值也会在小范围内波动(比如510-514)。这是正常的,别以为是传感器坏了。可以在代码里加一个「死区」判断,比如变化超过10才认为有振动。

4.7 动手试试:让数据「动」起来

现在你可以做个小实验:

  1. 把传感器放在桌面上,记录静止时的数值范围
  2. 用手指轻轻敲击桌面,观察数值如何变化
  3. 用力拍一下桌面,看看最大值能到多少
  4. 试试不同材质的表面(木板、金属、塑料),数值变化有什么不同?

你会发现,振动越强,数值波动越大。这就是我们后续做「振动强度分析」的基础。

我的经验:在共享单车项目里,我们通过分析振动信号的「峰值」和「频率」,就能判断出是「正常骑行」还是「暴力拆车」。这些原始数据,就是一切算法的基础。

4.8 本章小结

今天我们做了三件事:

  • 用Arduino读取了传感器的模拟信号
  • 通过串口监视器看到了原始数据
  • 理解了ADC是如何把电压变成数字的

下一章,我们会把这些原始数据保存下来,用Excel或者Python画成波形图。到时候你就能「看见」振动了——那感觉,挺奇妙的。

记住:数据采集是物联网的「眼睛」。眼睛不好使,后面再牛的算法也白搭。所以,把今天的内容吃透,别急着往下赶。