【Arduino】如何制作一款智能小夜灯
本篇文章主要描述如何利用 Arduino 制作智能小夜灯。智能在何处呢?主要有两处。第一,智能感应光线,只有在光线足够暗时才会亮起;第二,智能感应人体,只有当人靠近时,小夜灯才会亮起。所以,只有在环境暗淡、有人靠近时,小夜灯才会亮起。
最终的效果见下面视频。
在讲述如何制作这台小夜灯前,我们先梳理下需要准备的材料,对应的图示见下图。
-
Arduino Uno R3
-
红外人体感应传感器
-
面包板
-
光敏电阻(5528)
-
分压电阻(10KΩ,配合5528光敏电阻使用)
-
RGB LED 共阴极
-
限流电阻(100Ω - 300Ω) x 3
-
杜邦线:公对公 x 10, 公对母 x 10
电路原理
在动手之前,我们得先理解电路原理。
这张图看起来很复杂,但拆分了细看却很简单。我们将这张电路图拆分成 Arduino、光敏电阻、人体感应传感器和RGB LED 4 个部分。
Arduino
首先,Arduino 在这个电路图里充当的一个角色是电源。先看 1 号线和 2 号线(为了便于描述,这里对所有连线进行编号),1 号线连接的是 Arduino 的 5v 引脚和面包板的正极,同时 2 号线连接的是面包板的负极和 Arduino 的 GND 引脚,这样当 Arduino 通电后,便能够为面包板供电。需要注意的是,这个电路中的元器件的功耗都不高,所以可以使用 Arduino 进行供电,如果功耗比较高,则需要单独的电源模块。
光敏电阻
光敏电阻的一端通过 3 号线连接在面包板的负极,另一端通过 4 号线和 5 号线连接在 Arduino 的 A0 引脚。6 号是分压电阻,光敏电阻和分压电阻一同组成了分压电路,用来检测环境亮度。
人体感应传感器
人体感应传感器通过 7 号线和 8 号线分别连接电路的正极和负极,用来给传感器供电。9 号线连接传感器的输出引脚和 Arduino 的 8 号引脚,则传感器会将感应人体的数据输出到 Arduino 的 8 号引脚。
RGB LED
这里使用的是共阴极 RGB LED,通过 10 号线将阴极和面包板的负极相连。在 10 号线的旁边有 3 条线,分别是红、绿、蓝线,每条线连接一个限流电阻然后依次连接到 Arduino 的 6、5、3 号引脚。为什么不用 4 号引脚呢?因为 4 号引脚不是 PWM。要细细地解释 PWM 的话得费不少篇幅,简单的说就是只有 PWM 才可以调节 LED 的亮度,取值范围是 0 - 255,这样的话,通过调节 RGB LED 3 个引脚的值便可以调节 LED 的颜色。
动手组装
知道了原理之后,组装便成了件水到渠成的事情。
编写程序
完成组装搭建工作后,下面就可以编写程序了。
先帖一下整体程序。
-
#define rLedPin 6
-
#define gLedPin 5
-
#define bLedPin 3
-
#define irSensorPin 8
-
#define lightSensorPin A0
-
int ledR = 33;
-
int ledG = 150;
-
int ledB = 243;
-
bool irReading;
-
int lightReading;
-
void setup() {
-
pinMode(rLedPin, OUTPUT);
-
pinMode(gLedPin, OUTPUT);
-
pinMode(bLedPin, OUTPUT);
-
pinMode(irSensorPin, INPUT);
-
}
-
void loop() {
-
irReading = digitalRead(irSensorPin);
-
lightReading = analogRead(lightSensorPin);
-
if(irReading == HIGH && lightReading >= 500) {
-
lightOn(1);
-
} else {
-
lightOn(0);
-
}
-
delay(50);
-
}
-
void lightOn(bool on) {
-
if(on == 1) {
-
analogWrite(rLedPin, ledR);
-
delay(10);
-
analogWrite(gLedPin, ledG);
-
delay(10);
-
analogWrite(bLedPin, ledB);
-
delay(10);
-
} else {
-
analogWrite(rLedPin, 0);
-
delay(10);
-
analogWrite(gLedPin, 0);
-
delay(10);
-
analogWrite(bLedPin, 0);
-
delay(10);
-
}
-
}
上面的代码我们也拆分成 4 部分挨个解析。
宏定义与变量声明
-
#define rLedPin 6 //RGB-LED引脚R
-
#define gLedPin 5 //RGB-LED引脚G
-
#define bLedPin 3 //RGB-LED引脚B
-
#define irSensorPin 8 //红外人体感应模块信号输出
-
#define lightSensorPin A0 //光敏电阻分压电路信号输出
-
int ledR = 33; //R Led 亮度
-
int ledG = 150; //G Led 亮度
-
int ledB = 243; //B Led 亮度
-
bool irReading; //存储红外人体感应模块输出
-
int lightReading; //存储光敏电阻分压电路信号输出
前 5 行是宏定义,将 Arduino 的引脚序号使用变量表示,比如 rLedPin 表示 RGB LED 的红色引脚连接的是 Arduino 的 6 号引脚,再比如 lightSensorPin 表示光敏电阻的输出引脚连接的是 Arduino 的 A0 号引脚。
第 7 - 9 行 3 个变量分别表示 R、G、B 值。
第 11 行的变量表示从人体感应模块读取的值,第 12 行的变量表示从光敏电阻读取的光线值。
setup()函数
-
void setup() {
-
pinMode(rLedPin, OUTPUT);
-
pinMode(gLedPin, OUTPUT);
-
pinMode(bLedPin, OUTPUT);
-
pinMode(irSensorPin, INPUT);
-
}
当 Arduino 开始运行时,setup 函数会被执行一次。函数体中,第 2 - 4 行表示将 R、G、B 所连接的 Arduino 引脚设为输出模式,第 5 行将人体传感器连接的 Arduino 引脚设为输入模式。顾名思义,输出模式即 Arduino 将对外输出信号,输入模式则是 Arduino 将从该引脚获取信号。
loop()函数
-
void loop() {
-
irReading = digitalRead(irSensorPin);
-
lightReading = analogRead(lightSensorPin);
-
if(irReading == HIGH && lightReading >= 500) {
-
lightOn(1);
-
} else {
-
lightOn(0);
-
}
-
}
loop函数是个循环体,setup 函数执行后将会反复执行。
第 2 行获取人体感应模块的值,如果值等于HIGH,表示传感器感应到了人体。
第 3 行获取分压电路的光线值,如果值大于 500,表示当前的光线比较暗。
那么,下面的条件语句就好理解了,当检测到人体并且光线比较暗的话,则执行lightOn(1),其余情况执行lightOn(0)。lightOn函数我们下面细看,现在只要知道前者表示点亮 LED,后者表示熄灭 LED。
lightOn()函数
-
void lightOn(bool on) {
-
if(on == 1) {
-
analogWrite(rLedPin, ledR);
-
delay(10);
-
analogWrite(gLedPin, ledG);
-
delay(10);
-
analogWrite(bLedPin, ledB);
-
delay(10);
-
} else {
-
analogWrite(rLedPin, 0);
-
delay(10);
-
analogWrite(gLedPin, 0);
-
delay(10);
-
analogWrite(bLedPin, 0);
-
delay(10);
-
}
-
}
lightOn 函数包含一个 on 参数,当 on 等于 1 时表示点亮 LED,其他情况熄灭 LED。如何实现的呢?on 等于 1 时,Arduino 将从 rLedPin、gLedPin、bLedPin 3 个引脚分别输出值为 ledR、ledG 和 ledB 的模拟数值,这样 LED 便可以点亮了。如果这 3 个引脚都输出 0,则 LED 熄灭。
至此,一款可以同时监测人体和光线的智能小夜灯便制作完成啦~有兴趣的还可以进一步 3D 打印外壳包装,将小夜灯制成成品,因为这里只作实验学习,后续工作就不再进行啦。
--end--
声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com