Funpack2-5活动:基于ESP32-S3的WiFi和TTS功能的联网天气语音播报系统
本项目使用ESP32-S3-box-live,参照乐鑫官方提供的教程和例子,搭建完成任务所需要的环境并编写任务代码,完成任务。
标签
ESP32-S3-BOX-LITE
Funpack第二季第五期:ESP32-S3-BOX-LITE
天气语音播报
影墨kke
更新2023-08-02
湖南科技大学
415

基于ESP32-S3的WiFi和TTS功能的联网天气语音播报系统

一.项目介绍

本项目参加Funpack2-5活动,采用搭载了ESP32-S3开发板ESP32-S3-BOX的智能语音设备开发平台完成任务一:使用ESP32的WiFi和TTS功能,实现一个语音播报系统(联网获取指定地点、指定日期的天气并进行语言播报)。

二.硬件介绍

ESP32-S3-BOX和ESP32-S3-BOX-Lite是目前对应的AIoT应用开发板,搭载支持AI加速的ESP32-S3 Wi-Fi + Bluetooth 5 (LE) SoC。它们为用户提供了一个基于语音助手 + 触摸屏控制、传感器、红外控制器和智能 Wi-Fi 网关等功能,开发和控制智能家居设备的平台。

FgNyhpc6qFQ0t2a_W0-zKvPNFBW2

其官方将 ESP32-S3-BOX 与乐鑫 AI 图像处理、Wi-Fi 智能网关、Wi-Fi 人体检测、Wi-Fi 无线图传等技术方案相结合,对办公室进行了升级改造,构建了一个以前台和会议室为主体的智能场景,让乐鑫会议更聪明。

核心微控制器:ESP32-S3

ESP32-S3 是一款集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE) 的 MCU 芯片,支持远距离模式 (Long Range)。ESP32-S3 搭载 Xtensa 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM (TCM),具有 45 个可编程 GPIO 管脚和丰富的通信接口。ESP32-S3 支持更大容量的高速 Octal SPI flash 和片外 RAM,支持用户配置数据缓存与指令缓存。

Xtensa 32 位 LX7 双核处理器,主频高达 240 MHz
内置 512 KB SRAM、384 KB ROM 存储空间,并支持多个外部 SPI、Dual SPI、 Quad SPI、Octal SPI、QPI、OPI flash 和片外 RAM
额外增加用于加速神经网络计算和信号处理等工作的向量指令 (vector instructions)
45 个可编程 GPIO,支持常用外设接口如 SPI、I2S、I2C、PWM、RMT、ADC、UART、SD/MMC 主机控制器和 TWAITM 控制器等
基于 AES-XTS 算法的 Flash 加密和基于 RSA 算法的安全启动,数字签名和 HMAC 模块,“世界控制器 (World Controller)”模块

三.设计思路

任务主要分为两部分:

a.通过WiFi功能联网获取天气信息并进行处理

b.将处理后的数据信息运用板子的TTS功能实现语音播报

乐鑫提供了详细的开放指引,活动主办方真的很照顾我这样的新人,在活动页面就提供了板子的编程指南

按照开发指引,我首先进行了ESP-IDF的编程,一开始想通过mu编辑器+circuitpython编程语言进行代码的编辑的,觉得用python写会更容易完成任务,但尝试过后并没有搞明白。

刚好乐鑫官方在github上提供了非常多的应用例程,也包括了实现WiFi联网和TTS功能的例程,甚至直接就有获取天气信息的例程。这使得用c语言完成任务变得容易了。

1.设置开发环境

开发环境的搭建分为四步:

安装先决条件、获取ESP-IDF、设置工具和设置环境变量。

windows系统可以简单地从https://dl.espressif.com/dl/esp-idf/?idf=4.4 中下载 ESP-IDF 工具安装器(根据官方提供的版本支持信息,这里选择V4.4版本)直接完成先决条件和ESP-IDF的安装。完成这步后,打开ESP-IDF命令提示符窗口并运行export.bat脚本便可以进行各环境变量的设置。

而linux系统环境的搭建较为复杂,在完成所需工具的安装后。在终端下运行以下命令:

mkdir -p ~/esp
cd ~/esp
git clone -b release/v4.4 --recursive https://github.com/espressif/esp-idf.git

获取V4.4版本的ESP-IDF

FptAl0gd0PtCNTX8_h93IfZ4l7NY

完成后,通过输入指令 git clone --recursive https://github.com/espressif/esp-box.git 下载本项目的代码,环境的搭建到此结束。

2.开始例程的运行

完成环境搭建后,我通过运行官方提供的 examples 目录下的 get-started/hello_world 工程开始了我对板子的探索路程,例程的成功编译和烧录表明环境已经成功搭建。

案例里提示windows系统打开一个新项目后,应首先设置“目标”芯片 idf.py set-target esp32s3

3.参照官方提供的例程,以及相关的readme.md文件了解如何编写相关的代码,并通过板子实现联网获取天气信息并进行语音播报。

四.软件流程图

Fu-50N744awNgBH_N0f5icmd9HFE

五.各功能对应主要代码片段及说明

a 数字转中文

考虑到天气信息获取后存在一部分阿拉伯数字数据,这部分数据tts无法解析,进行数字和中文之间的转换:

static void E_T_C_handle(char *str1,char *str2)
{
    // char buffer[4];
    switch (str1[0])
    {
    case '0':
        strcpy(str2, "零");
        break;
    case '1':
        strcpy(str2, "一");
        break;
    case '2':
        strcpy(str2, "二");
        break;
    case '3':
        strcpy(str2, "三");
        break;
    case '4':
        strcpy(str2, "四");
        break;
    case '5':
        strcpy(str2, "五");
        break;
    case '6':
        strcpy(str2, "六");
        break;
    case '7':
        strcpy(str2, "七");
        break;
    case '8':
        strcpy(str2, "八");
        break;
    case '9':
        strcpy(str2, "九");
        break;
    default:
        break;
    }
    switch (str1[1])
    {
    case '0':
        strcat(str2, "零");
        break;
    case '1':
        strcat(str2, "一");
        break;
    case '2':
        strcat(str2, "二");
        break;
    case '3':
        strcat(str2, "三");
        break;
    case '4':
        strcat(str2, "四");
        break;
    case '5':
        strcat(str2, "五");
        break;
    case '6':
        strcat(str2, "六");
        break;
    case '7':
        strcat(str2, "七");
        break;
    case '8':
        strcat(str2, "八");
        break;
    case '9':
        strcat(str2, "九");
        break;
    default:
        break;
    }

    // return buffer;
}

b 天气信息的获取

首先根据../examples/protocols/README.md中的介绍:

### Configuring the Example

To configure the example to use Wi-Fi, Ethernet or both connections, open the project configuration menu (`idf.py menuconfig`) and navigate to "Example Connection Configuration" menu. Select either "Wi-Fi" or "Ethernet" or both in the "Connect using" choice.

When connecting using Wi-Fi, enter SSID and password of your Wi-Fi access point into the corresponding fields. If connecting to an open Wi-Fi network, keep the password field empty.

When connecting using Ethernet, set up PHY type and configuration in the provided fields. If using Ethernet for the first time, it is recommended to start with the [Ethernet example readme](../ethernet/basic/README.md), which contains instructions for connecting and configuring the PHY. Once Ethernet example obtains IP address successfully, proceed to the protocols example and set the same configuration options.

打开项目配置菜单(idf.py menuconfig),然后导航到“示例连接配置”菜单。在“连接使用”选项中选择“Wi-Fi”进行网络的连接配置。

然后通过心知天气的接口,能够很方便地获取天气的json数据,这里参照了https_request例程,read.me里面给出了详细的操作步骤.

static bool parse_json_data(const char *analysis_buf)
{
    cJSON *json_data = NULL;
    json_data = cJSON_Parse(analysis_buf);
    if (json_data == NULL) // 判断字段是否json格式
    {
        return false;
    }
    // ESP_LOGI(TAG, "Start parsing data");
    cJSON *cjson_item = cJSON_GetObjectItem(json_data, "results");
    cJSON *cjson_results = cJSON_GetArrayItem(cjson_item, 0);
    // ESP_LOGI(TAG, "getresult");
    // /* 获取天气的地址 */
    cJSON *cjson_location = cJSON_GetObjectItem(cjson_results, "location");
    cJSON *cjson_location_name = cJSON_GetObjectItem(cjson_location, "name");
    ESP_LOGI(TAG, "local is: %s", cjson_location_name->valuestring);

    cJSON *cjson_daily = cJSON_GetObjectItem(cjson_results, "daily");
    for (int i = 0; i < 3; i++)
    {
        /* 当天的天气信息 */
        cJSON *cjson_daily_1 = cJSON_GetArrayItem(cjson_daily, i);
        ESP_LOGI(TAG, "get daily:%d", i);
        strcpy(weatherInf[i], cJSON_GetObjectItem(cjson_daily_1, "text_day")->valuestring);

        strcpy(Htemperature[i], cJSON_GetObjectItem(cjson_daily_1, "high")->valuestring);
        strcpy(Ltemperature[i], cJSON_GetObjectItem(cjson_daily_1, "low")->valuestring);
        strcpy(humidity[i], cJSON_GetObjectItem(cjson_daily_1, "humidity")->valuestring);
        ESP_LOGI(TAG, "%d:day_date  ", i + 1);
        ESP_LOGI(TAG, "day_text_day is: %s", weatherInf[i]);
        ESP_LOGI(TAG, "day_one_temp_high is: %s", Htemperature[i]);
        ESP_LOGI(TAG, "day_one_temp_low is: %s", Ltemperature[i]);
        ESP_LOGI(TAG, "day_one_humi is: %s", humidity[i]);
    }
    return true;
}

c 语音播报

根据官方给出的硬件图可以清晰地看到板子的电路:

FtBxLEPmIsfckdJ0MVd8MEEa4CWu

可以看到音频codec电路使用的是I2S驱动的ES8156,这里可以通过I2S直接传输上述步骤获取的天气信息数据:

i2s_set_clk(I2S_NUM_0, 16000, 16, 1);
    const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "voice_data");
    if (part == 0)
        printf("Couldn't find voice data partition!\n");
    else
        printf("voice_data paration size:%d\n", part->size);

    spi_flash_mmap_handle_t mmap;
    uint16_t *voicedata;
    err = esp_partition_mmap(part, 0, 3 * 1024 * 1024, SPI_FLASH_MMAP_DATA, (const void **)&voicedata, &mmap);
    if (err != ESP_OK)
    {
        printf("Couldn't map voice data partition!\n");
    }
    esp_tts_voice_t *voice = esp_tts_voice_set_init(&esp_tts_voice_xiaole, voicedata);

    esp_tts_handle_t *tts_handle = esp_tts_create(voice);

    WeatherGetRequest();
    TextToVoice(tts_handle,"你好我是你的天气管家");
    TextToVoice(tts_handle,"即将为您进行湘潭地区天气播报");
    for (int i = 0; i < 3; i++)
    {
        if (i == 0)
        {
            TextToVoice(tts_handle,"今天天气是");
        }
        else if (i == 1)
        {
            TextToVoice(tts_handle,"明天天气是");
        }
        else
        {
            TextToVoice(tts_handle,"后天天气是");
        }
        TextToVoice(tts_handle,weatherInf[i]);
        TextToVoice(tts_handle,"最高温度是");
        TextToVoice(tts_handle,Htemperature[i]);
        TextToVoice(tts_handle,"最低温度是");
        TextToVoice(tts_handle,Ltemperature[i]);
        TextToVoice(tts_handle,"湿度是");
        TextToVoice(tts_handle,humidity[i]);
        vTaskDelay(100);
    }

其中TextToVoice使用了ESP-tts库中的esp_tts_parse_chinese函数,将中文文本解析为拼音,并判断解析是否成功。

六.功能演示

1.联网获取天气信息

Fn45ygz5KhtQ4EkwLWKhCbeKKNvj

2.将天气信息中的数字转换为汉字

Fpt1spfevxX_szzQrdP2MmN_Wg3N

3.语音播报

FmFpK-PpWaNh7N3EcYoL5CeQlOU0

FoVn7Y00zu5iFEPLm4Ndjh5t0nQ0

七.对本活动的心得体会

本次活动给我提供了一个接触esp32-s3板子的机会,活动提供了足够的资料,这些资料对于像我这样的新人真的很友好。我接下来会继续完善这个项目(如使用LVGL开发UI界面,实现天气信息在屏幕上的显示)学习其他例程利用esp32-s3-box-live实现一些其他的功能。

 

 

附件下载
boxdemo.zip
团队介绍
为个人团队,目前在湖南科技大学读研,在宿友的影响下首次参加Funpack的活动,感谢他给予我的巨大的帮助。
团队成员
影墨kke
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号