本文档只讲一件事:怎么把线接对。所有接线在 Arduino Uno(或兼容板)上验证过。
┌─────────────────────┐
┌─────────────┤ Arduino Uno R3 ├─────────────┐
│ └─────────────────────┘ │
│ │
LCD1602 I2C DHT11
GND → GND VCC → 5V
VCC → 5V GND → GND
SDA → A4 DATA→ D7
SCL → A5
LED
按键 LED1: D9 → 220Ω → GND
D2 ──┐ LED2: D8 → 220Ω → GND
GND ─┘
HC-05
VCC → 5V ⚠️ 仅供 3.6~6V,模块底板已带稳压
GND → GND
TX → D10 ← 交叉连接!
RX → D11 ← 交叉连接!
| 外设 | 引脚 | 接到 Arduino | 备注 |
|---|---|---|---|
| LCD1602 (I2C) | GND | GND | |
| VCC | 5V | ||
| SDA | A4 | Uno 上 A4 是硬件 I2C 的 SDA,不能随意换 | |
| SCL | A5 | Uno 上 A5 是硬件 I2C 的 SCL | |
| HC-05 | VCC | 5V | 模块底板自带 3.3V LDO,直连 5V 安全 |
| GND | GND | ||
| TXD | D10 | 蓝牙发 → Arduino 收(即软串口的 RX) | |
| RXD | D11 | 蓝牙收 ← Arduino 发(即软串口的 TX) | |
| DHT11 | VCC | 5V | 模块版红灯须常亮 |
| GND | GND | ||
| DATA | D7 | 与代码中 #define DHTPIN 7 对应 |
|
| 光敏模块 DO | GND | GND | |
| VCC | 5V | 模块上的蓝色电位器用于调节触发阈值 | |
| DO | D4 | 数字输出。暗时输出 HIGH(与常见直觉相反,见 2.4) | |
| 声音模块 I/O | GND | GND | |
| VCC | 5V | 灵敏度由模块上的电位器调节 | |
| I/O | D5 | 数字输出。有声时输出 LOW | |
| 蜂鸣器 I/O | GND | GND | |
| VCC | 5V | 有源蜂鸣器,自带振荡电路 | |
| I/O | D3 | 低电平触发发声,高电平停止 | |
| LED 1 | 阳极 | D9 | 必须串 220Ω 限流电阻 |
| 阴极 | GND | ||
| LED 2 | 阳极 | D8 | 必须串 220Ω 限流电阻 |
| 阴极 | GND | ||
| 按键 | 一端 | D2 | 代码启用 INPUT_PULLUP |
| 另一端 | GND | 按下读到 LOW |
这是新手第一坑。同名相接是错的:
| ❌ 错误接法 | ✅ 正确接法 |
|---|---|
| 蓝牙 TX → D11 | 蓝牙 TX → D10 |
| 蓝牙 RX → D10 | 蓝牙 RX → D11 |
记忆方法:SoftwareSerial BT(10, 11) 的第一个参数是 Arduino 的接收脚,所以要接对方的发送脚。
接反的典型症状:串口能收到数据,但全是 FFFF / C7 / 80 之类的乱码,或者完全收不到。
直接把 LED 跨接在 D9 和 GND 之间,短时间可能看起来正常,但长时间运行会烧毁 LED,甚至损伤 ATmega328P 的 IO 口(单脚安全电流上限约 20mA)。
- 220Ω → 约 15mA,亮度足够且安全
- 330Ω → 约 10mA,更保守
- 1kΩ → 约 3mA,很暗但可用
判断 LED 极性:长脚是阳极(+),短脚是阴极(−);或看灯珠内部,小的一侧是阳极。
I2C 转接板上那颗蓝色小电位器控制 V0 对比度。
- 背光亮、但屏幕一片空白 → 电位器位置不对,缓慢来回旋转直到字符出现
- 屏幕显示一排黑方块 → 也常是对比度过头
- 这是「背光亮但无显示」问题中最容易被忽略的原因,很多人直接怀疑代码或地址
光敏、声音、蜂鸣器这三个模块的电平逻辑正好和直觉相反,接错或理解错会导致「灯一直亮」「蜂鸣器一直响」:
| 模块 | 引脚 | 有效电平 | 实物现象 | 代码里的判断 |
|---|---|---|---|---|
| 光敏模块 | DO | HIGH = 暗 | 遮住光敏电阻时 DO 变高 | if (lightState == HIGH) → "Dark" |
| 声音模块 | I/O | LOW = 有声 | 拍手时 I/O 被拉低 | if (digitalRead(soundPin) == LOW) |
| 蜂鸣器模块 | I/O | LOW = 发声 | 给低电平才响 | digitalWrite(buzzerPin, LOW) 发声 |
为什么蜂鸣器是低电平触发? 这类「低电平触发」模块内部用 PNP 三极管(或 P-MOS)做开关:I/O 悬空或高电平时三极管截止,蜂鸣器不响;I/O 被拉低的瞬间三极管导通,蜂鸣器得电发声。所以初始化时必须先写 HIGH 关闭它,否则上电瞬间会「嘀」一声甚至持续作响:
pinMode(buzzerPin, OUTPUT);
digitalWrite(buzzerPin, HIGH); // 初始化时先关闭蜂鸣器光敏模块为什么 HIGH 表示暗? DO 输出来自模块上的电压比较器。光敏电阻光照越强、阻值越小,分压后的电压随之变化;比较器把这个电压与电位器设定的阈值比较后输出高低电平。不同厂家的模块分压位置可能相反,所以不要死记,用实测验证:遮住光敏电阻看串口/屏幕显示是 Dark 还是 Bright,如果反了就反转代码里的判断,或旋转电位器跨过阈值。
上传以下程序(或使用 IDE 自带示例 文件 → 示例 → Wire → i2c_scanner),打开串口监视器(9600 波特率):
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("I2C Scanner starting...");
}
void loop() {
byte error, address;
int nDevices = 0;
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
nDevices++;
}
}
if (nDevices == 0) Serial.println("No I2C devices found - check wiring!");
delay(5000);
}预期输出:
I2C device found at address 0x27
把扫到的地址填进代码:
LiquidCrystal_I2C lcd(0x27, 16, 2); // ← 改成你扫到的地址| 常见地址 | 说明 |
|---|---|
0x27 |
PCF8574T,最常见 |
0x3F |
PCF8574AT,也很常见 |
0x20 |
PCF8574(无背光跳线的裸芯片) |
💡 扫描不到任何设备时:检查 A4/A5 是否插反、SDA/SCL 是否插到了数字口(插到 D4/D5 是搜不到的)、LCD 是否供电。
项目最早不知道怎么用 I2C,直接用 LiquidCrystal 库跑并行 4 位模式。引脚占用多,且与蓝牙软串口冲突,仅作学习记录保留。
| LCD1602 引脚 | Arduino 引脚 | 说明 |
|---|---|---|
| VSS (1) | GND | 地 |
| VDD (2) | 5V | 电源 |
| V0 (3) | 电位器中间脚 | 对比度 |
| RS (4) | D12 | 寄存器选择 |
| RW (5) | GND | 只写模式 |
| E (6) | D11 | 使能 |
| D4 (11) | D5 | 数据位 4 |
| D5 (12) | D4 | 数据位 5 |
| D6 (13) | D3 | 数据位 6 |
| D7 (14) | D2 | 数据位 7 |
| A (15) | 5V(串 220Ω) | 背光正极 |
| K (16) | GND | 背光负极 |
对应代码:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7
lcd.begin(16, 2);| 对比项 | 并行 4 位 | I2C 转接板 |
|---|---|---|
| 占用 IO 口 | 6 个 | 2 个(A4/A5) |
| 杜邦线数量 | 12 根 | 4 根 |
| 与蓝牙软串口冲突 | 是(抢 D10/D11) | 否 |
| 接线出错概率 | 高 | 低 |
| 成本 | 低 | 多一块转接板 |
这次升级是本项目的第一个重要工程决策:不追求「能用就行」,而是主动消除接线复杂度和引脚冲突。用 2 个 IO 换回 4 个可用 IO,同时让蓝牙方案成为可能。
┌──────────────────── 面包板 ────────────────────┐
│ [+ 电源轨] ─────────────────────── 5V ─────── │
│ [− 地轨] ─────────────────────── GND ─────── │
│ │
│ [DHT11] [LED1] [LED2] [按键] │
│ ○ ○ ○ ○ ○ ○ ○ ○ ○ │
│ │ │ │ │ │ │ │ │ │ │
│ VCC G DATA D9 GND D8 GND D2 GND │
│ │
│ [LCD1602 I2C 转接板] [HC-05 底板] │
│ ○ ○ ○ ○ ○ ○ ○ ○ │
│ G V S S V G T R │
│ N C D C C N X X │
│ D C A L 5 D D │
│ │ │ 10 11 │
└───────────────────┼──────────────┼────────────┘
│ │
A4/A5 D10/D11
实用建议:
- 两个 LED 之间留出间距,方便观察交替闪烁效果
- DHT11 尽量远离 LED 和电源走线,减少读数干扰
- HC-05 天线端(模块顶部波浪形区域)不要贴近金属物体或面包板电源轨,会明显缩短通信距离
- 供电:HC-05 配对瞬间瞬态电流较大,建议从 Arduino 的 5V 引脚直接取电,必要时并联 100µF 电容
上传代码后按顺序确认:
- Arduino 板载 LED(D13)在复位时闪烁 → 程序在跑
- LCD 背光亮 → 供电正常
- LCD 出现文字 → I2C 地址和对比度正确
- DHT11 模块红灯常亮 → 传感器已供电
- 上电瞬间蜂鸣器不响 → 说明
digitalWrite(buzzerPin, HIGH)生效、低电平触发接线正确 - HC-05 底板 LED 快闪 → 未连接,可被搜索
- HC-05 底板 LED 慢闪(约 2 秒一次) → 已连接,可发指令
- 发送
1→ LED 亮、LCD 显示LED: ON、蜂鸣器提示一声 - 发送
2→ 双灯交替跳动,且期间发送其它指令仍有响应(验证非阻塞) - 发送
3→ LCD 显示中秋祝福,蜂鸣器响三声 - 发送
L→ 用手机手电筒照/遮住光敏电阻,屏幕在Status: Bright与Status: Dark间切换,暗时自动开灯 - 发送
T→ 屏幕显示温湿度,手机端同时收到Temp: ..C, Humi: ..% - 发送
B→ 蜂鸣器急促响三声 - 对声音模块拍手 → 蜂鸣器提示、LED 闪三下、手机收到
>> Sound Detected! <<,且不会连续响个不停(验证自激抑制生效) - 按物理按键 → 灯态切换、LCD 同步刷新、蜂鸣器提示音
全部通过,说明接线 100% 正确 ✅
⚠️ 最后两项(声音触发不自激、非阻塞闪烁)是最容易失败的,若异常请直接查 TROUBLESHOOTING.md。