arduino 語音音箱 :語音控制、MP3播放、報時、回復溫濕度情況
效果圖
線路圖
包裝后的效果
功能
需要材料
- arduino板
- MP3播放模塊及喇叭
- 時鍾模塊
- 溫濕度模塊
- 語音識別模塊
- 面包板及其他線材、電阻
- TF卡(用於儲存音頻)
原理
- 通過語音識別模塊對使用者的語音指令進行與設置的指令匹配,匹配成功調用MP3模塊播放對應音樂。
- 因為MP3播放需要一定的delay,但是由於系統自帶的delay會阻塞arduino的操作,因此需要將大的延遲拆分成許多小塊,每執行一個小塊,就調用一次語音識別模塊,使其能在有指令后能快速反應。
- MP3模塊的使用需要按指定格式,例如文件名需要按照指定格式命名。中間有部分音頻做為音箱的人機交互的對話。
理論知識
Arduino是一個基於開放原始碼的軟硬件平台,可用來開發獨立運作、並具互動性的電子產品,也可以開發與PC相連的周邊裝置,同時能在運行時與PC上的軟件進行交互。為了測量正弦波電壓有效值,首先我們設計了單電源供電的半波整流電路,並進行整流濾波輸出,然后選擇了通過Arduino設計了讀取電壓有效值的程序,並實現使用此最小系統來測量和顯示電壓有效值。在頻率和直流電壓幅度限定在小范圍的情況下,最小系統的示數基本和毫伏表測量的值相同。根據交流電壓有效值的定義,運用集成運放和設計的Arduino最小系統的結合,實現了運用少量元器件對交流電壓有效值的測量。
實驗目的
在很多人眼里依舊是新潮玩意的智能音箱,往往具備智能家居聲控中心和個人助理兩大核心功能。通過智能音箱可以實現對家居中的智能電器進行聯網和語音控制,同樣也可完成日常安排、訂餐廳、叫車、閱讀、翻譯、通話等類似個人助理的功能。智能音箱的優勢在於其能夠通過語音實現“隔空操作”,在人們不方便使用手機或其他電子設備時提供幫助。
智能音箱首先承載的功能是音樂播放,其次是聯網智能,因此,音樂娛樂市場的繁榮程度是音箱普及的前提條件。
通過智能音箱可以控制智能燈泡、窗簾、安全監控等智能家居產品,因此未來智能音箱的普及將大大提升家庭語音交互的使用頻率,從而帶動智能家居行業進入實質性發展階段。
主要功能
1、開機語音:歡迎使用語音音箱;
2、詢問溫濕度情況:她會及時做出反應,播報當前溫度和濕度;
3、命令隨機:會隨機播放任何一首音樂,TF里共存儲20首音樂;
4、命令暫停:暫停當前正在放的音樂;
5、命令繼續,繼續播放已暫停的歌;
6、加大/降低音量:在播放過程中,可以用語音控制加大或者調低音量;
7、上一首/下一首:切換前一首或下一首歌曲。
前期准備知識
C語言
Arduino使用C/C++編寫程序,雖然C++兼容C語言,但這是兩種語言,C語言是一種面向過程的編程語言,C++是一種面向對象的編程語言。早期的Arduino核心庫使用C語言編寫,后來引進了面向對象的思想,目前最新的Arduino核心庫采用C與C++混合編寫而成。
通常我們說的Arduino語言,是指Arduino核心庫文件提供的各種應用程序編程接口(Application Programming Interface,簡稱API)的集合。這些API是對更底層的單片機支持庫進行二次封裝所形成的。例如,使用AVR單片機的Arduino的核心庫是對AVR-Libc(基於GCC的AVR支持庫)的二次封裝。
傳統開發方式中,你需要厘清每個寄存器的意義及之間的關系,然后通過配置多個寄存器來達到目的。
代碼
//引入依賴
#include <LiquidCrystal.h>
#include <ld3320.h>
#include <stdlib.h>
#include <SoftwareSerial.h> //軟串口頭文件名
#include <DFPlayer_Mini_Mp3.h> //MP3頭文件名
#include <Wire.h>
#include <RTClib.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 14
#define DHTTYPE DHT11
#define Led A1
#define MP3GO A3
void showTimeAndDHT();
void play();
void defa();
int recoderRun();
int myDelay(int t);
int random_play();
int getRandom();
RTC_DS1307 RTC;
VoiceRecognition Voice;
DHT dht(DHTPIN, DHTTYPE);
byte heart[8] = {0b00100, 0b01000, 0b11000, 0b11111, 0b00011, 0b00010, 0b00100, 0b00000};
int theVo = 25;
// 初始化針腳
const int rs = 3, en = 5, d4 = 6, d5 = 7, d6 = 8, d7 = 10;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int myDelay(int t)
{
int c = 0;
c = t / 100;
for (int i = 0; i < c; i++)
{
delay(100);
if (!recoderRun())
return 0;
}
return 1;
}
int getRandom()
{
int i = 30;
randomSeed(RTC.now().second());
i = random(53);
while ((i >= 0 && i <= 10) || (i >= 21 && i <= 29))
{
i = random(53);
}
return i;
}
int random_play()
{
int i = 30;
i = getRandom();
mp3_play(i);
// if (!myDelay(300000))
// return 0;
delay(5000);
while(1)
{
if(!myDelay(1500)) return 0;
if(digitalRead(MP3GO) == HIGH)
{
i = getRandom();
mp3_play(i);
}
}
return 1;
}
void setup()
{
// 設定LCD 的行列數目(2 x 16)
pinMode(MP3GO, INPUT);
lcd.begin(16, 2);
Serial.begin(9600);
Wire.begin();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__));
lcd.createChar(1, heart);
lcd.write(1);
//Serial.println(F("DHTxx test!"));
dht.begin();
Serial.begin(9600); //串口波特率,9600
mp3_set_serial(Serial); //定義MP3串口為Arduino串口。
mp3_set_volume(theVo); //設置音量。
Voice.init(); //初始化VoiceRecognition模塊
Voice.addCommand("kai deng", 0); //添加指令,參數(指令內容,指令標簽(可重復))
Voice.addCommand("guan deng", 1); //添加指令,參數(指令內容,指令標簽(可重復))
Voice.addCommand("xia yi shou", 2);
Voice.addCommand("shang yi shou", 3);
Voice.addCommand("zhan ting", 4);
Voice.addCommand("ji xu", 5);
Voice.addCommand("ting zhi", 6);
Voice.addCommand("sui ji yin yue", 7);
Voice.addCommand("xian zai shi jian", 8);
Voice.addCommand("wen shi du qing kuang", 9);
Voice.addCommand("xian zai wen shi du", 10);
Voice.addCommand("jia da yin liang", 11);
Voice.addCommand("jiang di yin liang", 12);
Voice.addCommand("bo fang yin yue ba", 13);
Voice.addCommand("guan ji",14);
Voice.start(); //開始識別
pinMode(Led, OUTPUT); //初始化LED引腳為輸出模式
digitalWrite(Led, LOW); //LED引腳低電平
//showTimeAndDHT();
defa();
play();
}
void showTimeAndDHT()
{
lcd.setCursor(0, 0);
lcd.write(1);
float h = dht.readHumidity();
float t = dht.readTemperature();
float hic = dht.computeHeatIndex(t, h, false);
lcd.print('T');
lcd.print(':');
lcd.print(hic);
lcd.print(' ');
lcd.print('H');
lcd.print(':');
lcd.print(h);
lcd.print(' ');
lcd.setCursor(0, 1);
DateTime now = RTC.now();
lcd.print(now.year());
lcd.print('/');
lcd.print(now.month());
lcd.print('/');
lcd.print(now.day());
lcd.print(' ');
lcd.print(now.hour());
lcd.print(':');
lcd.print(now.minute());
}
void play()
{
mp3_play(23);
delay(2000);
}
int whatTH()
{
int h = 0, m = 0, hic = 0, t = 0;
if (!myDelay(1000))
return 0;
mp3_stop();
showTimeAndDHT();
t = dht.readTemperature();
h = (int)dht.readHumidity();
hic = (int)dht.computeHeatIndex(t, h, false);
mp3_stop();
mp3_play(26);
if (!myDelay(2000))
return 0;
if (t / 10 > 0)
{
mp3_play(t / 10);
if (!myDelay(600))
return 0;
mp3_play(10);
if (!myDelay(600))
return 0;
}
if (t % 10 != 0)
{
mp3_play(t % 10);
if (!myDelay(600))
return 0;
}
if (t == 0)
{
mp3_play(2);
if (!myDelay(600))
return 0;
mp3_play(10);
if (!myDelay(600))
return 0;
mp3_play(4);
if (!myDelay(600))
return 0;
}
if (!myDelay(1000))
return 0;
mp3_play(24);
myDelay(800);
if (h / 10 > 0)
{
mp3_play(h / 10);
if (!myDelay(600))
return 0;
mp3_play(10);
if (!myDelay(600))
return 0;
}
if (h % 10 != 0)
{
mp3_play(h % 10);
if (!myDelay(600))
return 0;
}
mp3_stop();
defa();
Voice.read();
return 1;
};
int whatTime()
{
int h = 0, m = 0, hic = 0, t = 0;
showTimeAndDHT();
mp3_stop();
if (!myDelay(1000))
return 0;
mp3_play(25);
if (!myDelay(2000))
return 0;
h = (int)RTC.now().hour();
if (h / 10 > 0)
{
mp3_play(h / 10);
if (!myDelay(600))
return 0;
mp3_play(10);
if (!myDelay(600))
return 0;
}
if (h % 10 != 0)
{
mp3_play(h % 10);
if (!myDelay(600))
return 0;
}
if (h == 0)
{
mp3_play(2);
if (!myDelay(600))
return 0;
mp3_play(10);
if (!myDelay(600))
return 0;
mp3_play(4);
if (!myDelay(600))
return 0;
}
mp3_play(21);
if (!myDelay(600))
return 0;
m = (int)RTC.now().minute();
if (m / 10 > 0)
{
mp3_play(m / 10);
if (!myDelay(600))
return 0;
mp3_play(10);
if (!myDelay(600))
return 0;
}
if (m % 10 != 0)
{
mp3_play(m % 10);
if (!myDelay(600))
return 0;
}
if (m != 0)
{
mp3_play(22);
if (!myDelay(600))
return 0;
}
mp3_stop();
defa();
Voice.read();
return 1;
}
int recoderRun()
{
int h = 0, m = 0, hic = 0, t = 0;
switch (Voice.read()) //判斷識別
{
case 0: //若是指令“kai deng”
//digitalWrite(Led, HIGH); //點亮LED
break;
case 1: //若是指令“guan deng”
//digitalWrite(Led, LOW); //熄滅LED
break;
case 2:
//mp3_stop ();
mp3_play(28);
delay(2500);
Voice.read();
if (!random_play())
return 0;
break;
case 3:
//mp3_stop ();
mp3_prev();
break;
case 4:
mp3_pause();
break;
case 5:
mp3_play();
//mp3_random_play();
break;
case 6:
mp3_stop();
break;
case 13:
case 7:
mp3_play(29);
delay(2500);
Voice.read();
if (!random_play())
return 0;
break;
case 8:
whatTime();
defa();
break;
case 9:
case 10:
whatTH();
defa();
break;
case 11:
theVo += 2;
mp3_set_volume(theVo);
break;
case 12:
theVo -= 2;
mp3_set_volume(theVo);
break;
case 14:
Voice.reset();
default:
return 1;
break;
}
delay(100);
return 0;
}
void defa()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(1);
lcd.print("Intellgent MP3");
lcd.setCursor(0, 1);
lcd.print("la la la ~");
}
void loop()
{
recoderRun();
}
參考鏈接
【4】LD3320 Board