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