0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于ESP32和DFPlayer实现WiFi门铃的制作

科技观察员 来源:八色木 作者:八色木 2022-04-08 15:13 次阅读

本文将介绍如何制作一款基于ESP32,并经由WiFi网络实现的门铃。

项目起因

今年新家装修的时候,我忽略了门铃的问题。原来门边上设置有一个门铃按钮,但由于原来预留的线都被混凝土掩盖了,没办法找到电缆头在哪里。于是纠结怎么安装一款门铃。到网上一搜,目前有WiFi门铃的解决方案,可以把电铃放在不同的房间,但价格相当昂贵,而且还需要220v的电源供电。于是我选择用无线门铃来解决,但结果证明无线门铃的运行并不是非常可靠,而且我不怎么喜欢基于电池的解决方案。于是,开始萌生了采用微控制器来解决这个问题,使旧门铃能复活过来。

工作原理

项目的思路是这样的:设置两片单片机,分别置于室内和室外,当第一个单片机检测到按钮上的按钮动作时,通过WiFi网络向第二个单片机发送请求。第二个单片机连接到喇叭,当它收到发送的请求时便播放预设的铃声。项目中我使用了集成WiFi的Espressif ESP32开发板。为了让项目更简单,我还添加了一个便宜的MP3播放器模块。

原件清单

两块 Espressif ESP32开发板 ;

DFPlayer MP3模块和 SD卡;

4欧姆 3W的喇叭;

2个1K的电阻

两个3.3V LED指示灯

按钮开关;

面包板。

电路组装

这一部分比较简单,没什么值得注意的。基本上就是把所有的元件放在一起。最后,我把LED灯忘在扬声器那一侧了。(不过,最后代码中对其进行了处理。)poYBAGJP4FmAE4_RAALhu_IAMUw677.png

基于ESP32制作门铃之发送侧

门铃的外壳是采用3D打印机打印的,分为两部分,室外部分和室内部分。附件是电路连接图和外壳的3D打印STL文件,需要可下载

poYBAGJP4F2ALrjsAAVJvVn2LJ0537.png

基于ESP32制作门铃之发送侧实物

pYYBAGJP4GKAUunNAANJpF8jkVM003.png

基于ESP32制作门铃之接收侧

poYBAGJP4GiAbpTKAARod_c6ToA893.png

基于ESP32制作门铃之接收侧实物

代码

虽然发射端硬件上仅仅是稍微闪烁一下LED,功能比较单一,但接收单元提供了更多的功能,它可以启动一个小型web服务器,为发射端提供界面,也可以通过浏览器直接使用它。它还允许设置扬声器音量。

pYYBAGJP4G2AK3KqAAC_1TiutJg372.png

ESP32门铃的设置界面

发送端代码

/*

* Sources:

* https://www.arduino.cc/en/Tutorial/Button

* https://techtutorialsx.com/2017/05/19/esp32-http-get-requests/

*/

#include

#include

const char* ssid = "WiFi SSID";

const char* password = "WiFi password";

const char* bellUrl = "http://192.168.1.149/bell/on";

const int buttonPin = 21; // the number of the pushbutton pin

const int ledPin = 23; // the number of the LED pin

int buttonState = 0;

void setup() {

Serial.begin(115200);

btStop(); // turn off bluetooth

pinMode(ledPin, OUTPUT);

pinMode(buttonPin, INPUT);

connectWifi();

}

void loop() {

if ((WiFi.status() == WL_CONNECTED)) {

buttonState = digitalRead(buttonPin);

delay(100);

if (buttonState == HIGH) {

digitalWrite(ledPin, HIGH);

HTTPClient http;

http.begin(bellUrl);

Serial.print("GET ");

Serial.println(bellUrl);

int httpCode = http.GET();

if (httpCode > 0) {

//String payload = http.getString();

Serial.println(httpCode);

//Serial.println(payload);

}

else {

Serial.println("Error on HTTP request");

}

http.end();

delay(200);

}

else {

digitalWrite(ledPin, LOW);

}

}

else {

Serial.println("WiFi not connected!");

digitalWrite(ledPin, HIGH);

delay(200);

digitalWrite(ledPin, LOW);

delay(50);

digitalWrite(ledPin, HIGH);

delay(200);

digitalWrite(ledPin, LOW);

connectWifi();

}

}

void connectWifi() {

boolean ledStatus = false;

Serial.print("Connecting to ");

Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

ledStatus = !ledStatus;

digitalWrite(ledPin, ledStatus);

}

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

}

接收端代码

/*

Sources:

https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299

https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_DFPlayer_full/ESP32_DFPlayer_full.ino

https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_DFPlayer_full/setup.png

ESP32 Web Server – Arduino IDE

*/

#include

#include "DFRobotDFPlayerMini.h"

#include

HardwareSerial hwSerial(1);

DFRobotDFPlayerMini dfPlayer;

int volume = 5;

const char* ssid = "WiFi SSID";

const char* password = "WiFi password";

WiFiServer server(80); // Set web server port number to 80

String header;

String ledState = "";

const int ledPin = 26;

unsigned long timestamp = 0;

void setup()

{

btStop(); // turn off bluetooth

hwSerial.begin(9600, SERIAL_8N1, 18, 19); // speed, type, TX, RX

Serial.begin(115200);

// WiFi & LED ==================================================================

pinMode(ledPin, OUTPUT);

digitalWrite(ledPin, LOW);

// Connect to Wi-Fi network with SSID and password

Serial.print("Connecting to ");

Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

// Print local IP address and start web server

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

server.begin();

delay(500);

dfPlayer.begin(hwSerial); //Use softwareSerial to communicate with mp3

dfPlayer.setTimeOut(500); //Set serial communication time out 500ms

dfPlayer.volume(volume); //Set volume value (0~30).

dfPlayer.EQ(DFPLAYER_EQ_NORMAL);

dfPlayer.outputDevice(DFPLAYER_DEVICE_SD);

ledState = "on";

digitalWrite(ledPin, HIGH);

timestamp = millis();

dfPlayer.play(1); //Play the first mp3

}

void loop() {

WiFiClient client = server.available(); // Listen for incoming clients

if (ledState == "on" && (millis() - timestamp) > 2000) {

ledState = "off";

digitalWrite(ledPin, LOW);

}

if (client) {

String currentLine = ""; // make a String to hold incoming data from the client

while (client.connected()) { // loop while the client's connected

if (client.available()) { // if there's bytes to read from the client,

char c = client.read(); // read a byte, then

Serial.write(c); // print it out the serial monitor

header += c;

if (c == '\n') { // if the byte is a newline character

// if the current line is blank, you got two newline characters in a row.

// that's the end of the client HTTP request, so send a response:

if (currentLine.length() == 0) {

// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)

// and a content-type so the client knows what's coming, then a blank line:

client.println("HTTP/1.1 200 OK");

client.println("Content-type:text/html");

client.println("Connection: close");

client.println();

// turns the GPIOs on and off

if (header.indexOf("GET /bell/on") >= 0) {

ledState = "on";

digitalWrite(ledPin, HIGH);

timestamp = millis();

dfPlayer.play(1); //Play the first mp3

}

else if (header.indexOf("GET /volume/") >= 0) { // yes, I know this is not RESTful

String str1 = header;

str1 = str1.substring(header.indexOf("GET /volume/") + 12);

volume = str1.substring(0, str1.indexOf(" ")).toInt();

if (volume < 0) {

volume = 0;

}

else if (volume > 30) {

volume = 30;

}

dfPlayer.volume(volume);

Serial.print("volume set to ");

Serial.println(volume);

}

// Display the HTML web page

client.println("

");

client.println("

");

client.println("

");

client.println(" html { font-family: sans-serif; display: inline-block; margin: 0px auto; text-align: center; }");

client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");

client.println(".button2 { background-color: #4CAF50; border: none; color: white; padding: 4px 10px; text-decoration: none; margin: 1px; cursor: pointer;} ");

client.println("

LeWe Türklingel

");

client.println("

Volume: − " + String(volume) + " +

");

client.println("

Klingeln

");

client.println("

dfplayer status: " + printDetail(dfPlayer.readType(), dfPlayer.read()) + "

");

client.println("

LED - State " + ledState + "

");

client.println("");

// The HTTP response ends with another blank line

client.println();

// Break out of the while loop

break;

} else { // if you got a newline, then clear currentLine

currentLine = "";

}

} else if (c != '\r') { // if you got anything else but a carriage return character,

currentLine += c; // add it to the end of the currentLine

}

}

}

// Clear the header variable

header = "";

// Close the connection

client.stop();

Serial.println("Client disconnected.");

Serial.println("");

}

}

String printDetail(uint8_t type, int value){

switch (type) {

case TimeOut:

return "Time Out!";

break;

case WrongStack:

return "Stack Wrong!";

break;

case DFPlayerCardInserted:

return "Card Inserted!";

break;

case DFPlayerCardRemoved:

return "Card Removed!";

break;

case DFPlayerCardOnline:

return "Card Online!";

break;

case DFPlayerPlayFinished:

return "Play Finished!";

break;

case DFPlayerError:

switch (value) {

case Busy:

return "Error: Card not found";

break;

case Sleeping:

return "Error: Sleeping";

break;

case SerialWrongStack:

return "Error: Get Wrong Stack";

break;

case CheckSumNotMatch:

return "Error: Check Sum Not Match";

break;

case FileIndexOut:

return "Error: File Index Out of Bound";

break;

case FileMismatch:

return "Error: Cannot Find File";

break;

case Advertise:

return "Error: In Advertise";

break;

default:

break;

}

break;

default:

break;

}

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 门铃
    +关注

    关注

    1

    文章

    118

    浏览量

    35796
  • WIFI
    +关注

    关注

    81

    文章

    5297

    浏览量

    203604
  • ESP32
    +关注

    关注

    18

    文章

    971

    浏览量

    17214
收藏 人收藏

    评论

    相关推荐

    使用ESP32实现蓝牙通信

    上次给大家分享了如何使用ESP32实现UDP通信,今天跟大家聊聊如何使用ESP32实现蓝牙通信。
    发表于 11-21 09:31 1.5w次阅读

    浅谈Zephyr ESP32 wifi如何使用

    在Zephyr ESP32 wifi驱动简析一文中简要分析了esp32 wifi如何集成进Zephyr,本文接着说明要如何使用esp32
    的头像 发表于 06-01 10:17 6847次阅读

    简析esp32wifi驱动如何被集成进Zephyr的驱动

    分析Zephyr ESP32 WIFI驱动的实现可以更为清晰的掌握esp32 wifi在zephyr上的使用,本文主要分析
    的头像 发表于 06-01 10:41 4536次阅读
    简析<b class='flag-5'>esp32</b>的<b class='flag-5'>wifi</b>驱动如何被集成进Zephyr的驱动

    wifi&蓝牙MCU 该不该选ESP32

    ESP32是了国内乐鑫科技推出的Wifi&蓝牙物联网MCU,而最近项目正好在用ESP32,所以我们今天就来分享下,如何让你的ESP32跑起来,并应用于更多实际项目。1
    发表于 10-26 14:51 21次下载
    <b class='flag-5'>wifi</b>&蓝牙MCU  该不该选<b class='flag-5'>ESP32</b>

    esp32 例程 蓝牙_wifi&amp;蓝牙MCU 该不该选ESP32

    ESP32是了国内乐鑫科技推出的Wifi&蓝牙物联网MCU,而最近项目正好在用ESP32,所以我们今天就来分享下,如何让你的ESP32跑起来,并应用于更多实际项目。1
    发表于 12-06 20:06 31次下载
    <b class='flag-5'>esp32</b> 例程 蓝牙_<b class='flag-5'>wifi</b>&amp;蓝牙MCU  该不该选<b class='flag-5'>ESP32</b>

    ESP32ESP-IDF 教学WiFi篇(一)—— WiFi两种模式

    本文章 来自原创专栏《ESP32教学专栏 (基于ESP-IDF)》 下的一个二级专栏 《ESP32 上的 WiFi 及 Lwip 协议栈》,讲解如何使用
    发表于 01-13 14:37 48次下载
    <b class='flag-5'>ESP32</b> 之 <b class='flag-5'>ESP</b>-IDF 教学<b class='flag-5'>WiFi</b>篇(一)—— <b class='flag-5'>WiFi</b>两种模式

    使用ESP32制作ESP RainMaker IoT项目

    电子发烧友网站提供《使用ESP32制作ESP RainMaker IoT项目.zip》资料免费下载
    发表于 10-24 10:54 9次下载
    使用<b class='flag-5'>ESP32</b><b class='flag-5'>制作</b><b class='flag-5'>ESP</b> RainMaker IoT项目

    基于ESP32的Wi-Fi门铃

    。由于我对 Arduino 世界还很陌生,并且想让事情变得简单,所以我使用了集成了 WiFi 的 Espressif ESP32 板。为了使它更容易,我添加了一个便宜的 MP3 播放器模块。2× 乐鑫 ESP32 开发板
    发表于 12-13 16:04 3次下载

    基于ESP32的可视智能门铃

    生气。当然,我们也可以忽略它,不开门,但总会有这种不确定的暗示——“也许这很重要”。这个问题的解决方案是“智能门铃”。多亏了它,你才会知道是否值得从沙发上站起来开门。我的项目基于 ESP32。它是一个非常流行的模块,因此非
    发表于 12-27 15:55 5次下载

    使用M5StickC ESP32制作WiFi扫描仪

    在这个项目中,我们将学习如何使用M5StickC ESP32模块制作WiFi扫描仪,以显示周围的WiFi网络。硬件组件:M5StickC ESP32
    发表于 01-04 17:34 0次下载

    使用M5StickC ESP32模块制作WiFi扫描仪

    在这个项目中,我们将学习如何使用M5StickC ESP32模块制作WiFi扫描仪,以显示周围的WiFi网络。硬件组件:M5StickC ESP32
    发表于 01-05 16:47 0次下载

    ESP8266或ESP32上的WiFi Webradio

    电子发烧友网站提供《ESP8266或ESP32上的WiFi Webradio.zip》资料免费下载
    发表于 06-13 11:38 1次下载
    <b class='flag-5'>ESP</b>8266或<b class='flag-5'>ESP32</b>上的<b class='flag-5'>WiFi</b> Webradio

    基于ESP32WiFi温度传感器网络的实现

    电子发烧友网站提供《基于ESP32WiFi温度传感器网络的实现.zip》资料免费下载
    发表于 06-13 11:01 0次下载
    基于<b class='flag-5'>ESP32</b>的<b class='flag-5'>WiFi</b>温度传感器网络的<b class='flag-5'>实现</b>

    基于ESP32+MicroPython实现联网并进行UDP通信

    使用 esp32 开发程序,非常重要的功能就是使用 wifi,下面我们就讲一下 esp32 连接 wifi 的方法。
    的头像 发表于 06-13 17:05 6204次阅读
    基于<b class='flag-5'>ESP32</b>+MicroPython<b class='flag-5'>实现</b>联网并进行UDP通信

    ESP32学习笔记:WiFi

    今天我们来说说ESP32WiFi
    的头像 发表于 07-15 16:20 3935次阅读
    <b class='flag-5'>ESP32</b>学习笔记:<b class='flag-5'>WiFi</b>