ESP32+TFTLCD实现WiFi天气语音播报(八)

ESP32实现天气播报

文章目录

前言

前面几篇已经把WiFi天气语音播报涉及到的知识内容提了一下,这一篇进行项目的整合进而完成WiFi天气语音播报。

1、实现功能

自己编写相关代码,驱动WIFI模组,连接气象服务器,获取当地天气,同时还可以通过温湿度传感器采集到当前室内的温湿度值,并在LCD屏上进行显示,还可以进行语音播报

ESP32+TFTLCD实现WiFi天气语音播报(八)
无需使用温湿度传感器即可读取实时温湿度。
[En]

There is no need to use temperature and humidity sensors to read real-time temperature and humidity.

; 2、获取并解析天气数据

首先我们要配置WIFI模块连上热点,检测是否接入 WIFI GOT IP,连接服务器,开启透传,获取天气结果。当WIFI模块获取服务器一次实时天气成功后,会返回对应的json格式数据,然后再对json格式数据解析获取需要的内容。需要说的是JSON是一种特殊的数据结构,ESP32中有一个内置的库cjson,用来处理json格式的数据并且获取内容。

void Get_Weather(void)
{
    static uint8_t count = 0;
    char http_cmd[256] = {0};
    uint8_t recv = 0;
    cJSON *root = NULL,*json_results = NULL,*json_arry = NULL,*json_location = NULL,*json_now = NULL,*json_daily = NULL,*json_daily_arr = NULL;

    switch(count)
    {
        case 0:
            weatherTime[1] = 1000;
            WIFI_SendStr("+++");
            count++;
            break;
        case 1:
            WIFI_SendStr("AT+RST\r\n");
            count++;
            break;
        case 2:
            recv = ESP8266_SendCmd_RecAck(NULL, "WIFI GOT IP", 30000, 1);

            count++;
            break;
        case 3:
            recv = ESP8266_SendCmd_RecAck("AT+CIPSTART=\"TCP\",\"116.62.81.138\",80\r\n", "OK", 20000, 1);
            if(recv == 0)   count++;
            break;
        case 4:
            recv = ESP8266_SendCmd_RecAck("AT+CIPMODE=1\r\n", "OK", 1000, 1);
            if(recv == 0)   count++;
            break;
        case 5:
            recv = ESP8266_SendCmd_RecAck("AT+CIPSEND\r\n", ">", 2000, 1);
            if(recv == 0)   count++;
            break;

        case 6:
            sprintf(http_cmd, "GET https://api.seniverse.com/v3/weather/now.json?key=%s&location=%s&language=en&unit=c\r\n",
                            Key_ID,
                            location[location_pos]);
            printf("%s\r\n", http_cmd);
            WIFI_SendStr(http_cmd);
            count++;
            break;
        case 7:
            count = 0;
            weatherTime[1] = 10000;

            printf("开始解析JSON数据\r\n");

            root = cJSON_Parse((char *)wifi_message.rx_buff);
            if(!root)
            {
                printf("root Error before: %s\n", cJSON_GetErrorPtr());
                break;
            }
            else
            {
                json_results = cJSON_GetObjectItem(root,"results");
                if(!json_results)
                {
                    printf("results Error before: %s\n", cJSON_GetErrorPtr());
                }
                else
                {
                    json_arry = json_results->child;
                    json_location = cJSON_GetObjectItem(json_arry,"location");

                    if(!json_location)
                    {
                        printf("location Error before: %s\n", cJSON_GetErrorPtr());
                    }

                    json_now = cJSON_GetObjectItem(json_arry,"now");
                    if(!json_now)
                    {
                        printf("json_now Error before: %s\n", cJSON_GetErrorPtr());
                    }
                    else
                    {

                        printf("地址\t天气\t温度\tcode\r\n");
                        printf("%s\t", cJSON_GetObjectItem(json_location,"name")->valuestring);
                        printf("%s\t", cJSON_GetObjectItem(json_now,"text")->valuestring);
                        printf("%s\t", cJSON_GetObjectItem(json_now,"temperature")->valuestring);
                        printf("%s\r\n", cJSON_GetObjectItem(json_now,"code")->valuestring);

                        weather[0].now_tem = atoi(cJSON_GetObjectItem(json_now,"temperature")->valuestring);
                        weather[0].now_code = atoi(cJSON_GetObjectItem(json_now,"code")->valuestring);
                        sprintf(weather[0].now_text,"%s",cJSON_GetObjectItem(json_now,"text")->valuestring);
                        if(weather[0].now_code > 38)    weather[0].now_code = 39;

                    }
                }
            }
            cJSON_Delete(root);
            wifi_message.rx_count = 0;
            memset(wifi_message.rx_buff,0,1024);
            break;

    }
}

JSON数据格式包括数组和对象两种嵌套方式,简单来说,数组就是中括号的嵌套,对象就是大括号的嵌套,解析的时候是两种不同的函数。
解析的大致步骤为:

  • 从第一层对象解析出键为results的对象
  • 对results对象进行继续解析,获取序号为0的数组
  • 该数组包含了键为location和now的两个对象
  • 继续解析来自两个对象的数据
    [En]

    continue to parse data from two objects*

3、获取天气

代码如下:


        if(weatherTime[0]>=weatherTime[1])
        {
            Get_Weather();
            if(Gui_flag==2)
            {
                memset(buff,0,20);
                sprintf(buff,"%s",location_cn[location_pos]);

                Draw_Text_8_16_Str(100,10,YELLOW,BLACK,buff);

                Draw_Text_8_16_Str(100,30,YELLOW,BLACK,weather[0].now_text);

                memset(buff,0,20);
                sprintf(buff,"%d",weather[0].now_tem);
                Draw_Text_8_16_Str(100,50,YELLOW,BLACK,buff);
            }
            weatherTime[0]=0;
        }

4、LCD显示

主界面画面
代码如下(示例):

void Gui_Main(void)
{
    LCD_Clear(YELLOW);
    Draw_Text_8_16_Str(10,288,YELLOW,BLACK,"WiFi语音气象站");

}

播报城市天气信息界面

void Gui_Weather(void)
{
    LCD_Clear(YELLOW);
    Draw_Text_8_16_Str(10,10,YELLOW,BLACK,"城市:");
    Draw_Text_8_16_Str(10,30,YELLOW,BLACK,"天气:");
    Draw_Text_8_16_Str(10,50,YELLOW,BLACK,"温度:");

    memset(buff,0,20);
    sprintf(buff,"%s",location_cn[location_pos]);

    Draw_Text_8_16_Str(100,10,YELLOW,BLACK,buff);

    Draw_Text_8_16_Str(100,30,YELLOW,BLACK,weather[0].now_text);

    memset(buff,0,20);
    sprintf(buff,"%d",weather[0].now_tem);
    Draw_Text_8_16_Str(100,50,YELLOW,BLACK,buff);
}

5、按键实现切换城市和界面

按键实现切换城市和界面


        if(KeyTime[0]>=KeyTime[1])
        {
            keyval = Get_KeyVal();
            switch(keyval)
            {

                case 1:
                    location_pos++;
                    if(location_pos>5)  location_pos=0;
                  break;

                case 2: Play_Weather();break;

                case 3: Gui_flag=2;Gui_mode=1;break;
                case 4: Gui_flag=1;Gui_mode=1;break;
            }
            KeyTime[0]=0;
        }

        if(GuiTime[0]>GuiTime[1])
        {
            GuiTime[0]=0;
            if(Gui_mode)
            {
                switch(Gui_flag)
                {
                    case 1:Gui_Main();Gui_mode = 0;break;
                    case 2:Gui_Weather();Gui_mode = 0;break;
                }
          }

        }

6、语音播报天气

天气播报实现

void Play_Weather(void)
{
    int i=0;int len=0;
    int num1[3] = {0};

    len = weather[0].now_tem;

    num1[0] = len/100;
    num1[1] = (len-num1[0]*100)/10;
    num1[2] = len%10;
    printf("num = %d %d %d  \r\n",num1[0],num1[1],num1[2]);

    if(len != 0)
    {

        Voice_PlayDirectoryMusic(01,(location_pos+11));
        Delay_nms(500);
        Voice_PlayDirectoryMusic(02,weather[0].now_code);
        Delay_nms(500);

        for(i=1;i<3;i++)
        {
            switch(num1[i])
            {
                case 0:break;

                case 1:Voice_PlayDirectoryMusic(00,0x01);break;
                case 2:Voice_PlayDirectoryMusic(00,0x02);break;
                case 3:Voice_PlayDirectoryMusic(00,0x03);break;
                case 4:Voice_PlayDirectoryMusic(00,0x04);break;
                case 5:Voice_PlayDirectoryMusic(00,0x05);break;
                case 6:Voice_PlayDirectoryMusic(00,0x06);break;
                case 7:Voice_PlayDirectoryMusic(00,0x07);break;
                case 8:Voice_PlayDirectoryMusic(00,0x08);break;
                case 9:Voice_PlayDirectoryMusic(00,0x09);break;
                default:break;

            }
            Delay_nms(1);
            if((i==1) && (num1[1]!=0))
                 Voice_PlayDirectoryMusic(00,10);

        }
        Delay_nms(1);
        Voice_PlayDirectoryMusic(01,01);
    }
}

总结

以上就是WiFi天气语音播报的全部内容了,可能有些地方有错误也有些地方是借鉴别的大佬的,不管怎样亲自完成一个项目还是挺有成就感的。最后附上整个项目的源码
WiFi天气语音播报 提取码:lwm2

Original: https://blog.csdn.net/qq_44890147/article/details/121380850
Author: 清道 夫
Title: ESP32+TFTLCD实现WiFi天气语音播报(八)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/515025/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球