【Arduino】如何制作一款智能小夜灯

网友投稿 2019-12-12 11:35

本篇文章主要描述如何利用 Arduino 制作智能小夜灯。智能在何处呢?主要有两处。第一,智能感应光线,只有在光线足够暗时才会亮起;第二,智能感应人体,只有当人靠近时,小夜灯才会亮起。所以,只有在环境暗淡、有人靠近时,小夜灯才会亮起。

最终的效果见下面视频。

在讲述如何制作这台小夜灯前,我们先梳理下需要准备的材料,对应的图示见下图。

  1. Arduino Uno R3

  2. 红外人体感应传感器

  3. 面包板

  4. 光敏电阻(5528)

  5. 分压电阻(10KΩ,配合5528光敏电阻使用)

  6. RGB LED 共阴极

  7. 限流电阻(100Ω - 300Ω) x 3

  8. 杜邦线:公对公 x 10, 公对母 x 10

https://cdn.china-scratch.com/timg/191214/1135402G0-0.jpg

https://cdn.china-scratch.com/timg/191214/1135403V4-1.jpg

https://cdn.china-scratch.com/timg/191214/11354020T-2.jpg

电路原理

在动手之前,我们得先理解电路原理。

https://cdn.china-scratch.com/timg/191214/1135404D8-3.jpg

这张图看起来很复杂,但拆分了细看却很简单。我们将这张电路图拆分成 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 的颜色。

动手组装

知道了原理之后,组装便成了件水到渠成的事情。

https://cdn.china-scratch.com/timg/191214/1135415337-4.jpg

编写程序

完成组装搭建工作后,下面就可以编写程序了。

先帖一下整体程序。

  1. #define rLedPin 6

  2. #define gLedPin 5

  3. #define bLedPin 3

  4. #define irSensorPin 8

  5. #define lightSensorPin A0

  6. int ledR = 33;

  7. int ledG = 150;

  8. int ledB = 243;

  9. bool irReading;

  10. int lightReading;

  11. void setup() {

  12. pinMode(rLedPin, OUTPUT);

  13. pinMode(gLedPin, OUTPUT);

  14. pinMode(bLedPin, OUTPUT);

  15. pinMode(irSensorPin, INPUT);

  16. }

  17. void loop() {

  18. irReading = digitalRead(irSensorPin);

  19. lightReading = analogRead(lightSensorPin);

  20. if(irReading == HIGH && lightReading >= 500) {

  21. lightOn(1);

  22. } else {

  23. lightOn(0);

  24. }

  25. delay(50);

  26. }

  27. void lightOn(bool on) {

  28. if(on == 1) {

  29. analogWrite(rLedPin, ledR);

  30. delay(10);

  31. analogWrite(gLedPin, ledG);

  32. delay(10);

  33. analogWrite(bLedPin, ledB);

  34. delay(10);

  35. } else {

  36. analogWrite(rLedPin, 0);

  37. delay(10);

  38. analogWrite(gLedPin, 0);

  39. delay(10);

  40. analogWrite(bLedPin, 0);

  41. delay(10);

  42. }

  43. }

上面的代码我们也拆分成 4 部分挨个解析。

宏定义与变量声明

  1. #define rLedPin 6 //RGB-LED引脚R

  2. #define gLedPin 5 //RGB-LED引脚G

  3. #define bLedPin 3 //RGB-LED引脚B

  4. #define irSensorPin 8 //红外人体感应模块信号输出

  5. #define lightSensorPin A0 //光敏电阻分压电路信号输出

  6. int ledR = 33; //R Led 亮度

  7. int ledG = 150; //G Led 亮度

  8. int ledB = 243; //B Led 亮度

  9. bool irReading; //存储红外人体感应模块输出

  10. int lightReading; //存储光敏电阻分压电路信号输出

前 5 行是宏定义,将 Arduino 的引脚序号使用变量表示,比如 rLedPin 表示 RGB LED 的红色引脚连接的是 Arduino 的 6 号引脚,再比如 lightSensorPin 表示光敏电阻的输出引脚连接的是 Arduino 的 A0 号引脚。

第 7 - 9 行 3 个变量分别表示 R、G、B 值。

第 11 行的变量表示从人体感应模块读取的值,第 12 行的变量表示从光敏电阻读取的光线值。

setup()函数

  1. void setup() {

  2. pinMode(rLedPin, OUTPUT);

  3. pinMode(gLedPin, OUTPUT);

  4. pinMode(bLedPin, OUTPUT);

  5. pinMode(irSensorPin, INPUT);

  6. }

当 Arduino 开始运行时,setup 函数会被执行一次。函数体中,第 2 - 4 行表示将 R、G、B 所连接的 Arduino 引脚设为输出模式,第 5 行将人体传感器连接的 Arduino 引脚设为输入模式。顾名思义,输出模式即 Arduino 将对外输出信号,输入模式则是 Arduino 将从该引脚获取信号。

loop()函数

  1. void loop() {

  2. irReading = digitalRead(irSensorPin);

  3. lightReading = analogRead(lightSensorPin);

  4. if(irReading == HIGH && lightReading >= 500) {

  5. lightOn(1);

  6. } else {

  7. lightOn(0);

  8. }

  9. }

loop函数是个循环体,setup 函数执行后将会反复执行。

第 2 行获取人体感应模块的值,如果值等于HIGH,表示传感器感应到了人体。

第 3 行获取分压电路的光线值,如果值大于 500,表示当前的光线比较暗。

那么,下面的条件语句就好理解了,当检测到人体并且光线比较暗的话,则执行lightOn(1),其余情况执行lightOn(0)。lightOn函数我们下面细看,现在只要知道前者表示点亮 LED,后者表示熄灭 LED。

lightOn()函数

  1. void lightOn(bool on) {

  2. if(on == 1) {

  3. analogWrite(rLedPin, ledR);

  4. delay(10);

  5. analogWrite(gLedPin, ledG);

  6. delay(10);

  7. analogWrite(bLedPin, ledB);

  8. delay(10);

  9. } else {

  10. analogWrite(rLedPin, 0);

  11. delay(10);

  12. analogWrite(gLedPin, 0);

  13. delay(10);

  14. analogWrite(bLedPin, 0);

  15. delay(10);

  16. }

  17. }

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