我是靠谱客的博主 坚定荷花,最近开发中收集的这篇文章主要介绍从零开始 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:%02xn",
              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 的智能语音合成播报模块前言硬件选择代码解析总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部