Skip to content

Arduino - 读取模拟电压

虽然 Arduino 运行在 HIGH 和 LOW 的数字世界中,但现实世界是模拟的。测量温度、光照或位置的传感器通常会产生连续变化的电压。本教程解释了如何使用 Arduino 的模数转换器 (ADC) 读取这些模拟信号,并将其转换为有意义的数据。

ADC 是微控制器上的一个外设,它将模拟电压转换为数字。主要概念包括:

  • 分辨率: Arduino UNO 具有 10 位 ADC。这意味着它可以用 2^10 = 1024 个不同的步长来表示模拟电压,编号从 0 到 1023。
  • 参考电压 (AREF): 这是 ADC 可以测量的最大电压。默认情况下,它是开发板的工作电压(UNO 上为 5V)。读数为 0 对应 0V,读数为 1023 对应 5V。

analogRead(pin) 函数执行此转换并返回 0 到 1023 之间的整数值。

电位器是一种可变电阻器,可作为完美的电压分压器,使其成为演示模拟输入的绝佳工具。通过旋转其旋钮,我们可以向模拟引脚提供 0V 到 5V 之间的可变电压。

  • 1 × Arduino UNO R3 或兼容开发板
  • 1 × 10kΩ 电位器
  • 跳线
// 电位器有3个引脚。
// 将两个外部引脚连接到电源和地。
// 中心引脚(“滑动端”)是输出电压。
Potentiometer Outer Pin 1 --- Arduino 5V
Potentiometer Outer Pin 2 --- Arduino GND
Potentiometer Center Pin --- Arduino Analog Pin A0

此草图从引脚 A0 读取原始 ADC 值,将其转换为浮点电压,并将结果打印到串口监视器。

/**
* @文件 read_analog_voltage.ino
* @简介 读取模拟输入,将其转换为电压,并打印。
* @作者 现代化教程
*/
// 连接电位器的模拟引脚。
constexpr int ANALOG_IN_PIN = A0;
// ADC 的参考电压。在大多数 Arduino 上,这是 5.0V。
constexpr float REFERENCE_VOLTAGE = 5.0;
void setup() {
// 初始化串口通信以显示结果。
Serial.begin(9600);
}
void loop() {
// 从 ADC 读取原始整数值 (0-1023)。
int sensorValue = analogRead(ANALOG_IN_PIN);
// 将 ADC 读数转换为电压值。
// 公式为:电压 = (ADC_读数 / ADC_分辨率) * 参考电压
// 对于 10 位 ADC,分辨率是 1023。
float voltage = (sensorValue / 1023.0) * REFERENCE_VOLTAGE;
// 将结果打印到串口监视器。
Serial.print("原始传感器值:");
Serial.print(sensorValue);
Serial.print("\t | 电压:");
Serial.print(voltage);
Serial.println(" 伏特");
// 使用串口绘图器 (工具 > 串口绘图器) 获取图形视图!
delay(100); // 在下次读取前等待一小段时间。
}

模拟读数有时会因为电气干扰或不稳定的电源而出现“噪声”或不稳定。解决此问题的一个常见技术是进行多次读取并取其平均值。这被称为平滑或滤波。

此代码修改会连续读取传感器多次,并对结果取平均值以产生更稳定的输出。

// --- 将此代码添加到你的 loop() 中以进行平滑处理 ---
const int NUM_READINGS = 10; // 要平均的样本数
long total = 0;
for (int i = 0; i < NUM_READINGS; i++) {
total += analogRead(ANALOG_IN_PIN);
delay(1); // 每次读取之间的小延迟
}
int sensorValue = total / NUM_READINGS; // 计算平均值
// ... 其余的电压转换和打印代码紧随其后

如果你正在测量一个只输出小电压范围(例如 0-1.1V)的传感器,使用默认的 5V 参考电压是低效的。你可以通过使用 analogReference() 将参考电压更改为较低的值来获得更精确的读数。对于 UNO,你可以选择 INTERNAL (1.1V) 或通过 AREF 引脚提供外部参考电压。

void setup() {
Serial.begin(9600);
// 使用内部 1.1V 参考。
// 重要提示:使用此功能时,请勿将任何东西连接到 AREF 引脚!
// 切勿使用低于 0V 或高于 5V 的外部参考电压。
analogReference(INTERNAL);
}
// 在你的 loop 中,请记住在电压计算中使用 1.1!
// float voltage = (sensorValue / 1023.0) * 1.1;