实验:使用 Blnyk APP 控制与 ESP32S 无线模块相连接的光敏传感器根据实际环境亮度自动调节模拟门头 LED 灯、阳台 LED 灯亮度
一、硬件清单
1.ESP32S 无线模块一块
2.Arduino Uno 开发板一块
3.PCB 集成板一块(Uno 配套)
2.USB 数据线一根(Uno 配套)
3.人体红外传感器一个
4.光敏传感器一个
5.LED 灯三个
6.杜邦线若干根
二、前景概述
ESP32S 是一款支持无线网络通信与控制的无线模块,可扩展性很好,可通过配网实现客户端远程控制设备,从而达到智能管理的目的。而 Arduino Uno 是一块广受欢迎的开源硬件开发板,由意大利公司Arduino 制造。其应用背景涵盖了广泛的电子和嵌入式系统开发领域。Arduino Uno 广泛应用于物联网项目。通过其丰富的库和插件,用户可以轻松地连接传感器、执行器和通信模块,构建各种物联网应用,如智能家居系统、环境监测系统等。
2.1 实物及原理图
ESP32S
Auduino Uno
2.2 接线
ESP32SNodeMCU LED 绿灯(一楼门头灯)
P4(自选) 正极
GND 负极
Arduino Uno
LED 红灯(一楼室内灯)
S(P6) 正极
GND 负极
LED 黄灯(二楼室内灯)
S(P3) 正极
GND 负极
人体红外传感器(二楼墙壁)
S(P8) OUT(信号)
VSS VSS
GND GND
光敏传感器
S(A0) AO
VSS 3V3
GND GND
三、任务目标
3.1 完成智能家居“别墅”中的灯光控制部分
3.1.1 APP/Uno 控制 LED 灯的亮灭
3.1.2 根据光线强度自动控制 LED 灯的亮灭
3.1.3 完成一楼门头以及室内灯、二楼室内灯的组装搭建
3.2 理论知识
3.2.1 了解什么是传感器
3.2.2 掌握数字/模拟信号
3.2.3 了解光敏传感器的检测原理,掌握该传感器的使用
3.2.4 掌握变量的使用
四、什么是传感器
4.1 传感器是一种能够检测周围信息,并按照一定规律转换成电信号或者其他信号的装置。(传感器类似于人的五官,帮助智能设备感受外界的变化)
电信号分类:数字信号、模拟信号
传感器分类:热敏、光敏、气敏、力敏、湿敏、声敏等
生活中的应用:
1. 自动门:利用人体的红外微波来开门
2. 烟雾报警器:利用烟敏电阻来测量烟雾浓度,从而达到报警目的
3. 公共楼道的灯:利用声音传感器对灯进行控制
4.2 数字&模拟信号
数字信号:在时间和数值上均具有离散性的信号。数字信号一般通过模拟信号转换而来
模拟信号:在时间和数值上均具有连续性的信号。大多数的外界信号均为模拟信号,例如环境温度、水流流量、光照强度等
数字信号用0和1表示(或高和低、或有和没有),模拟信号用一段数字范围来表示,如0-1023、0-4095等,通过数字的大小反应物理量的大小
关于数字信号和模拟信号的形象比喻,可以参考下图所示:
4.3 变量的使用
实际使用中,通常会采用变量来“存储”光线强度的数值,使用变量时,主要为以下几点:
1. 声明创建变量。需要命名,并赋初始值值
2. 将某个数据存入变量中,存放前的数据将会自动被覆盖(删除),并在该位置存放新的数据值
3. 读取变量中的数据
五、执行流程
六、执行方式
方式二:基于绑定 Blynk APP 生成的 Blynk-Auth Key、Blnyk-Server/Port、网络名称/密码、设置的参数值等信息控制设备(虚拟管脚)
Arduino Uno 开发板的本地控制室内设备
七、Blnyk APP
7.1 控制界面
创建一个"Button" 组件,取名为一楼门头灯,并分别使用 GPIO4 进行控制设备
7.2 设备接通
模型纯手工打造,做工有些许简陋,目的只为了模拟展示演示效果
7.3 智能家居组成
底部
正面
顶部
侧面
后面
八、建模
九、检验
9.1 编译以及输出结果
9.2 设备状态
十、操作视频演示
十一、代码
11.1 Blynk APP 控制(在线)
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
// Blynk-Auth Key
char auth[] = "TncBP9on3mNLTMDBr-xHAnxp_VM8-2lM";
// 无线网络名称/密码
char ssid[] = "CMCC-ZeEd";
char pass[] = "u6kd6bey";
void setup(){
// 设置波特率
Serial.begin(9600);
// 执行 auth/ssid/password/server/port
Blynk.begin(auth, ssid, pass,"blynk.iot-share.cn",8080);
}
void loop(){
// 运行
Blynk.run();
}
11.2 Uno 开发板控制(本地离线)
#define rLedPin 6 //RGB-LED引脚R
#define gLedPin 5 //RGB-LED引脚G
#define yLedPin 3 //RGB-LED引脚B
#define irSensorPin 8 //红外人体感应模块信号输出
#define lightSensorPin A0 //光敏电阻分压电路信号输出
int ledR = 0; //R Led 亮度
int ledG = 0; //G Led 亮度
int ledY = 0; //B Led 亮度
bool irReading; //红外人体感应模块输出
int lightReading; //光敏电阻分压电路信号输出
bool onOffState; //小夜灯开关状态
unsigned long previousIRMillis; //上一次检查红外传感器的时间
unsigned long previousLightMillis; //上一次检查光敏传感器的时间
int irCheckInterval = 500; //红外传感器检查时间间隔
int sensitivity = 500; // 调整灵敏度的阈值,根据实际情况调整
int lightCheckInterval = 1000; //光敏传感器检查时间间隔
int colorIndex; //颜色序列号
int colorChangeDelay = 1; //颜色改变速度控制变量(数值越大,颜色改变速度越慢)
int lightThreshold = 800; // 光敏传感器亮度预设值,根据实际情况调整
void setup() {
pinMode(rLedPin, OUTPUT);
pinMode(gLedPin, OUTPUT);
pinMode(yLedPin, OUTPUT);
pinMode(irSensorPin, INPUT);
Serial.begin(9600);
Serial.println("Welcome to Taichi-Maker RGB Led Night-Light.");
Serial.println("System Start Sensor Check.");
irReading = digitalRead(irSensorPin);
lightReading = analogRead(lightSensorPin);
Serial.println("");
Serial.println("======Checking Sensor.=====");
Serial.println("===========================");
Serial.print("irReading = "); Serial.println(irReading);
Serial.print("lightReading = "); Serial.println(lightReading);
Serial.println("===========================");
Serial.println("");
}
void loop() {
unsigned long currentMillis = millis();
irCheck(currentMillis);
lightCheck(currentMillis);
if (irReading == HIGH) {
irCheckInterval = 30000;
} else {
irCheckInterval = 500;
}
if (irReading == HIGH && lightReading >= lightThreshold) {
if (onOffState == 0) {
turnOn(); // 修改:点亮小夜灯照明
}
onOffState = 1;
} else {
if (onOffState == 1) {
turnOff(); // 修改:保持小夜灯熄灭
}
onOffState = 0;
}
}
void turnOn() {
Serial.println("");
Serial.println("Turn ON");
analogWrite(rLedPin, 255);
analogWrite(gLedPin, 255);
analogWrite(yLedPin, 255);
}
void turnOff() {
Serial.println("");
Serial.println("Turn OFF");
analogWrite(rLedPin, 0);
analogWrite(gLedPin, 0);
analogWrite(yLedPin, 0);
}
void ledShowColor(int ledColorIndex){
/*
* ledColorIndex参数为颜色序列号。
* 以下语句根据参数ledColorIndex让RGB-LED显示相应颜色。
* 从而产生小夜灯色彩渐变的效果。
* 您可以将程序上传并观察小夜灯在工作时候的串口监视器数据输出
* 从而找到小夜灯颜色变化的规律。
*/
if (ledColorIndex >= 0 && ledColorIndex <= 255){
ledR = 255 - ledColorIndex;
analogWrite (rLedPin, ledR);
} else if(ledColorIndex >= 256 && ledColorIndex <= 511){
ledR = ledColorIndex -256;
analogWrite (rLedPin, ledR);
} else if(ledColorIndex >= 512 && ledColorIndex <= 767){
ledG = 767 - ledColorIndex;
analogWrite (gLedPin, ledG);
} else if(ledColorIndex >= 768 && ledColorIndex <= 1023){
ledG = ledColorIndex - 768;
analogWrite (gLedPin, ledG);
} else if(ledColorIndex >= 1024 && ledColorIndex <= 1279){
ledY = 1279 - ledColorIndex;
analogWrite (yLedPin, ledY);
} else if(ledColorIndex >= 1280 && ledColorIndex <= 1535){
ledY = ledColorIndex - 1280;
analogWrite (yLedPin, ledY);
}
Serial.println("");
Serial.print("ledR = ");Serial.println(ledR);
Serial.print("ledG = ");Serial.println(ledG);
Serial.print("ledY = ");Serial.println(ledY);
delay(colorChangeDelay);
}
void irCheck(unsigned long thisIRMillis) {
/*
* 每一次调用irCheck函数,都需要将当前Arduino的开机
* 时间传递给irCheck函数的thisIRMillis参数。
* 而irCheck函数中的previousIRMillis变量是上一次传感器检查时间
* 通过比较变量thisIRMillis和变量previousIRMillis之间的间隔
* (当前的Arduino开机运行时间和上一次检查传感器时间的间隔)
* 来确定Arduino是否需要该检查传感器了。而控制这个时间间隔
* 的变量就是irCheckInterval。
*/
if ((unsigned long)(thisIRMillis - previousIRMillis >= irCheckInterval)) { //如果时间间隔到达了
irReading = digitalRead(irSensorPin); //读取红外人体感应模块
//通过串口监视器实时输出传感器检测的数据结果
//可用于调试小夜灯工作参数使用
Serial.println("");
Serial.println("=== Checking IR Sensor ====");
Serial.println("===========================");
Serial.print("irReading = "); Serial.println(irReading);
Serial.print("thisIRMillis = "); Serial.println(thisIRMillis);
Serial.print("previousIRMillis = "); Serial.println(previousIRMillis);
Serial.println("===========================");
Serial.println("");
// 每一次检查完传感器以后,都要将这一次检查传感器的时间更新给previousIRMillis。
// 这一个操作是通过将thisIRMillis存储的时间信息赋值给previousIRMillis完成的。
// 这样下次irCheck函数被调用时,previousIRMillis将保持为最近一次传感器检查时间。
previousIRMillis = thisIRMillis;
}
}
void lightCheck(unsigned long thisLightMillis) {
//检查是否到达时间间隔
if ((unsigned long)(thisLightMillis - previousLightMillis >= lightCheckInterval)) { //如果时间间隔到达了
lightReading = analogRead(lightSensorPin); //读取光敏电阻分压电路信号输出
//通过串口监视器实时输出各个传感器检测的数据结果
//可用于调试小夜灯工作参数使用
Serial.println("");
Serial.println("== Checking Light Sensor ==");
Serial.println("===========================");
Serial.print("lightReading = "); Serial.println(lightReading);
Serial.print("thisLightMillis = "); Serial.println(thisLightMillis);
Serial.print("previousLightMillis = "); Serial.println(previousLightMillis);
Serial.println("===========================");
Serial.println("");
previousLightMillis = thisLightMillis; // 记录最新一次的传感器检查时间
}
}