从零开始 DIY 智能家居 - 基于 ESP32 的智能语音合成播报模块
前言
这里这么多设备,突然发现我做的好像都是传感器之类的居多好像没啥输出端设备,每天采集一堆数据,但是没注意看手机就不知道,我那甲醛传感器丢柜子里面大半月都忘记它的存在了,但是每次掏手机就去打游戏刷视频去了,懒得专门去看(理直气壮!)

我得再搞个法子让我连手机都不用看,就能知道需要的信息,于是我搞了一个语音播报模块。
硬件选择
板子依然用便宜好用的的安信可的 ESP32S (我是不是真得去找安信可要赞助啊?至少把我买板子的钱报销一下啊!)
语音播报模块我买的是:亚博智能语音合成播报模块 DF家的用太多啦,换一家免得你们说我是托 o(* ̄3 ̄)o
这个模块使用 I2C 控制和通信(连接开发板:SDA->P21,SCL->P22)
服务器用的翼辉的 翼辉的 Spirit 1 边缘计算机(其实并不是真正的服务器,只是在这里的作用类似于服务器)。
代码解析
获取代码
为了方便讲解逻辑,我会打乱代码的顺序可能还会进行裁剪,要是想直接拿代码跑的朋友可以直接去 灵感桌面的秘密宝库 获取代码,或者直接 clone:
https://gitee.com/inspiration-desktop/DEV-lib-arduino.git
下载或者 clone代码后这次用到的是这个四个文件夹:

cjson:我移植的 cjson 库,就是标准的 cjson 库,放到 arduino 安装目录下的 libraries 文件夹里,百度一下 cjson 的函数使用就行了。
libsddc:是我移植自官方的SDDC库和自己写的 SDK,也是放入 libraries 文件夹里就行。里面是 SDDC 协议的处理函数,我们不用管。
XFS: 是亚博官方提供的语音播报模块的库,我单独打包出来了,也是放入也是放入 libraries 文件夹里就行。
demo 文件夹里面就是我们各种传感器的 demo 代码了:

红圈的 speech_sddc_sdk_demo 文件夹里面就是我们代码,点进去就能看见 speech_sddc_sdk_demo.ino 文件,双击文件会自动启动 arduino-IDE 打开代码。在工具 -> 端口 选择对应的 COM 口然后点击上传就可以把代码烧录到板子里:

具体 arduino 使用教程可以看我之前的文章 arduino开发指导 和 手把手带你 arduino 开发:基于ESP32S 的第一个应用-红外测温枪(带引脚图)
设备控制命令:
通过 Spirit 1 的应用程序或者嗅探器 向传感器设备发送的命令:
语音播报命令:
{
"method": "set",
"speech": "string" // string为需要播报的文本。编码方式必须为ANSI或者GB2312
}
语速设置命令:
{
"method": "set", //设置语速1~10
"set_speed": 1-10
}
语调设置命令:
{
"method": "set",
"set_intonation": 1-10 //设置语调1~10
}
音量设置命令:
{
"method": "set",
"set_volume": 1-10 //设置音量1~10
}
设备和协议初始化流程:
基于官方 demo 写的不需要做什么修改,主要是设备初始化,管脚配置,和协议初始化部分。
/*
* 初始化语音播报模块
*/
static void XFS_Init()
{
uint8_t n = 5;
Serial.println("初始化语音播报模块");
xfs.Begin(0x30);//设备i2c地址,地址为0x50
delay(n);
Serial.println("设置发音人");
xfs.SetReader(XFS5152CE::Reader_XiaoYan); //设置发音人
delay(n);
Serial.println("文本的编码格式");
xfs.SetEncodingFormat(XFS5152CE::GB2312); //文本的编码格式
delay(n);
Serial.println("语种判断");
xfs.SetLanguage(xfs.Language_Auto); //语种判断
delay(n);
Serial.println("合成风格设置");
xfs.SetStyle(XFS5152CE::Style_Continue); //合成风格设置
delay(n);
Serial.println("设置单词的发音方式");
xfs.SetArticulation(XFS5152CE::Articulation_Letter); //设置单词的发音方式
delay(n);
Serial.println("设置语速");
xfs.SetSpeed(5); //设置语速1~10
delay(n);
Serial.println("设置语调");
xfs.SetIntonation(5); //设置语调1~10
delay(n);
Serial.println("设置音量");
xfs.SetVolume(5); //设置音量1~10
delay(n);
}
/*
* 初始化传感器
*/
void sensor_init()
{
// 初始化语音播报模块
XFS_Init();
}
void setup() {
byte mac[6];
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
// 初始化传感器
sensor_init();
// 清除一下按键状态机的状态
button.reset();
// 创建按键扫描线程,长按 IO0 按键,松开后ESP32 将会进入 SmartConfig 模式
sddc_printf("长按按键进入 Smartconfig...\n");
button.attachLongPressStop(esp_io0_key_task);
xTaskCreate(esp_tick_task, "button_tick", ESP_TASK_STACK_SIZE, NULL, ESP_TASK_PRIO, NULL);
// 启动 WiFi 并且连接网络
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
// 获取并打印 IP 地址
Serial.println("");
Serial.println("WiFi connected");
Serial.print("'ip :");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
// sddc协议初始化
sddc_lib_main(&sys_cfg);
// 获取并打印网卡 mac 地址
WiFi.macAddress(mac);
sddc_printf("MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
// 使用网卡 mac 地址设置设备唯一标识 UID
sddc_set_uid(G_sddc, mac);
}
void loop() {
// 运行 SDDC 协议循环
while (1)
{
sddc_printf("SDDC running...\n");
sddc_run(G_sddc);
sddc_printf("SDDC quit!\n");
}
// 销毁 SDDC 协议
sddc_destroy(G_sddc);
}
配置设备信息
这部分代码可以配置 WiFi 名字和 WiFi 密码,要使用的引脚,并且配置设备在 Spirit 1 上显示的信息:
#define SDDC_CFG_PORT 680U // SDDC 协议使用的端口号
#define PIN_INPUT 0 // 选择 IO0 进行控制
#define ESP_TASK_STACK_SIZE 4096
#define ESP_TASK_PRIO 25
/*超时设置,示例为30S*/
static uint32_t LastSpeakTime = 0;
#define SpeakTimeOut 10000
static const char* ssid = "EOS-Tenda"; // WiFi 名
static const char* password = "1234567890"; // WiFi 密码
static double illu_val;
OneButton button(PIN_INPUT, true);
XFS5152CE xfs;
/*
* 当前设备的信息定义
*/
DEV_INFO dev_info = {
.name = "语音合成模块",
.type = "device.speech",
.excl = SDDC_FALSE,
.desc = "ESP-32S + 亚博语音合成播报模块",
.model = "IDSPEECHU01B",
.vendor = "inspiration-desktop",
};
/*
* 系统注册对象汇聚
*/
SDDC_CONFIG_INFO sys_cfg = {
.token = "1234567890", // 设备密码
.devinfo = &dev_info,
.io_dev_reg = io_dev,
.io_dev_reg_num = ARRAY_SIZE(io_dev),
.num_dev_reg = num_dev,
.num_dev_reg_num = ARRAY_SIZE(num_dev),
.state_get_reg = dev_state_get_reg,
.state_get_reg_num = ARRAY_SIZE(dev_state_get_reg),
.dis_dev_reg = dis_dev,
.dis_dev_num = ARRAY_SIZE(dis_dev),
};
回调函数注册
这是收到命令后回调函数注册的位置,在这里注册的函数才能被 SDK 正确的调用,执行正确的动作。
具体 SDK 的解析可以参考 同人逼死官方系列!基于sddc 协议的SDK框架 sddc_sdk_lib 解析 和 同人逼死官方系列!从 DDC 嗅探器到 sddc_sdk_lib 的数据解析
/*
* 数字量设备对象函数与处理方法注册
*/
NUM_DEV_REGINFO num_dev[] = {
// {"set_num_demo", demo}, // 字符串为输入命令,demo为命令处理函数
{"设置语速",SetSpeed},
{"设置语调",SetIntonation},
{"设置音量",SetVolume},
};
/*
* 显示设备对象函数与处理方法注册
*/
DIS_DEV_REGINFO dis_dev[] = {
// {"set_dis_demo", demo}, // 字符串为输入命令,demo为命令处理函数
};
/*
* IO设备对象设置函数与处理方法注册
*/
IO_DEV_REGINFO io_dev[] = {
// {"set_io_demo", demo}, // 字符串为输入命令,demo为命令处理函数
{"语音播报",speech},
};
/*
* 系统对象状态获取注册
*/
DEV_STATE_GET dev_state_get_reg[] = {
// {"demo", DEV_NUM_TYPE, num_get_demo}, // demo为输入命令,字符串为命令处理函数
// {"demo", DEV_IO_TYPE, io_get_demo},
// {"demo", DEV_DISPLAY_TYPE, dis_get_demo},
};
语音播报与设置流程
这里是我们自己编写的处理流程 ,可以根据你的需求自己更改,收到 set 或者 get 后根据前面的注册的函数,进入对应的处理函数。
语言播报模块会将语音播报命令中的字符串转换成中文,合成语音播报出来,还可以通过 set 命令来设置模块的功能,这里只举了用了三个常用功能,但是实际上还有更多的功能可以设置:
/*
* 语音播报函数
*/
sddc_bool_t speech(const char* value)
{
printf("开始播报\n");
xfs.StartSynthesis(value); // 选择播报的语句
while(xfs.GetChipStatus() != xfs.ChipStatus_Idle) //检查判断是否完成
{
delay(30);
}
return SDDC_TRUE;
}
/*
* 设置语速函数
*/
sddc_bool_t SetSpeed(const uint64_t value)
{
printf("设置语速\n");
xfs.SetSpeed(value);
return SDDC_TRUE;
}
/*
* 设置语调函数
*/
sddc_bool_t SetIntonation(const uint64_t value)
{
printf("设置语调\n");
xfs.SetIntonation(value);
return SDDC_TRUE;
}
/*
* 设置音量函数
*/
sddc_bool_t SetVolume(const uint64_t value)
{
xfs.SetVolume(value);
return SDDC_TRUE;
}
总结
好了之后只要写个应用,定一个时间或者阈值获取传感器数据让语言播报模块告诉我就好了,完美!
本文仅个人学习使用,如有错误,欢迎指正, ( ੭ ˙ᗜ˙ )੭谢谢老板!
从零开始 DIY 智能家居 - 基于 ESP32 的智能语音合成播报模块的更多相关文章
- 从零开始 DIY 智能家居 - 基于 ESP32 的智能紫外线传感器模块
目录 前言 硬件选择 二.使用步骤 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 数据获取与上报流程 总结 前言 做了这么多传感器都是自己玩,这次家里人看不下去了,非得 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的智能水浊度传感器
前言 家里有个鱼缸养了几条鱼来玩玩,但是换水的问题着实头疼,经常一个不注意就忘记换水,鱼儿就没了.o(╥﹏╥)o 在获得 Spirit 1 边缘计算机 后就相当于有了一个人智能设备服务器,可以自己开发 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的智能光照传感器
前言 上周出差有点急,结果家里灯没关,开了整整一周的时间(T▽T),整个人都裂开了,准备做一个能够远程控制灯的东西,让我以后出差能远程把家里灯关了. 第一步就是做这期的主题 - 智能光照传感器,因为我 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的智能浇水器
前言 上次 土壤湿度传感器 完成之后,就立下一个 flag 要搭建一个智慧浇水的智能场景,现在终于有时间填坑了!(o゚▽゚)o 智慧浇水场景的核心设备有三个: 检测土壤状态的:土壤湿度传感器 通过这个 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器
前言 自从上次做了那个 甲醛传感器 和 水浊度传感器 之后开始尝到智能家居的甜头了,这两东西有没有用我不知道,但是没事的时候掏出手机瞄两眼,看着就让人很安心( ̄︶ ̄). 于是懒惰的我开始琢磨把给植物浇 ...
- 基于ESP32的智能家居管理系统的设计与实现
基于ESP32的智能家居管理系统的设计与实现 ESP32的智能家居管理系统访问链接: https://www.cnblogs.com/easyidea/p/13101165.html 一.需求分析 1 ...
- 手把手搭建自己的智能家居 - 基于 IOT Pi 的智能甲醛检测器
智慧家居 - 基于 IOT Pi 的智能甲醛检测器 之前的文章体验 MS-RTOS 的时候入手了一个块 IOT Pi ,放着也是浪费,这次我们就利用 IOT PI 开发一个智能甲醛检测器.φ(> ...
- 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统 IA-SmartHome团队 2012.12 l 基于无线的智能家居解决方案,节省施工成本: l 基于能 ...
- 谁才是智能家居的未来?视声M+O融合方案给出答案
有些智能家居,你不能说它不智能. 但在现实生活中,常常帅不过一秒. 就比如,当你经历了一天的疲惫后回到家,发现玄关的智能开关突然没反应,家里的灯怎么都打不开.这种时候你得明白,你的智能开关面板很有可能 ...
随机推荐
- 改Jupyter Notebook的默认工作路径?
如何更改Jupyter Notebook的默认工作路径? 1.在cmd中输入命令使Jupyter产生配置文件:Jupyter_notebook_config.py jupyter notebook - ...
- C语言使用getch()读取方向键
初衷: 在解决N皇后问题时需要使用方向键实现布局切换,于是就在网上查找资料,感觉自己收获不小,就把自己总结的一些知识点给记录下来. 总结: 1.getch()读取字符需要一次. 2.getch()读取 ...
- css3 显示一行内容,多余的以省略号显示
overflow: hidden; white-space: nowrap; text-overflow: ellipsis; 代码如上
- html 表单input disabled属性提交后台无法获得数据
在input上加入disabled属性后, 点击提交会遗漏该值, 有两个办法: 一 可以考虑readonly属性,一样的不可修改操作,但是可以提交 二 在提交时 js 代码操作去除input上的dis ...
- 腾讯云 CIF 工程效能峰会,10 月 19 - 20 日震撼来袭!
近年来,依托于云计算的飞速发展,腾讯云云产品更新迅猛,云原生生态构建初具规模,越来越多的企业也开始寻求与深入数字化转型之路.但在摸索与实践中,企业往往会进入"伪上云"的误区.除了单 ...
- springboot pom.xml
Demo project for Spring Boot <?xml version="1.0" encoding="UTF-8"?> <pr ...
- Appium Android Toast控件
Android Toast控件是Android系统级别的控件,不是App的控件,getPageSource是⽆法找到的. Toast介绍 1.背景 在安卓设备里面,使用各种手机应用程序的时候,需要先进 ...
- 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核资源 | 百篇博客分析OpenHarmonyOS | v2.07
百篇博客系列篇.本篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核资源 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核 ...
- P3306-[SDOI2013]随机数生成器【BSGS】
正题 题目链接:https://www.luogu.com.cn/problem/P3306 题目大意 给出一个\(p,a,b,x_1,t\),有\(x_i=ax_{i-1}+b\) 求一个最小的\( ...
- 一、mybatis入门案例
今天学习了mybatis框架,简单记录一下mybatis第一个入门案例,目标是使用Mybatis作为持久层框架,执行查询数据的SQL语句并且获取结果集 基本步骤: 物理建模 逻辑建模 引入依赖 创建持 ...