0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于ESP32和DFPlayer實(shí)現(xiàn)WiFi門(mén)鈴的制作

科技觀察員 ? 來(lái)源:八色木 ? 作者:八色木 ? 2022-04-08 15:13 ? 次閱讀

本文將介紹如何制作一款基于ESP32,并經(jīng)由WiFi網(wǎng)絡(luò)實(shí)現(xiàn)的門(mén)鈴。

項(xiàng)目起因

今年新家裝修的時(shí)候,我忽略了門(mén)鈴的問(wèn)題。原來(lái)門(mén)邊上設(shè)置有一個(gè)門(mén)鈴按鈕,但由于原來(lái)預(yù)留的線都被混凝土掩蓋了,沒(méi)辦法找到電纜頭在哪里。于是糾結(jié)怎么安裝一款門(mén)鈴。到網(wǎng)上一搜,目前有WiFi門(mén)鈴的解決方案,可以把電鈴放在不同的房間,但價(jià)格相當(dāng)昂貴,而且還需要220v的電源供電。于是我選擇用無(wú)線門(mén)鈴來(lái)解決,但結(jié)果證明無(wú)線門(mén)鈴的運(yùn)行并不是非??煽浚椅也辉趺聪矚g基于電池的解決方案。于是,開(kāi)始萌生了采用微控制器來(lái)解決這個(gè)問(wèn)題,使舊門(mén)鈴能復(fù)活過(guò)來(lái)。

工作原理

項(xiàng)目的思路是這樣的:設(shè)置兩片單片機(jī),分別置于室內(nèi)和室外,當(dāng)?shù)谝粋€(gè)單片機(jī)檢測(cè)到按鈕上的按鈕動(dòng)作時(shí),通過(guò)WiFi網(wǎng)絡(luò)向第二個(gè)單片機(jī)發(fā)送請(qǐng)求。第二個(gè)單片機(jī)連接到喇叭,當(dāng)它收到發(fā)送的請(qǐng)求時(shí)便播放預(yù)設(shè)的鈴聲。項(xiàng)目中我使用了集成WiFi的Espressif ESP32開(kāi)發(fā)板。為了讓項(xiàng)目更簡(jiǎn)單,我還添加了一個(gè)便宜的MP3播放器模塊。

原件清單

兩塊 Espressif ESP32開(kāi)發(fā)板 ;

DFPlayer MP3模塊和 SD卡;

4歐姆 3W的喇叭;

2個(gè)1K的電阻;

兩個(gè)3.3V LED指示燈

按鈕開(kāi)關(guān);

面包板。

電路組裝

這一部分比較簡(jiǎn)單,沒(méi)什么值得注意的。基本上就是把所有的元件放在一起。最后,我把LED燈忘在揚(yáng)聲器那一側(cè)了。(不過(guò),最后代碼中對(duì)其進(jìn)行了處理。)poYBAGJP4FmAE4_RAALhu_IAMUw677.png

基于ESP32制作門(mén)鈴之發(fā)送側(cè)

門(mén)鈴的外殼是采用3D打印機(jī)打印的,分為兩部分,室外部分和室內(nèi)部分。附件是電路連接圖和外殼的3D打印STL文件,需要可下載

poYBAGJP4F2ALrjsAAVJvVn2LJ0537.png

基于ESP32制作門(mén)鈴之發(fā)送側(cè)實(shí)物

pYYBAGJP4GKAUunNAANJpF8jkVM003.png

基于ESP32制作門(mén)鈴之接收側(cè)

poYBAGJP4GiAbpTKAARod_c6ToA893.png

基于ESP32制作門(mén)鈴之接收側(cè)實(shí)物

代碼

雖然發(fā)射端硬件上僅僅是稍微閃爍一下LED,功能比較單一,但接收單元提供了更多的功能,它可以啟動(dòng)一個(gè)小型web服務(wù)器,為發(fā)射端提供界面,也可以通過(guò)瀏覽器直接使用它。它還允許設(shè)置揚(yáng)聲器音量。

pYYBAGJP4G2AK3KqAAC_1TiutJg372.png

ESP32門(mén)鈴的設(shè)置界面

發(fā)送端代碼

/*

* 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;

}

}

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 門(mén)鈴
    +關(guān)注

    關(guān)注

    1

    文章

    118

    瀏覽量

    35808
  • WIFI
    +關(guān)注

    關(guān)注

    81

    文章

    5297

    瀏覽量

    203717
  • ESP32
    +關(guān)注

    關(guān)注

    18

    文章

    971

    瀏覽量

    17261
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用ESP32實(shí)現(xiàn)藍(lán)牙通信

    上次給大家分享了如何使用ESP32實(shí)現(xiàn)UDP通信,今天跟大家聊聊如何使用ESP32實(shí)現(xiàn)藍(lán)牙通信。
    發(fā)表于 11-21 09:31 ?1.6w次閱讀

    淺談Zephyr ESP32 wifi如何使用

    在Zephyr ESP32 wifi驅(qū)動(dòng)簡(jiǎn)析一文中簡(jiǎn)要分析了esp32 wifi如何集成進(jìn)Zephyr,本文接著說(shuō)明要如何使用esp32
    的頭像 發(fā)表于 06-01 10:17 ?6857次閱讀

    簡(jiǎn)析esp32wifi驅(qū)動(dòng)如何被集成進(jìn)Zephyr的驅(qū)動(dòng)

    分析Zephyr ESP32 WIFI驅(qū)動(dòng)的實(shí)現(xiàn)可以更為清晰的掌握esp32 wifi在zephyr上的使用,本文主要分析
    的頭像 發(fā)表于 06-01 10:41 ?4543次閱讀
    簡(jiǎn)析<b class='flag-5'>esp32</b>的<b class='flag-5'>wifi</b>驅(qū)動(dòng)如何被集成進(jìn)Zephyr的驅(qū)動(dòng)

    wifi&藍(lán)牙MCU 該不該選ESP32

    ESP32是了國(guó)內(nèi)樂(lè)鑫科技推出的Wifi&藍(lán)牙物聯(lián)網(wǎng)MCU,而最近項(xiàng)目正好在用ESP32,所以我們今天就來(lái)分享下,如何讓你的ESP32跑起來(lái),并應(yīng)用于更多實(shí)際項(xiàng)目。1
    發(fā)表于 10-26 14:51 ?21次下載
    <b class='flag-5'>wifi</b>&藍(lán)牙MCU  該不該選<b class='flag-5'>ESP32</b>

    esp32 例程 藍(lán)牙_wifi&amp;藍(lán)牙MCU 該不該選ESP32

    ESP32是了國(guó)內(nèi)樂(lè)鑫科技推出的Wifi&藍(lán)牙物聯(lián)網(wǎng)MCU,而最近項(xiàng)目正好在用ESP32,所以我們今天就來(lái)分享下,如何讓你的ESP32跑起來(lái),并應(yīng)用于更多實(shí)際項(xiàng)目。1
    發(fā)表于 12-06 20:06 ?31次下載
    <b class='flag-5'>esp32</b> 例程 藍(lán)牙_<b class='flag-5'>wifi</b>&amp;藍(lán)牙MCU  該不該選<b class='flag-5'>ESP32</b>

    ESP32ESP-IDF 教學(xué)WiFi篇(一)—— WiFi兩種模式

    本文章 來(lái)自原創(chuàng)專欄《ESP32教學(xué)專欄 (基于ESP-IDF)》 下的一個(gè)二級(jí)專欄 《ESP32 上的 WiFi 及 Lwip 協(xié)議?!?,講解如何使用
    發(fā)表于 01-13 14:37 ?48次下載
    <b class='flag-5'>ESP32</b> 之 <b class='flag-5'>ESP</b>-IDF 教學(xué)<b class='flag-5'>WiFi</b>篇(一)—— <b class='flag-5'>WiFi</b>兩種模式

    使用ESP32制作ESP RainMaker IoT項(xiàng)目

    電子發(fā)燒友網(wǎng)站提供《使用ESP32制作ESP RainMaker IoT項(xiàng)目.zip》資料免費(fèi)下載
    發(fā)表于 10-24 10:54 ?9次下載
    使用<b class='flag-5'>ESP32</b><b class='flag-5'>制作</b><b class='flag-5'>ESP</b> RainMaker IoT項(xiàng)目

    基于ESP32的Wi-Fi門(mén)鈴

    。由于我對(duì) Arduino 世界還很陌生,并且想讓事情變得簡(jiǎn)單,所以我使用了集成了 WiFi 的 Espressif ESP32 板。為了使它更容易,我添加了一個(gè)便宜的 MP3 播放器模塊。2× 樂(lè)鑫 ESP32 開(kāi)發(fā)板
    發(fā)表于 12-13 16:04 ?3次下載

    基于ESP32的可視智能門(mén)鈴

    生氣。當(dāng)然,我們也可以忽略它,不開(kāi)門(mén),但總會(huì)有這種不確定的暗示——“也許這很重要”。這個(gè)問(wèn)題的解決方案是“智能門(mén)鈴”。多虧了它,你才會(huì)知道是否值得從沙發(fā)上站起來(lái)開(kāi)門(mén)。我的項(xiàng)目基于 ESP32。它是一個(gè)非常流行的模塊,因此非
    發(fā)表于 12-27 15:55 ?5次下載

    使用M5StickC ESP32制作WiFi掃描儀

    在這個(gè)項(xiàng)目中,我們將學(xué)習(xí)如何使用M5StickC ESP32模塊制作WiFi掃描儀,以顯示周?chē)?b class='flag-5'>WiFi網(wǎng)絡(luò)。硬件組件:M5StickC ESP32
    發(fā)表于 01-04 17:34 ?0次下載

    使用M5StickC ESP32模塊制作WiFi掃描儀

    在這個(gè)項(xiàng)目中,我們將學(xué)習(xí)如何使用M5StickC ESP32模塊制作WiFi掃描儀,以顯示周?chē)?b class='flag-5'>WiFi網(wǎng)絡(luò)。硬件組件:M5StickC ESP32
    發(fā)表于 01-05 16:47 ?0次下載

    ESP8266或ESP32上的WiFi Webradio

    電子發(fā)燒友網(wǎng)站提供《ESP8266或ESP32上的WiFi Webradio.zip》資料免費(fèi)下載
    發(fā)表于 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溫度傳感器網(wǎng)絡(luò)的實(shí)現(xiàn)

    電子發(fā)燒友網(wǎng)站提供《基于ESP32WiFi溫度傳感器網(wǎng)絡(luò)的實(shí)現(xiàn).zip》資料免費(fèi)下載
    發(fā)表于 06-13 11:01 ?0次下載
    基于<b class='flag-5'>ESP32</b>的<b class='flag-5'>WiFi</b>溫度傳感器網(wǎng)絡(luò)的<b class='flag-5'>實(shí)現(xiàn)</b>

    基于ESP32+MicroPython實(shí)現(xiàn)聯(lián)網(wǎng)并進(jìn)行UDP通信

    使用 esp32 開(kāi)發(fā)程序,非常重要的功能就是使用 wifi,下面我們就講一下 esp32 連接 wifi 的方法。
    的頭像 發(fā)表于 06-13 17:05 ?6234次閱讀
    基于<b class='flag-5'>ESP32</b>+MicroPython<b class='flag-5'>實(shí)現(xiàn)</b>聯(lián)網(wǎng)并進(jìn)行UDP通信

    ESP32學(xué)習(xí)筆記:WiFi

    今天我們來(lái)說(shuō)說(shuō)ESP32WiFi。
    的頭像 發(fā)表于 07-15 16:20 ?3994次閱讀
    <b class='flag-5'>ESP32</b>學(xué)習(xí)筆記:<b class='flag-5'>WiFi</b>