如今,安全系统是研究最多的领域之一,随着安全威胁的增加,公司正在推出新的智能安全产品来应对这些威胁。物联网是该领域的一个额外优势,它可以在任何紧急情况下自动触发事件,例如报警、消防队或您的邻居。今天我们将使用ESP32 和摄像头构建智能 Wi-Fi 门铃。
所需组件
ESP32-CAM
FTDI编程板
220V AC 到 5V DC 转换器
蜂鸣器
按钮
发光二极管 (2)
电路原理图
这款智能 Wi-Fi 门铃的电路图非常简单,只需将两个 LED、一个按钮和一个蜂鸣器连接到 ESP32 GPIO 引脚即可。每当按下按钮时,蜂鸣器都会发出声音。一个 LED 用于指示电源状态,另一个 LED 用于指示网络状态。如果 ESP 连接到网络,网络 LED 将处于高电平状态,否则它将闪烁。
这是Wi-Fi 视频门铃设置在 3D 打印外壳中的外观:
Wi-Fi 门铃的 IFTTT 设置
IFTTT 是一项基于 Web 的免费服务,它允许用户创建称为“食谱”的简单条件语句链,这些语句是基于对其他 Web 服务(如 Gmail、Facebook、Instagram 和 Pinterest)的更改而触发的。 IFTTT 是“If This Then That”的缩写。
在这个项目中,IFTTT 用于在温度或湿度超过预定义限制时发送电子邮件。我们之前在许多基于物联网的项目中使用 IFTTT 来发送电子邮件或 SMS 以针对特定事件发送电子邮件或 SMS,例如过度用电、高脉冲率、入侵者进入等。
首先 使用您的凭据 登录IFTTT , 如果您没有帐户,请注册。
现在搜索“Webhooks”并单击“服务”部分中的“Webhooks”。
现在,在 Webhooks 窗口中,单击右上角的“文档”以获取私钥。
复制此密钥。它将在程序中使用。
获得私钥后,现在我们将使用 Webhooks 和电子邮件服务创建一个小程序。要创建小程序,请单击您的个人资料,然后单击“创建”。‘
现在在下一个窗口中,单击“此”图标。
现在在搜索部分搜索 Webhooks,然后单击“ Webhooks”。’
现在选择“接收 Web 请求” 触发器,然后在下一个窗口中,输入事件名称为 button_pressed,然后单击创建触发器。
现在要完成小程序,单击“那个”为button_pressed事件创建一个反应。
在这里,我们将在按下 IoT 门铃按钮时在手机上播放特定歌曲。在搜索部分中搜索“Android 设备”。
现在在 Android 设备中,选择“播放特定歌曲”触发器。
现在输入按下门铃按钮时要播放的歌曲名称。就我而言,我正在播放我的谷歌播放音乐中名为“123”的歌曲。您还可以使用 Spotify 或其他音乐应用程序。
之后,单击“创建操作”,然后单击“完成”以完成该过程。
现在创建另一个小程序,在按下门铃按钮时向手机发送带有网页链接的消息。
因此,要创建此小程序,请在“ this ”部分中选择“ Webhooks ” ,在“that”部分中选择“ Android SMS ”。
现在它会要求输入电话号码和消息正文。对于这个Wi-Fi 门铃项目,我们正在发送带有 Web 服务器链接的消息,以便您可以直接看到实时视频流。
代码说明
本文档末尾提供了此Wi-Fi 门铃摄像头的完整代码以及视频。它也可以从这里下载。下面我们将解释代码的一些重要部分。
首先,包含此代码所需的所有库文件。
#include “esp_camera.h”
#include
然后输入 Wi-Fi 凭据。
const char* ssid = "Wi-Fi 名称";
const char* 密码 = "Wi-Fi 密码";
之后,输入您从 IFTTT 网站复制的 IFTTT 主机名和私钥。
const char *host = "maker.ifttt.com";
const char *privateKey = "你的私钥";
定义您在此项目中使用的所有引脚。我正在使用 GPIO 2、14 和 15 引脚来连接按钮、LED 和蜂鸣器。
常量 int buttonPin = 2;
常量 int led1 = 14;
常量 int 蜂鸣器 = 15;
在void setup循环内,将按钮引脚定义为输入,将 LED 和蜂鸣器引脚定义为输出。
无效设置(){
pinMode(buttonPin,输入);
pinMode(led1,输出);
pinMode(蜂鸣器,输出);
它将尝试使用给定的凭据连接到 Wi-Fi,并且当连接到网络时,LED 状态将从低变为高。
WiFi.begin(ssid, 密码);
int led = 低;
而(WiFi.status()!= WL_CONNECTED){
延迟(500);
Serial.print(".");
数字写入(led1,led);
领导=!领导;
}
序列号.println("");
Serial.println("WiFi 连接");
数字写入(led1,高);
与网络断开连接时,ESP32 将重新启动,直到它连接到网络。
而(WiFi.status()== WL_DISCONNECTED){
ESP.restart();
数字写入(led1,低);
Serial.print("连接丢失");
ESP32 会读取按键状态,如果按键处于 LOW 状态(拉高),即有按键被按下,则发送事件并打开蜂鸣器 3 秒。
int 阅读 = digitalRead(buttonPin);
如果(按钮状态 == 低){
send_event("button_pressed");
Serial.print("按下按钮");
数字写入(蜂鸣器,高);
延迟(3000);
数字写入(蜂鸣器,低);
用于智能 Wi-Fi 门铃的 3D 打印外壳
在这里,我为这款无线门铃摄像头设计了一个 3D 打印外壳。为此,我使用游标卡尺测量了 ESP32 板、按钮、蜂鸣器和 LED 的尺寸,设计完成后如下图所示。
之后,我将其导出为 STL 文件,根据打印机设置对其进行切片,最后打印出来。STL 文件可从Thingiverse下载,您可以使用它打印自己的外壳。
打印完外壳后,我将电路组装到外壳中,一切都非常合适,正如您在此处看到的那样。
如果您想了解更多关于 3D 打印机及其工作原理的信息,您可以阅读这篇关于 3D 打印入门指南的文章,也可以查看我们使用3D 打印外壳的其他项目,例如Biped Robot、Robotic Arm等。
测试智能 Wi-Fi 门铃
组装电路后,使用交流插座为门铃供电。现在,只要按下 IoT 门铃按钮,智能手机就会开始播放一首名为“123”的歌曲,并会收到一条消息,其中包含如下所示的网页链接,其中可以看到实时视频源。
此智能 Wi-Fi 门铃的完整代码和工作视频可在文档末尾找到,或者您可以从此处下载代码。如果您对此项目有任何疑问,请将其留在评论部分。
代码
#include “esp_camera.h”
#include 《WiFi.h》
//
// 警告!!!确保您选择了 ESP32 Wrover 模块,
// 或另一个启用了 PSRAM 的板
//
// 选择相机型号
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER
#include “camera_pins.h”
void send_event(const char *event);
const char* ssid = “银河-M20”;
const char* 密码 = “ac312124”;
const char *host = “maker.ifttt.com”;
const char *privateKey = “
常量 int buttonPin = 2;
int 按钮状态;// 来自输入引脚的当前读数
int lastButtonState = LOW; // 输入引脚的先前读数
const int led1 = 14;
常量 int 蜂鸣器 = 15;
上次去抖时间 = 0; // 最后一次切换输出引脚
long debounceDelay = 50; // 去抖时间;如果输出闪烁则增加
void startCameraServer();
无效设置(){
pinMode(buttonPin,输入);
pinMode(led1,输出);
pinMode(蜂鸣器,输出);
序列号。开始(115200);
Serial.setDebugOutput(true);
序列号.println();
camera_config_t 配置;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
//用高规格初始化以预分配更大的缓冲区
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} 其他 {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
#如果定义(CAMERA_MODEL_ESP_EYE)
pinMode(13,INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
// 摄像头初始化
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf(”Camera init failed with error 0x%x“, err);
返回;
}
sensor_t * s = esp_camera_sensor_get();
//初始传感器垂直翻转,颜色有点饱和
if (s-》id.PID == OV3660_PID) {
s-》set_vflip(s, 1);//翻转回来
s-》set_brightness(s, 1) ;//稍微提高亮度
s-》set_saturation(s, -2);//降低饱和度
}
//降低帧大小以获得更高的初始帧速率
s-》set_framesize(s, FRAMESIZE_QVGA);
#if 定义(CAMERA_MODEL_M5STACK_WIDE)
s-》set_vflip(s, 1);
s-》set_hmirror(s, 1);
#endif
WiFi.begin(ssid, 密码);
int led = 低;
而(WiFi.status()!= WL_CONNECTED){
延迟(500);
Serial.print(”。“);
数字写入(led1,led);
领导=!领导;
}
Serial.println(”“);
Serial.println(”WiFi 连接“);
数字写入(led1,高);
startCameraServer();
Serial.print(”相机准备好了!使用‘http://“);
Serial.print(WiFi.localIP());
Serial.println(”’要连接“);
}
void loop() {
while (WiFi.status() == WL_DISCONNECTED) {
ESP.restart();
数字写入(led1,低);
Serial.print(”连接丢失“);
}
int 阅读 = digitalRead(buttonPin);
如果(阅读!= lastButtonState){
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) 》 debounceDelay)
{
// 如果按钮状态发生了变化:
if (reading != buttonState)
{
Serial.print(”Button now “);
Serial.println(HIGH == reading ? ”HIGH“ : ”LOW“);
按钮状态 = 阅读;
// 当按钮处于 LOW 状态(拉高)时,按钮已被按下,因此发送事件。
if (buttonState == LOW) {
send_event(”button_pressed“);
Serial.print(”按下按钮“);
数字写入(蜂鸣器,高);
延迟(3000);
数字写入(蜂鸣器,低);
}
}
}
// 保存读数。下一次循环,
lastButtonState = reading;
}
void send_event(const char *event)
{
Serial.print(”连接到“);
串行.println(主机);
// 使用 WiFiClient 类创建 TCP 连接
WiFiClient 客户端;
常量 int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println(”连接失败“);
返回;
}
// 我们现在为请求创建一个 URI
String url = ”/trigger/“;
网址 += 事件;
url += ”/with/key/“;
网址 += 私钥;
Serial.print(”请求网址:“);
序列号.println(url);
// 这会将请求发送到服务器
client.print(String(”GET “) + url + ” HTTP/1.1rn“ +
”Host: “ + host + ”rn“ +
”Connection:关闭rnrn“);
while(client.connected())
{
if(client.available())
{
String line = client.readStringUntil(‘r’);
串行打印(行);
} else {
// 还没有数据,请稍等
delay(50);
};
}
Serial.println();
Serial.println(”关闭连接“);
客户端.stop();
}