传感器读取
给 Arduino 装上"感官":光敏电阻感光、DHT11 测温湿度、超声波量距离、PIR 探人体。
给 Arduino 装上"感官":光敏电阻感光、DHT11 测温湿度、超声波量距离、PIR 探人体。
analogRead 读。数字传感器输出高/低电平或按协议(单总线/I2C)传数据(如 DHT11、PIR、超声波),用 digitalRead 或专用库读。买传感器先看它是哪种输出。#include 头文件、创建对象、调 readTemperature() 之类的高层函数即可拿到结果,不必手撕时序。第 2 章学过用库管理器安装。光敏电阻要和一个 10kΩ 电阻串联成分压器,中间节点接 A0:
// 光控夜灯:暗了自动开灯 const int ldrPin = A0; const int ledPin = 13; const int THRESHOLD = 300; // 阈值,需按实际环境调 void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); } void loop() { int light = analogRead(ldrPin); Serial.println(light); if (light < THRESHOLD) { // 光弱 → 天黑 digitalWrite(ledPin, HIGH); // 开灯 } else { digitalWrite(ledPin, LOW); } delay(100); }
// 采样 10 次取平均,读数更稳 int readAveraged(int pin, int times) { long sum = 0; for (int i = 0; i < times; i++) { sum += analogRead(pin); delay(2); // 每次采样间隔一点点 } return sum / times; }
DHT11 用单总线协议,靠库读取。先在库管理器装 "DHT sensor library"(Adafruit)。DATA 脚接 D2,接一个 10kΩ 上拉到 5V(部分模块已内置)。
#include <DHT.h> #define DHTPIN 2 // DATA 接 D2 #define DHTTYPE DHT11 // 型号:DHT11 或 DHT22 DHT dht(DHTPIN, DHTTYPE); // 创建传感器对象 void setup() { Serial.begin(9600); dht.begin(); } void loop() { delay(2000); // DHT11 至少间隔 1 秒,稳妥用 2 秒 float h = dht.readHumidity(); // 读湿度 % float t = dht.readTemperature(); // 读温度 ℃ // 读取失败会返回 NaN,必须检查 if (isnan(h) || isnan(t)) { Serial.println("读取 DHT 失败!"); return; } Serial.print("温度: "); Serial.print(t); Serial.print(" C 湿度: "); Serial.print(h); Serial.println(" %"); }
返回 NaN 通常是:① 读取太频繁(DHT11 需 ≥1s 间隔);② DATA 脚没接上拉电阻;③ 型号选错(DHT11 vs DHT22);④ 接线松动。务必用 isnan() 判断再使用数据,否则拿 NaN 去计算或显示会出错。
无需库,用 pulseIn 测回波时间即可换算距离:
// HC-SR04 超声波测距(厘米) const int trigPin = 9; const int echoPin = 10; void setup() { Serial.begin(9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } float measureCm() { // 发一个 10μs 触发脉冲 digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // 测量 Echo 高电平持续时间(μs),超时 30ms 防卡死 long duration = pulseIn(echoPin, HIGH, 30000); if (duration == 0) return -1; // 超时/超量程 return duration * 0.034 / 2; // 换算成 cm } void loop() { float cm = measureCm(); if (cm < 0) { Serial.println("超出量程"); } else { Serial.print(cm); Serial.println(" cm"); } delay(200); }
pulseIn(pin, HIGH) 会阻塞等待引脚变高,然后测量它保持高电平的微秒数直到变低。第三个参数是超时(μs),务必设置(如 30000),否则障碍物太远收不到回波时程序会一直卡在这里。
最简单的数字传感器,检测到人就输出高电平:
// PIR 检测到人就亮灯并打印 const int pirPin = 3; // PIR 输出接 D3 const int ledPin = 13; void setup() { Serial.begin(9600); pinMode(pirPin, INPUT); pinMode(ledPin, OUTPUT); } void loop() { if (digitalRead(pirPin) == HIGH) { digitalWrite(ledPin, HIGH); Serial.println("检测到有人!"); } else { digitalWrite(ledPin, LOW); } delay(100); }
| 传感器 | 测量量 | 输出类型 | 读取方式 | 需要库 |
|---|---|---|---|---|
| 光敏电阻 LDR | 光照强度 | 模拟(分压) | analogRead | 否 |
| 热敏电阻 NTC | 温度 | 模拟(分压) | analogRead+公式 | 否 |
| DHT11/22 | 温度+湿度 | 数字(单总线) | 库函数 | 是(DHT) |
| HC-SR04 | 距离 | 数字(脉宽) | pulseIn | 否 |
| PIR | 人体运动 | 数字(电平) | digitalRead | 否 |
| MPU6050 | 加速度/陀螺仪 | 数字(I2C) | 库函数 | 是 |
传感器供电看清是 3.3V 还是 5V(有的模块两者兼容)。所有传感器的 GND 必须和 Arduino 的 GND 相连(共地),否则电平没有共同参考,读数全乱。多个模块用外部电源时,外部电源负极也要和 Arduino GND 相连。
传感器是 Arduino 感知世界的入口,分两类:模拟传感器输出连续电压(光敏、热敏电阻,需组分压电路用 analogRead 读),数字传感器输出电平或按协议传数据(用 digitalRead 或专用库)。光敏电阻+10kΩ 分压做光控夜灯;读数抖动用"多次采样取平均"简单滤波。DHT11/22 走单总线协议,装 DHT 库后 readTemperature/readHumidity 即可,读取间隔 ≥1s,失败返回 NaN 要用 isnan() 判断。HC-SR04 超声波无需库:Trig 发 10μs 脉冲,用 pulseIn(带超时)测 Echo 高电平时长,距离 = 时长 × 0.034 / 2。PIR 是最简单的数字传感器,检测到人输出高电平直接 digitalRead。复杂传感器优先找现成库省去手撕时序。铁律:看清供电电压,所有传感器必须与 Arduino 共地。