基於ESP8266+BY8301語音模組的與山地車捉迷藏的小項目

基於ESP8266+BY8301語音模組的與山地車捉迷藏的小項目

寫在前面:

不知道大家有沒有經歷過,在茫茫車海中找不到自己山地車情況,針對這個痛點(開玩笑的),我做了個小玩意,純屬娛樂,拿出來,在疫情逐漸加劇的時候,給大家帶來一份歡樂。

B站有項目的概要影片,不喜歡文字的同學可以去看看,看完別忘了點贊哦!

B站影片地址

項目所有軟體與硬體支援都在我的碼雲倉庫里。

碼雲倉庫

下面就是這個項目的簡單介紹了。

硬體支援:

電路元件

ESP8266模組、BY8301語音控制晶片、flash晶片、功放晶片、揚聲器、電容、電阻、二極體、LED。

原理圖

原理部分比較簡單,就是連一連控制的IO引腳,別的好像也沒什麼要注意的。

PCB

大家想復現的時候,我建議把電阻、電容的封裝換成最大號的,我第一次沒經驗,瞎弄,焊接的時候可是廢了老鼻子勁了。

真的是吃一塹長一智。

打樣

嘉立創,免費打樣,一個月一個用戶有兩次機會。

要求10cm×10cm以內,二層板,四層板,都可以,顏色可任選,我選了黑色(因為酷),因此我等了差不多有兩周時間(綠色的最快),還碰到嘉立創伺服器崩潰,維護了兩天。

焊接完成

看著還可以,但這已經不知道是焊接的第幾個板子了,中間焊不好,老是把焊盤給帶下來,最後直接用0歐姆的電阻當飛線給連起來了,再次重申:在空間允許的情況下,一定要選大封裝,要分散開布置,我的血淚教訓!!

接下來就是軟體部分了。

軟體支援:

開發平台

Arduino平台,大量的集成庫,賊方便~

邏輯控制部分程式碼

程式碼分為兩部分,一部分燒錄直接燒錄到ESP8266,用來構建個網路伺服器端。


#include <ESP8266WiFi.h>      // 本程式使用ESP8266WiFi庫
#include <ESP8266WiFiMulti.h> // 本程式使用ESP8266WiFiMulti庫
#include <ESP8266WebServer.h> // 本程式使用ESP8266WebServer庫
#include <FS.h>               // 本程式使用SPIFFS庫

ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti對象,對象名稱是'wifiMulti'
 
ESP8266WebServer esp8266_server(80);    // 建立網路伺服器對象,該對象用於響應HTTP請求。監聽埠(80)

int button1Pin = D1; 
int button2Pin = D2;
int button3Pin = D3;
int button4Pin = D4;
int button5Pin = D5;
int button6Pin = D6;
                                   
void setup(){
  Serial.begin(9600);        
  Serial.println("");
  
  pinMode(LED_BUILTIN, OUTPUT);      // 初始化NodeMCU控制板載LED引腳為OUTPUT
  pinMode(button1Pin, OUTPUT);
  pinMode(button2Pin, OUTPUT);
  pinMode(button3Pin, OUTPUT);
  pinMode(button4Pin, OUTPUT);
  pinMode(button5Pin, OUTPUT);
  pinMode(button6Pin, OUTPUT);
  
  digitalWrite(button1Pin,HIGH);
  digitalWrite(button2Pin,HIGH);
  digitalWrite(button3Pin,HIGH);
  digitalWrite(button4Pin,HIGH);
  digitalWrite(button5Pin,HIGH);
  digitalWrite(button6Pin,HIGH);
  
  //通過addAp函數存儲  WiFi名稱       WiFi密碼
  wifiMulti.addAP("iron2222", "184******009"); // 將需要連接的一系列WiFi ID和密碼輸入這裡
  wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再啟動後會掃描當前網路
  wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 環境查找是否有這裡列出的WiFi ID。如果有
  Serial.println("Connecting ...");                            // 則嘗試使用此處存儲的密碼進行連接。
 
  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 在當前環境中搜索addAP函數所存儲的WiFi
    delay(1000);                             // 如果搜到多個存儲的WiFi那麼NodeMCU
    Serial.print(i++); Serial.print('.');                       // 將會連接訊號最強的那一個WiFi訊號。
  }                                          
                                         
  // WiFi連接成功後將通過串口監視器輸出連接成功資訊 
  Serial.println('\n');                     // WiFi連接成功後
  Serial.print("Connected to ");            // NodeMCU將通過串口監視器輸出。
  Serial.println(WiFi.SSID());              // 連接的WiFI名稱
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址

  if(SPIFFS.begin()){                       // 啟動快閃記憶體文件系統
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
  
  esp8266_server.on("/1-Control", handle1Control); // 告知系統如何處理/1-Control請求
  esp8266_server.on("/2-Control", handle2Control);
  esp8266_server.on("/3-Control", handle3Control);
  esp8266_server.on("/4-Control", handle4Control);
  esp8266_server.on("/5-Control", handle5Control);
  esp8266_server.on("/6-Control", handle6Control);
       
  esp8266_server.onNotFound(handleUserRequest);        // 告知系統如何處理其它用戶請求     
  
  esp8266_server.begin();                   // 啟動網站服務                                  
  Serial.println("HTTP server started");    
}

void loop(){
  esp8266_server.handleClient();  //處理用戶請求
  digitalWrite(LED_BUILTIN,HIGH);
}                                

// 處理/1-Control請求  
void handle1Control(){
   digitalWrite(button1Pin,!digitalRead(button1Pin));
   delay(500);
   digitalWrite(button1Pin,HIGH);
 
   esp8266_server.sendHeader("Location", "/yuyinctrl.html");       
   esp8266_server.send(303);  
}
void handle2Control(){
   digitalWrite(button2Pin,!digitalRead(button2Pin));
   delay(500);
   digitalWrite(button2Pin,HIGH);
 
   esp8266_server.sendHeader("Location", "/yuyinctrl.html");       
   esp8266_server.send(303);  
}
void handle3Control(){
   digitalWrite(button3Pin,!digitalRead(button3Pin));
   delay(500);
   digitalWrite(button3Pin,HIGH);
 
   esp8266_server.sendHeader("Location", "/yuyinctrl.html");       
   esp8266_server.send(303);  
}
void handle4Control(){
   digitalWrite(button4Pin,!digitalRead(button4Pin));
   delay(500);
   digitalWrite(button4Pin,HIGH);
 
   esp8266_server.sendHeader("Location", "/yuyinctrl.html");       
   esp8266_server.send(303);  
}
void handle5Control(){
   digitalWrite(button5Pin,!digitalRead(button5Pin));
   delay(500);
   digitalWrite(button5Pin,HIGH);
 
   esp8266_server.sendHeader("Location", "/yuyinctrl.html");       
   esp8266_server.send(303);  
}
void handle6Control(){
   digitalWrite(button6Pin,!digitalRead(button6Pin));
   delay(500);
   digitalWrite(button6Pin,HIGH);
 
   esp8266_server.sendHeader("Location", "/yuyinctrl.html");       
   esp8266_server.send(303);  
}

                                                                     
// 處理用戶瀏覽器的HTTP訪問
void handleUserRequest() {         
     
  // 獲取用戶請求資源(Request Resource)
  String reqResource = esp8266_server.uri();
  Serial.print("reqResource: ");
  Serial.println(reqResource);
  
  // 通過handleFileRead函數處處理用戶請求資源
  bool fileReadOK = handleFileRead(reqResource);

  // 如果在SPIFFS無法找到用戶訪問的資源,則回復404 (Not Found)
  if (!fileReadOK){                                                 
    esp8266_server.send(404, "text/plain", "404 Not Found"); 
  }
}

bool handleFileRead(String resource) {            //處理瀏覽器HTTP訪問

  if (resource.endsWith("/")) {                   // 如果訪問地址以"/"為結尾
    resource = "/index.html";                     // 則將訪問地址修改為/index.html便於SPIFFS訪問
  } 
  
  String contentType = getContentType(resource);  // 獲取文件類型
  
  if (SPIFFS.exists(resource)) {                     // 如果訪問的文件可以在SPIFFS中找到
    File file = SPIFFS.open(resource, "r");          // 則嘗試打開該文件
    esp8266_server.streamFile(file, contentType);// 並且將該文件返回給瀏覽器
    file.close();                                // 並且關閉文件
    return true;                                 // 返回true
  }
  return false;                                  // 如果文件未找到,則返回false
}

// 獲取文件類型
String getContentType(String filename){
  if(filename.endsWith(".htm")) return "text/html";
  else if(filename.endsWith(".html")) return "text/html";
  else if(filename.endsWith(".css")) return "text/css";
  else if(filename.endsWith(".js")) return "application/javascript";
  else if(filename.endsWith(".png")) return "image/png";
  else if(filename.endsWith(".gif")) return "image/gif";
  else if(filename.endsWith(".jpg")) return "image/jpeg";
  else if(filename.endsWith(".ico")) return "image/x-icon";
  else if(filename.endsWith(".xml")) return "text/xml";
  else if(filename.endsWith(".pdf")) return "application/x-pdf";
  else if(filename.endsWith(".zip")) return "application/x-zip";
  else if(filename.endsWith(".gz")) return "application/x-gzip";
  return "text/plain";
}

網頁構建程式碼

主頁面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title>語音模組控制</title>
</head>
<body>
	<center>
	<a href="//gitee.com/iron2222/esp8266" target="_blank"><img src="/img/lalala.png" alt="iron2222"></a>
	<h1>歡迎來到我的小家!</h1>
	<p><a href="yuyinctrl.html">前往語音控制頁面</a></p>
	<p>此頁面用於演示如何通過網頁按鈕來控制語音播放。</p>
    <p>詳情請參考我的碼雲倉庫: <a href="//gitee.com/iron2222/esp8266" target="_blank">//gitee.com/iron2222/esp8266</a> 
	</center>
</body>

</html>

語音控制頁面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title>語音模組控制</title>
</head> 
<body>
	<center>
	<h1>語音模組選擇</h1>
	<p>通過以下按鍵,您可以選擇所需要播放的語音</p>
   <form action="1-Control"><input type="submit" value="語音1"style="width:100px;height:60px">
   </form>
   <br>
   <form action="2-Control"><input type="submit" value="語音2"style="width:100px;height:60px">
   </form>
   <br>
   <form action="3-Control"><input type="submit" value="語音3"style="width:100px;height:60px">
   </form>
   <br>
   <form action="4-Control"><input type="submit" value="語音4"style="width:100px;height:60px">
   </form>
   <br>
   <form action="5-Control"><input type="submit" value="語音5"style="width:100px;height:60px">
   </form>
   <br>
   <form action="6-Control"><input type="submit" value="語音6"style="width:100px;height:60px">
   </form>
   <br>
   <form action="index.html"><input type="submit" value="返回首頁"style="width:100px;height:60px">
   </form>
   	<p>此頁面用於演示如何通過網頁按鈕來控制語音播放。</p>
    <p>詳情請參考我的碼雲網址: <a href="//gitee.com/iron2222/esp8266" target="_blank">//gitee.com/iron2222/esp8266</a> 
   </center>
</body>

</html>

網頁效果展示


網頁文件和圖片資源是與要通過,ardunio直接上傳到你的ESP8266這個板子裡面的。具體方式大家可以參考太極創客網站,裡面的教程說的相當清楚。附上地址吧:

太極創客

以上便是軟體的所有內容。

實際效果演示:

演示效果大家可以去看我那個影片,因為使用的是wifi連接,所以不建議室內,室外50~100m還是可以連接上的,但可能你得換一個功率相當大的喇叭,才能聽得到你的山地車的回應。

總結

第一次從頭到尾做一個小東西,收穫很多,教訓也很多,加油~

祝大家早安,午安和晚安!!!