目录
先上视频:
资料提供
准备材料:
连接方式:
语音交互表情制作
ESP32代码部分
1.主函数
2.太空人时钟esp32_101
3.配网与时钟布局
4.与语音模块通信
5.初始化时钟时间
LU-ASR01模块代码
先上视频:
esp32+1.3寸屏幕语音交互
资料提供
百度网盘
链接:https://pan.baidu.com/s/14NO9VFD0rBgw6YYv1eYk3w?pwd=psbn
提取码:psbn
准备材料:
nodemcu开发板一个
1.3寸IPS模块一个
继电器一个
舵机俩个+舵机云台
LU-ASR01鹿小班智能语音识别模块 离线识别
购买需要选择带喇叭的
杜邦线 一样买点 都会用得到
温湿度模块 DHT11
12V小灯泡
连接方式:
esp32S 屏幕
GND GND
3.3V VCC
14 SCL
15 SDA
33 RES
27 DC
esp32S 语音模块
16 IO8
P17 IO7
继电器 语音模块
信号线 IO1
舵机信号线 语音模块
舵机1 I02
舵机2 IO3
温湿度DHT11 语音模块
信号线 DHT
具体实物图连接方式如下:
语音交互表情制作
制作链接:http://tomeko.net/online_tools/file_to_hex.php?lang=en
将240x240大小的图片添加进去,会生成一个数组文件,将数组文件添加到esp266+1.3寸屏幕语音交互\语音模块与1.3寸屏幕交互\esp32_101\img\face.h文件里面
注意这里的数组名需要在语音模块和esp32中对应位置同时进行修改文章来源:https://www.toymoban.com/news/detail-774120.html
文章来源地址https://www.toymoban.com/news/detail-774120.html
ESP32代码部分
1.主函数
// UDP时间服务初始化
void UDPTimeInit(){
Serial.println("Starting UDP"); //连接时间服务器
Udp.begin(localPort);
Serial.print("Local port: ");
// Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(300); //时间校准间隔
}
time_t getNtpTime() //获取NTP时间
{
IPAddress ntpServerIP; //NTP服务器的IP地址
while (Udp.parsePacket() > 0) ; //之前的数据没有处理的话一直等待 discard any previously received packets
WiFi.hostByName(ntpServerName, ntpServerIP); //从网站名获取IP地址
sendNTPpacket(ntpServerIP); //发送数据包
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket(); //接收数据
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); //从缓冲区读取数据
unsigned long secsSince1900;
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; //没获取到数据的话返回0
}
void sendNTPpacket(IPAddress &address) //发送数据包到NTP服务器
{
memset(packetBuffer, 0, NTP_PACKET_SIZE); //缓冲区清零
packetBuffer[0] = 0b11100011; //LI, Version, Mode 填充缓冲区数据
packetBuffer[1] = 0; //Stratum, or type of clock
packetBuffer[2] = 6; //Polling Interval
packetBuffer[3] = 0xEC; //Peer Clock Precision
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123); //NTP服务器端口123
Udp.write(packetBuffer, NTP_PACKET_SIZE); //发送udp数据
Udp.endPacket(); //发送结束
}
String week() //星期
{
String wk[7] = {"日","一","二","三","四","五","六"};
String s = "周" + wk[weekday()-1];
return s;
}
String monthDay() //月日
{
String s = String(month());
s = s + "月" + day() + "日";
return s;
}
String hourMinute() //时分
{
String s = num2str(hour());
s = s + ":" + num2str(minute());
return s;
}
String num2str(int digits) //数字转换成字符串,保持2位显示
{
String s = "";
if (digits < 10)
s = s + "0";
s = s + digits;
return s;
}
void printDigits(int digits) //打印时间数据
{
Serial.print(":");
if (digits < 10) //打印两位数字
Serial.print('0');
Serial.print(digits);
}
2.太空人时钟esp32_101
#include "main.h"
#define VERSION "V101"
void setup()
{
mySoftwareSerial.begin(9600);
Serial.begin(115200); //初始化串口
Serial.println(); //打印回车换行
TFTDisplayInit(); //初始化TFT
connect_wifi(); //联网处理
UDPTimeInit(); //初始化时间服务
MainView(); //太空表主结构
// getCityCode(); //通过IP地址获取城市代码
CityWeaterShow(); //获取天气信息
weatherOldTime = millis();
}
void loop()
{
SoftSerialRx();
if(dhStatus != 0){
runImg(dhStatus);
}else{
//时钟动画
taikongren();
}
}
//太空人业务
void taikongren(){
//主界面动画
if (now() != oldTime){ //如果本次数据和上次不一样的话,刷新
oldTime = now();
TimeUpdateShow();
}
if(millis() - weatherUpdateTime > 600000){ //10分钟更新一次天气
weatherUpdateTime = millis();
CityWeaterShow();
}
weatherShow(); //天气数据滚动显示
jpgSlideShow();
}
3.配网与时钟布局
void connect_wifi() //联网
{
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); //用固定的账号密码连接网络
while (WiFi.status() != WL_CONNECTED) { //未连接上的话
for (uint8_t n = 0; n < 10; n++){ //每500毫秒检测一次状态
PowerOn_Loading(50);
}
}
while(loadNum < 194){ //让动画走完
PowerOn_Loading(1);
}
Serial.print("\nWiFi connected to: ");
Serial.println(WIFI_SSID);
Serial.print("IP: ");
Serial.println(WiFi.localIP()); //得到IP地址
}
void PowerOn_Loading(uint8_t delayTime) //开机联网显示的进度条,输入延时时间
{
clk.setColorDepth(8);
clk.createSprite(200, 50); //创建Sprite
clk.fillSprite(0x0000); //填充颜色
clk.drawRoundRect(0,0,200,16,8,0xFFFF); //画一个圆角矩形
clk.fillRoundRect(3,3,loadNum,10,5,0xFFFF); //画一个填充的圆角矩形
clk.setTextDatum(CC_DATUM); //显示对齐方式
clk.setTextColor(TFT_GREEN, 0x0000); //文本的前景色和背景色
clk.drawString("Connecting to WiFi",100,40,2); //显示文本
clk.pushSprite(20,110); //Sprite中内容一次推向屏幕
clk.deleteSprite(); //删除Sprite
loadNum += 1; //进度条位置变化,直到加载完成
if(loadNum>=194){
loadNum = 194;
}
delay(delayTime);
}
void TimeUpdateShow() //时间显示
{
clk.setColorDepth(8);
//--------------------中间时间区显示开始--------------------
//时分
clk.createSprite(140, 48); //创建Sprite,先在Sprite内存中画点,然后将内存中的点一次推向屏幕,这样刷新比较快
clk.fillSprite(bgColor); //背景色
//clk.loadFont(FxLED_48);
clk.setTextDatum(CC_DATUM); //显示对齐方式
clk.setTextColor(TFT_BLACK, bgColor); //文本的前景色和背景色
clk.drawString(hourMinute(),70,24,7); //绘制时和分
//clk.unloadFont();
clk.pushSprite(28,40); //Sprite中内容一次推向屏幕
clk.deleteSprite(); //删除Sprite
//秒
clk.createSprite(40, 32);
clk.fillSprite(bgColor);
clk.loadFont(FxLED_32); //加载字体
clk.setTextDatum(CC_DATUM);
clk.setTextColor(TFT_BLACK, bgColor);
clk.drawString(num2str(second()),20,16);
clk.unloadFont(); //卸载字体
clk.pushSprite(170,60);
clk.deleteSprite();
//--------------------中间时间区显示结束--------------------
//--------------------底部时间区显示开始--------------------
clk.loadFont(ZdyLwFont_20); //加载汉字字体
//星期
clk.createSprite(58, 32);
clk.fillSprite(bgColor);
clk.setTextDatum(CC_DATUM);
clk.setTextColor(TFT_BLACK, bgColor);
clk.drawString(week(),29,16); //周几
clk.pushSprite(1,168);
clk.deleteSprite();
//月日
clk.createSprite(98, 32);
clk.fillSprite(bgColor);
clk.setTextDatum(CC_DATUM);
clk.setTextColor(TFT_BLACK, bgColor);
clk.drawString(monthDay(),49,16); //几月几日
clk.pushSprite(61,168);
clk.deleteSprite();
clk.unloadFont(); //卸载字体
//--------------------底部时间区显示结束--------------------
}
void getCityCode() //发送HTTP请求并且将服务器响应通过串口输出
{
String URL = "http://wgeo.weather.com.cn/ip/?_="+String(now());
httpClient.begin(Client,URL); //配置请求地址。此处也可以不使用端口号和PATH而单纯的
httpClient.setUserAgent("esp8266"); //用户代理版本,其实没什么用 最重要是后端服务器支持
//httpClient.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");//设置请求头中的User-Agent
httpClient.addHeader("Referer", "http://www.weather.com.cn/");
int httpCode = httpClient.GET(); //启动连接并发送HTTP请求
Serial.print("Send GET request to URL: ");
Serial.println(URL);
if (httpCode == HTTP_CODE_OK) { //如果服务器响应OK则从服务器获取响应体信息并通过串口输出
String str = httpClient.getString();
int aa = str.indexOf("id=");
if (aa > -1){ //应答包里找到ID了
cityCode = str.substring(aa+4,aa+4+9); //9位长度
Serial.println(cityCode);
CityWeaterShow(); //显示天气信息
weatherOldTime = millis();
}
else{ //没有找到ID
Serial.println("获取城市代码失败");
}
}
else{
Serial.println("请求城市代码错误:");
Serial.println(httpCode);
}
httpClient.end(); //关闭与服务器连接
}
void CityWeaterShow() //获取城市天气
{
String URL = "http://d1.weather.com.cn/weather_index/" + cityCode + ".html?_="+String(now());
httpClient.begin(Client,URL); //配置请求地址。
httpClient.setUserAgent("esp8266"); //用户代理版本,其实没什么用 最重要是后端服务器支持
//httpClient.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");//设置请求头中的User-Agent
httpClient.addHeader("Referer", "http://www.weather.com.cn/");
int httpCode = httpClient.GET(); //启动连接并发送HTTP请求
Serial.print("Send GET request to URL: ");
Serial.println(URL);
if (httpCode == HTTP_CODE_OK) { //如果服务器响应OK则从服务器获取响应体信息并通过串口输出
String str = httpClient.getString();
int indexStart = str.indexOf("weatherinfo\":");//寻找起始和结束位置
int indexEnd = str.indexOf("};var alarmDZ");
String jsonCityDZ = str.substring(indexStart+13,indexEnd);//复制字符串
Serial.println(jsonCityDZ);
indexStart = str.indexOf("dataSK ="); //寻找起始和结束位置
indexEnd = str.indexOf(";var dataZS");
String jsonDataSK = str.substring(indexStart+8,indexEnd);//复制字符串
Serial.println(jsonDataSK);
indexStart = str.indexOf("\"f\":["); //寻找起始和结束位置
indexEnd = str.indexOf(",{\"fa");
String jsonFC = str.substring(indexStart+5,indexEnd);//复制字符串
Serial.println(jsonFC);
weaterData(&jsonCityDZ,&jsonDataSK,&jsonFC); //显示天气信息
Serial.println("获取成功");
}
else {
Serial.println("请求城市天气错误:");
Serial.print(httpCode);
}
httpClient.end(); //关闭与服务器连接
}
void weaterData(String *cityDZ,String *dataSK,String *dataFC)//天气信息写到屏幕上
{
DynamicJsonDocument doc(512);
deserializeJson(doc, *dataSK);
JsonObject sk = doc.as<JsonObject>();
clk.setColorDepth(8);
clk.loadFont(ZdyLwFont_20); //加载汉字字体
//温度显示
clk.createSprite(54, 32); //创建Sprite
clk.fillSprite(bgColor); //填充颜色
clk.setTextDatum(CC_DATUM); //显示对齐方式
clk.setTextColor(TFT_BLACK, bgColor); //文本的前景色和背景色
clk.drawString(sk["temp"].as<String>()+"℃",27,16);//显示文本
clk.pushSprite(185,168); //Sprite中内容一次推向屏幕
clk.deleteSprite(); //删除Sprite
//城市名称显示
clk.createSprite(88, 32);
clk.fillSprite(bgColor);
clk.setTextDatum(CC_DATUM);
clk.setTextColor(TFT_BLACK, bgColor);
clk.drawString(sk["cityname"].as<String>(),44,16);
clk.pushSprite(151,1);
clk.deleteSprite();
//PM2.5空气指数显示
uint16_t pm25BgColor = tft.color565(156,202,127);//优
String aqiTxt = "优";
int pm25V = sk["aqi"];
if (pm25V > 200){
pm25BgColor = tft.color565(136,11,32); //重度,显示颜色和空气质量程度
aqiTxt = "重度";
}
else if (pm25V > 150){
pm25BgColor = tft.color565(186,55,121); //中度
aqiTxt = "中度";
}
else if (pm25V > 100){
pm25BgColor = tft.color565(242,159,57); //轻
aqiTxt = "轻度";
}
else if (pm25V > 50){
pm25BgColor = tft.color565(247,219,100); //良
aqiTxt = "良";
}
clk.createSprite(50, 24);
clk.fillSprite(bgColor);
clk.fillRoundRect(0,0,50,24,4,pm25BgColor);
clk.setTextDatum(CC_DATUM);
clk.setTextColor(0xFFFF);
clk.drawString(aqiTxt,25,13);
clk.pushSprite(5,130);
clk.deleteSprite();
//湿度显示
clk.createSprite(56, 24);
clk.fillSprite(bgColor);
clk.setTextDatum(CC_DATUM);
clk.setTextColor(TFT_BLACK, bgColor);
clk.drawString(sk["SD"].as<String>(),28,13);
//clk.drawString("100%",28,13);
clk.pushSprite(180,130);
clk.deleteSprite();
scrollText[0] = "实时天气 " + sk["weather"].as<String>();//滚动显示的数据缓冲区
scrollText[1] = "空气质量 " + aqiTxt;
scrollText[2] = "风向 " + sk["WD"].as<String>()+sk["WS"].as<String>();
//左上角滚动字幕
deserializeJson(doc, *cityDZ);
JsonObject dz = doc.as<JsonObject>();
//Serial.println(sk["ws"].as<String>());
//String aa = "今日天气:" + dz["weather"].as<String>() + ",温度:最低" + dz["tempn"].as<String>() + ",最高" + dz["temp"].as<String>() + " 空气质量:" + aqiTxt + ",风向:" + dz["wd"].as<String>() + dz["ws"].as<String>();
//Serial.println(aa);
scrollText[3] = "今日" + dz["weather"].as<String>();
deserializeJson(doc, *dataFC);
JsonObject fc = doc.as<JsonObject>();
scrollText[4] = "最低温度"+fc["fd"].as<String>()+"℃";
scrollText[5] = "最高温度"+fc["fc"].as<String>()+"℃";
clk.unloadFont(); //卸载字体
}
void weatherShow() //天气滚动条显示
{
if(millis() - weatherOldTime > 2500){ //2.5秒切换一次显示内容
if(scrollText[Dis_Count]){ //如果滚动显示缓冲区有数据
clkb.setColorDepth(8);
clkb.loadFont(ZdyLwFont_20); //加载汉字字体
// for(int pos = 24; pos>0; pos--){ //24点,每次移动一个点,从下往上移
// Dis_Scroll(pos);
// }
//滚动显示修改为静态显示,滚动的时候太空人会卡顿
clkb.createSprite(148, 24); //创建Sprite,先在Sprite内存中画点,然后将内存中的点一次推向屏幕,这样刷新比较快
clkb.fillSprite(bgColor); //背景色
clkb.setTextWrap(false);
clkb.setTextDatum(CC_DATUM); //显示对齐方式
clkb.setTextColor(TFT_BLACK, bgColor); //文本的前景色和背景色
clkb.drawString(scrollText[Dis_Count],74,12);//打显示内容
clkb.pushSprite(2,4); //Sprite中内容一次推向屏幕
clkb.deleteSprite(); //删除Sprite
//clkb.deleteSprite(); //删除Sprite,这个我移动到Dis_Scroll函数里了
clkb.unloadFont(); //卸载字体
if (Dis_Count >= 5){ //总共显示五条信息
Dis_Count = 0; //回第一个
}
else{
Dis_Count += 1; //准备切换到下一个
}
//Serial.println(Dis_Count);
}
weatherOldTime = millis();
}
}
void Dis_Scroll(int pos){ //字体滚动
clkb.createSprite(148, 24); //创建Sprite,先在Sprite内存中画点,然后将内存中的点一次推向屏幕,这样刷新比较快
clkb.fillSprite(bgColor); //背景色
clkb.setTextWrap(false);
clkb.setTextDatum(CC_DATUM); //显示对齐方式
clkb.setTextColor(TFT_BLACK, bgColor); //文本的前景色和背景色
clkb.drawString(scrollText[Dis_Count],74,pos+12);//打显示内容
clkb.pushSprite(2,4); //Sprite中内容一次推向屏幕
clkb.deleteSprite(); //删除Sprite
}
void SoftSerialRx(){
String revData;
if(mySoftwareSerial.available()){
revData = mySoftwareSerial.readStringUntil('\n');
String val = "kaixin";
revData.trim();
Serial.println(revData);
Serial.println(revData.length());
Serial.println(val.length());
// if( val=="kaixin"){
// dhStatus =1;
// }
if( revData=="kaixin"){
dhStatus =1;
}
if(revData== "chongbai"){
dhStatus =2;
}
if(revData== "shuaku"){
dhStatus =3;
}
if(revData== "tiaopi"){
dhStatus = 4;
}
if(revData== "zhangsan"){
dhStatus = 5;
}
if(revData== "kongtiao"){
dhStatus = 6;
}
}
}
//开心表情
void kaixindh(){
TJpgDec.drawJpg(0,0,kaixin, sizeof(kaixin));//
delay(450);
TJpgDec.drawJpg(0,0,kaixin2, sizeof(kaixin2));//
delay(900);
}
//耍酷 表情
void shuakudh(){
TJpgDec.drawJpg(0,0,shuaku, sizeof(shuaku));//
delay(450);
TJpgDec.drawJpg(0,0,kaixin2, sizeof(kaixin2));//
delay(900);
}
//调皮 表情
void tiaopidh(){
TJpgDec.drawJpg(0,0,tiaopi, sizeof(tiaopi));//
delay(450);
TJpgDec.drawJpg(0,0,kaixin2, sizeof(kaixin2));//
delay(900);
}
//自定义 表情
void zidingyidh(){
TJpgDec.drawJpg(0,0,tiaopi, sizeof(tiaopi));//
delay(450);
TJpgDec.drawJpg(0,0,kaixin2, sizeof(kaixin2));//
delay(900);
}
//崇拜 表情
void chongbaidh(){
TJpgDec.drawJpg(0,0,chongbai, sizeof(chongbai));//
delay(450);
TJpgDec.drawJpg(0,0,kaixin2, sizeof(kaixin2));//
delay(900);
}
void runImg(int index){
tft.resetViewport();
if(index == 1){
tft.fillScreen(0xFFFF);
kaixindh();
}
if(index == 2){
tft.fillScreen(0xFFFF);
chongbaidh();
}
if(index == 3){
tft.fillScreen(0xFFFF);
shuakudh();
}
if(index == 4){
tft.fillScreen(0xFFFF);
tiaopidh();
}
if(index == 5){
tft.fillScreen(0xFFFF);
zidingyidh();
}
if(index == 6){
tft.fillScreen(0xFFFF);
tiaopidh();
}
tft.resetViewport();
CityWeaterShow();
dhStatus = 0;
MainView();
}
4.与语音模块通信
//初始化TFT
void TFTDisplayInit(){
tft.init(); //TFT初始化
tft.setRotation(0); //旋转角度0-3
tft.fillScreen(0x0000); //清屏tft.color565(255,6,31
tft.setTextColor(TFT_BLACK, bgColor); //设置字体颜色
//设置 TJpgDec
TJpgDec.setJpgScale(1); //设置放大倍数
TJpgDec.setSwapBytes(true); //交换字节
TJpgDec.setCallback(tft_output); //回调函数tft_output()
}
//显示回调函数
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
{
if (y >= tft.height()) return 0;
tft.pushImage(x, y, w, h, bitmap);
return 1;
}
// 太空表主结构
void MainView(){
TJpgDec.drawJpg(0,0,watchtop, sizeof(watchtop));//显示顶部图标 240*20
TJpgDec.drawJpg(0,220,watchbottom, sizeof(watchbottom));//显示底部图标 240*20
//绘制一个窗口
tft.setViewport(0, 20, 240, 200); //中间的显示区域大小
tft.fillScreen(0x0000); //清屏
tft.fillRoundRect(0,0,240,200,5,bgColor); //实心圆角矩形
//tft.resetViewport();
//绘制线框
// drawFastHLine 画横线
// drawFastVLine 画竖线
tft.drawFastHLine(0,34,240,TFT_BLACK); //这些坐标都是窗体内部坐标
tft.drawFastVLine(150,0,34,TFT_BLACK);
tft.drawFastHLine(0,166,240,TFT_BLACK);
tft.drawFastVLine(60,166,34,TFT_BLACK);
tft.drawFastVLine(160,166,34,TFT_BLACK);
TJpgDec.drawJpg(161,171,temperature, sizeof(temperature));//温度图标
TJpgDec.drawJpg(159,130,humidity, sizeof(humidity)); //湿度图标
}
void jpgSlideShow(){
int x=80,y=94,dt=30; //dt图片播放间隔时长
TJpgDec.drawJpg(x,y,i0, sizeof(i0));
delay(dt);
TJpgDec.drawJpg(x,y,i1, sizeof(i1));
delay(dt);
TJpgDec.drawJpg(x,y,i2, sizeof(i2));
delay(dt);
TJpgDec.drawJpg(x,y,i3, sizeof(i3));
delay(dt);
TJpgDec.drawJpg(x,y,i4, sizeof(i4));
delay(dt);
TJpgDec.drawJpg(x,y,i5, sizeof(i5));
delay(dt);
TJpgDec.drawJpg(x,y,i6, sizeof(i6));
delay(dt);
TJpgDec.drawJpg(x,y,i7, sizeof(i7));
delay(dt);
TJpgDec.drawJpg(x,y,i8, sizeof(i8));
delay(dt);
TJpgDec.drawJpg(x,y,i9, sizeof(i9));
delay(dt);
}
5.初始化时钟时间
// UDP时间服务初始化
void UDPTimeInit(){
Serial.println("Starting UDP"); //连接时间服务器
Udp.begin(localPort);
Serial.print("Local port: ");
// Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(300); //时间校准间隔
}
time_t getNtpTime() //获取NTP时间
{
IPAddress ntpServerIP; //NTP服务器的IP地址
while (Udp.parsePacket() > 0) ; //之前的数据没有处理的话一直等待 discard any previously received packets
WiFi.hostByName(ntpServerName, ntpServerIP); //从网站名获取IP地址
sendNTPpacket(ntpServerIP); //发送数据包
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket(); //接收数据
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); //从缓冲区读取数据
unsigned long secsSince1900;
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; //没获取到数据的话返回0
}
void sendNTPpacket(IPAddress &address) //发送数据包到NTP服务器
{
memset(packetBuffer, 0, NTP_PACKET_SIZE); //缓冲区清零
packetBuffer[0] = 0b11100011; //LI, Version, Mode 填充缓冲区数据
packetBuffer[1] = 0; //Stratum, or type of clock
packetBuffer[2] = 6; //Polling Interval
packetBuffer[3] = 0xEC; //Peer Clock Precision
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123); //NTP服务器端口123
Udp.write(packetBuffer, NTP_PACKET_SIZE); //发送udp数据
Udp.endPacket(); //发送结束
}
String week() //星期
{
String wk[7] = {"日","一","二","三","四","五","六"};
String s = "周" + wk[weekday()-1];
return s;
}
String monthDay() //月日
{
String s = String(month());
s = s + "月" + day() + "日";
return s;
}
String hourMinute() //时分
{
String s = num2str(hour());
s = s + ":" + num2str(minute());
return s;
}
String num2str(int digits) //数字转换成字符串,保持2位显示
{
String s = "";
if (digits < 10)
s = s + "0";
s = s + digits;
return s;
}
void printDigits(int digits) //打印时间数据
{
Serial.print(":");
if (digits < 10) //打印两位数字
Serial.print('0');
Serial.print(digits);
}
LU-ASR01模块代码
#include "asr.h"
#include "setup.h"
#include "myLib/asr_event.h"
#include "SoftwareSerial.h"
#include "myLib/luxiaoban.h"
uint32_t snid;
SoftwareSerial mySerial1(6,7);
DHTxx _component(9);
QueueHandle_t play = xQueueCreate(5,4);
float temp = 255;
uint8_t hum = 255;
uint32_t var = 0;
uint32_t ser_rec = 0;
Servo servo1;
Servo servo2;
//{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
//{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
//{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
void audio_play(){
while (1) {
if(xQueueReceive(play,&ser_rec,0)){
if(ser_rec == 1)
{
temp = _component.read_temperature();
luxiaoban_speech(temp, 255);
}else if(ser_rec == 2){
temp = _component.read_temperature();
hum = _component.readHumidity();
luxiaoban_speech(temp, hum);
}
}
delay(10);
}
vTaskDelete(NULL);
}
//{ID:1,keyword:"命令词",ASR:"我是一",ASRTO:"一"}
//{ID:2,keyword:"命令词",ASR:"我是二",ASRTO:"二"}
//{ID:3,keyword:"命令词",ASR:"我是三",ASRTO:"三"}
//{ID:4,keyword:"命令词",ASR:"我是四",ASRTO:"四"}
//{ID:5,keyword:"命令词",ASR:"我是五",ASRTO:"五"}
//{ID:6,keyword:"命令词",ASR:"我是六",ASRTO:"六"}
//{ID:7,keyword:"命令词",ASR:"我是七",ASRTO:"七"}
//{ID:8,keyword:"命令词",ASR:"我是八",ASRTO:"八"}
//{ID:9,keyword:"命令词",ASR:"我是九",ASRTO:"九"}
//{ID:10,keyword:"命令词",ASR:"我是十",ASRTO:"十"}
//{ID:11,keyword:"命令词",ASR:"我是百",ASRTO:"百"}
//{ID:12,keyword:"命令词",ASR:"我是千",ASRTO:"千"}
//{ID:13,keyword:"命令词",ASR:"我是摄氏度",ASRTO:"摄氏度"}
//{ID:24,keyword:"命令词",ASR:"我是点",ASRTO:"点"}
//{ID:25,keyword:"命令词",ASR:"当前温度唯",ASRTO:"温度唯"}
//{ID:26,keyword:"命令词",ASR:"湿度百分之",ASRTO:"湿度百分之"}
//{ID:27,keyword:"命令词",ASR:"我是零",ASRTO:"零"}
//{ID:28,keyword:"命令词",ASR:"当前温度唯零下",ASRTO:"温度唯零下"}
void ASR_CODE()
{
//{ID:500,keyword:"唤醒词",ASR:"小电小电",ASRTO:"小电在呢,有什么需要帮助吗?"}
if(snid == 500){
mySerial1.println("kaixin");
}
//{ID:501,keyword:"唤醒词",ASR:"你好小电",ASRTO:"主人我在"}
if(snid == 501){
mySerial1.println("zhangsan");
}
//{ID:502,keyword:"命令词",ASR:"打开灯光",ASRTO:"好的,灯光已打开"}
if(snid == 502){
luxiaoban_digital_write(0,0);
mySerial1.println("shuaku");
}
//{ID:503,keyword:"命令词",ASR:"关闭灯光",ASRTO:"好的,灯光已关闭"}
if(snid == 503){
luxiaoban_digital_write(0,1);
mySerial1.println("tiaopi");
delay(3000);
}
//{ID:504,keyword:"命令词",ASR:"灯光向前",ASRTO:"灯光位置已调节"}
if(snid == 504){
mySerial1.println("kongtiao");
servo1.write(90);
delay(1000);
}
//{ID:505,keyword:"命令词",ASR:"盒子在哪",ASRTO:"盒子在书桌里"}
if(snid == 505){
mySerial1.println("chongbai");
luxiaoban_digital_write(2,1);
delay(3000);
luxiaoban_digital_write(2,0);
}
//{ID:506,keyword:"命令词",ASR:"灯光向右",ASRTO:"灯光位置已调节"}
if(snid == 506){
mySerial1.println("kongtiao");
servo1.write(180);
delay(1000);
}
//{ID:507,keyword:"命令词",ASR:"灯光向下",ASRTO:"灯光位置已调节"}
if(snid == 507){
mySerial1.println("kongtiao");
servo2.write(170);
delay(1000);
}
//{ID:508,keyword:"命令词",ASR:"灯光向左",ASRTO:"灯光位置已调节"}
if(snid == 508){
mySerial1.println("kongtiao");
servo1.write(0);
delay(1000);
}
//{ID:509,keyword:"命令词",ASR:"灯光向上",ASRTO:"灯光位置已调节"}
if(snid == 509){
mySerial1.println("kongtiao");
servo2.write(20);
delay(1000);
}
//{ID:510,keyword:"命令词",ASR:"房间温湿度",ASRTO:"当前"}
if(snid == 510){
ser_rec = 2;
xQueueSend(play,&ser_rec,0);
}
}
void setup()
{
mySerial1.begin(9600);
Serial.begin((9600));
//输入代码
//code here
//esp32 语音模块开发板
//P16 IO8
//P17 IO7
//{speak:橙子-甜美客服,vol:20,speed:10,platform:haohaodada}
//{playid:10001,voice:欢迎使用小电,用小电小电唤醒我}
//{playid:10002,voice:我退下了,用小电小电唤醒我}
_component.init();
xTaskCreate(audio_play,"audio_play",256,NULL,4,NULL);
servo1.attach(1);
servo2.attach(2);
}
到了这里,关于esp32+1.3寸屏幕语音交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!