0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

触摸屏WIFI获取时间和天气预报相关的功能是怎样实现的

嵌入式技术开发 来源:嵌入式技术开发 作者:Mr张工 2022-10-24 08:59 次阅读

前几天发布了开源4.3寸触摸屏的文章,里面有WIFI获取时间和天气预报相关的功能,今天就来介绍一下这个功能是怎样实现的。

1.底层驱动

首先,硬件上,单片机通过串口AT指令访问WIFI模块(ESP8266)。具体AT指令怎样写,可以参考之前的文章《单片机裸机环境下编写AT指令程序》。上电后,先配置WIFI模块的工作模式等,用到的AT指令如下:

1. 关闭回显

ATE0

2. 设置为STA模式

AT+CWMODE_DEF=1

3. 设置WIFI名称和密码

AT+CWJAP_DEF=”SSID”,”Password”

4. 开启DHCP

AT+CWDHCP_DEF=1,1

5. 设置为单连接模式

AT+CIPMUX=0

6.设置为透传模式

AT+CIPMODE=1

2.获取网络时间 获取网络时间的方式有两种,对于较新版本的固件,可以直接通过AT指令来获取。(可以通过AT+GMR指令来查询固件的版本。) AT+CIPSNTPTIME? 对于较老版本的固件,不支持该AT指令,只能通过自己连接网络服务器来获取当前时间。具体需要的AT指令如下:

1.建立TCP链接

AT+CIPSTART="TCP","www.beijing-time.org",80

2.打开传透模式

AT+CIPSEND

3.收到‘>’符号后,随便发送个数据

4.等待接收数据

接收的数据可以先用网络调试助手来测试,如下,可以看到,数据中包含了当前的日期和时间信息,我们可以先找到字符串中“Data”的位置,再解析后面的数据。数据格式固定,直接按照字符位置解析就行。

需要注意的是,获取的这个时间是格林威治时间,与北京时间相差8个小时。

当然,也可以通过连接其它NTP时间服务器来获取时间,步骤是类似的。

8f5150ec-5331-11ed-a3b6-dac502259ad0.png

3.获取天气预报 天气的获取就要比时间稍复杂一些,网上有很多可以提供天气预报的服务器,有些可以免费使用,一般都需要注册一个账号,这里以“心知天气”为例进行介绍。步骤如下:

1.注册账号

在该网站注册一个账号:https://www.seniverse.com/。注册之后就可以通过其开放的API来获取天气预报。有免费版和付费版,区别在于访问频次和获取的天气信息内容不同。如下:

8f9b6d44-5331-11ed-a3b6-dac502259ad0.png

2.查看私钥

在控制台查看账号的私钥,这个在程序中要用。

8fbc5d88-5331-11ed-a3b6-dac502259ad0.png

3.API

有了这个私钥,我们就可以通过API来获取天气预报了,相关的API说明可以在这里查询:

https://seniverse.yuque.com/books/share/f4f9bf1a-d3d9-4a68-8996-950f8c88400e/sl6gvt#d29hl

先用网络调试助手测试一下:

8fe42b2e-5331-11ed-a3b6-dac502259ad0.png

可以看到,通过TCP连接服务器后,发送GET请求就可以收到天气预报数据,接下来就是解析数据了。

4.解析数据

接收的数据是JSON格式的字符串,在单片机中我们可以移植cJSON来进行解析。cJSON是一个开源的C语音解析库,只有cJSON.c、cJSON.h两个文件,直接添加到工程中就可以使用相关函数。

程序如下:

void Weather_JSON( )
{  
    char *data;
    cJSON *root;
    cJSON *results;
    cJSON *last_update;
    cJSON *loc_json, *daily_json;
    cJSON *forecast_json;
    char *loc_tmp, *weather_tmp;
    int i = 0;


    data = (char*)(Uart1.RxBuf);//接受到的数据
    root = cJSON_Parse(data);
    if(root)
    {
        //printf("JSON格式正确:
%s

",cJSON_Print(root));    //输出json字符串
        results = cJSON_GetObjectItem(root, "results");
        results = cJSON_GetArrayItem(results,0);
        if(results)
        {
            loc_json = cJSON_GetObjectItem(results, "location");   //得到location键对应的值,是一个对象


            loc_tmp = cJSON_GetObjectItem(loc_json, "id") -> valuestring;
            //printf("城市ID:%s
",loc_tmp);
            loc_tmp = cJSON_GetObjectItem(loc_json, "name") -> valuestring;
            memset(loc_str,0,20);
            memcpy(loc_str,loc_tmp,strlen(loc_tmp));
          
            loc_tmp = cJSON_GetObjectItem(loc_json, "timezone") -> valuestring;
            //printf("城市时区:%s

",loc_tmp);


            daily_json = cJSON_GetObjectItem(results, "daily");
            if(daily_json)
            {
                Weather_Dat[0].Flag = 1;
                for(i = 0; i < 3; i++)
                {
                    forecast_json = cJSON_GetArrayItem(daily_json, i);
                    //weather_tmp = cJSON_GetObjectItem(forecast_json, "date") -> valuestring;//日期


                    weather_tmp = cJSON_GetObjectItem(forecast_json, "code_day") -> valuestring;//白天天气代码
                    Weather_Dat[i].Weathcode = atoi(weather_tmp);


                    //weather_tmp = cJSON_GetObjectItem(forecast_json, "code_night") -> valuestring;//晚上天气代码


                    weather_tmp = cJSON_GetObjectItem(forecast_json, "high") -> valuestring;//最高温度
                    memset(Weather_Dat[i].HighT,0,4);
                    memcpy(Weather_Dat[i].HighT,weather_tmp,strlen(weather_tmp));


                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "low") -> valuestring;//最低温度
                    memset(Weather_Dat[i].LowT,0,4);
                    memcpy(Weather_Dat[i].LowT,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "wind_direction") -> valuestring;//风向
                    memset(Weather_Dat[i].Wind_Dir,0,10);
                    memcpy(Weather_Dat[i].Wind_Dir,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "wind_scale") -> valuestring;//风力
                    memset(Weather_Dat[i].WindScale,0,4);
                    memcpy(Weather_Dat[i].WindScale,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "humidity") -> valuestring;//湿度
                    memset(Weather_Dat[i].Humi,0,4);
                    memcpy(Weather_Dat[i].Humi,weather_tmp,strlen(weather_tmp));
                }
            }
            else
            {
                //printf("daily json格式错误
");
                Weather_Dat[0].Flag = 0;
}


        }
        else
        {
            Weather_Dat[0].Flag = 0;
            //printf("results格式错误:%s
", cJSON_GetErrorPtr());
        }
    }
    else
    {
        Weather_Dat[0].Flag = 0;
        //printf("JSON格式错误
");
    }
    cJSON_Delete(root);  
}
解析后,将有用数据转换为自己想要的格式存储在变量中。需要注意的是,cJSON可能占用较大的堆栈,因此堆栈需要设大一些。

总结一下,获取天气预报的步骤如下:

1.注册账号。

2.获取私钥。

3.连接服务器。

AT+CIPSTART="TCP”,” api.seniverse.com”,80

4..打开传透模式。

AT+CIPSEND

5..收到‘>’符号后,发送GET请求

GET https://api.seniverse.com/v3/weather/daily.json?key=your_key&location=ip&language=zh-Hans&unit=c&start=0&days=3

6.等待接收数据,并解析。

以上就是单片机通过AT指令访问WIFI模块获取网络时间和天气预报的方法,需要注意的是上述所有指令后面别忘了加回车换行符。






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6030

    文章

    44482

    浏览量

    631751
  • 触摸屏
    +关注

    关注

    42

    文章

    2282

    浏览量

    115720
  • wifi模块
    +关注

    关注

    60

    文章

    376

    浏览量

    73251
  • ESP8266
    +关注

    关注

    50

    文章

    962

    浏览量

    44744

原文标题:单片机通过WIFI模块(ESP8266)获取网络时间与天气预报

文章出处:【微信号:嵌入式技术开发,微信公众号:嵌入式技术开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    labview天气预报

    `用labview写的天气预报,信息比较多,懒得分析,你们各取所需吧!`
    发表于 07-28 14:49

    怎样去设计一种基于rt-thread带有显示时间天气预报功能的桌面小盒子

    摘要这个桌面小盒子是之前的东西,一直放着没有整理好。最近有空了就把他整理整理。小盒子主要用来显示时间天气预报功能比较简单,其实还有很多可以玩的,懒得弄,所以就把最简单的整理出来。软件
    发表于 03-31 14:46

    基于ESP32 WiFi连接天气预报机的设计方案

    描述WeatherBot - 3D 打印天气预报剧院 | ESP32 和 OpenWeatherMap如何 3D 打印/激光切割带有 E-ink 显示的 ESP32 WiFi 连接天气预报
    发表于 06-30 06:49

    【Banana PI Leaf S3开发板试用体验】基于Banana PI Leaf S3的天气预报系统

    request获取本地天气预报,然后再解析返回的JSON,实现几个关键词的内容在OLED上 的显示。至于HTTPS与HTTP的选择,当然是越简单越好了,找了个HTTP的天气网站(ht
    发表于 10-17 20:06

    【国民技术N32项目移植】5.项目提交-天气显示及预报系统介绍以及演示

    SPI+DAM驱动触摸LCD(ST7789+XPT2046)4.天气显示及预报系统之ESP8266联网以及获取天气
    发表于 02-22 19:53

    Android智能手机天气预报系统设计及实现

    Android智能手机天气预报系统设计及实现
    发表于 01-14 11:22 22次下载

    由MQTT进行的天气预报ESPWatch 远程控制本地仪器

    ESPWatch基于ESP-12 WIFI模块。它从Internet服务器获取几天的日期/时间天气预报
    的头像 发表于 06-13 09:44 3670次阅读

    基于STM32 ESP8266的WIFI TFT自动校时天气预报设计

    本设计使用stm32作为主控,采用esp8266作为网络接入模组,可实现自动校准时间以及获取天气信息等功能! 该项目成本低廉,主要
    的头像 发表于 12-07 11:09 5230次阅读

    基于天气预报的自动灌溉系统

    电子发烧友网站提供《基于天气预报的自动灌溉系统.zip》资料免费下载
    发表于 10-31 14:47 2次下载
    基于<b class='flag-5'>天气预报</b>的自动灌溉系统

    Zambreti天气预报器开源分享

    电子发烧友网站提供《Zambreti天气预报器开源分享.zip》资料免费下载
    发表于 11-01 14:30 0次下载
    Zambreti<b class='flag-5'>天气预报</b>器开源分享

    基于SWM32单片机+LVGL的4.3寸触摸屏设计

    Uart1通过AT 指令访问WIFI模块,连接WIFI后,访问心知天气获取当地的天气预报;访问时间
    的头像 发表于 11-22 17:34 1946次阅读

    Arduino天气预报小矮人

    电子发烧友网站提供《Arduino天气预报小矮人.zip》资料免费下载
    发表于 02-08 16:09 0次下载
    Arduino<b class='flag-5'>天气预报</b>小矮人

    ESP8266获取天气预报信息,并使用CJSON解析天气预报数据

    当前文章介绍如何使用ESP8266和STM32微控制器,搭配OLED显示,制作一个能够实时显示天气预报的智能设备。将使用心知天气API来获取天气
    的头像 发表于 04-27 13:45 2177次阅读

    天气预报显示开源项目

    电子发烧友网站提供《天气预报显示开源项目.zip》资料免费下载
    发表于 06-14 10:47 0次下载
    <b class='flag-5'>天气预报</b>显示开源项目

    AWTK 开源串口开发(11) - 天气预报

    AWTK串口内置了XML/JSON/INI等各种数据文件的模型,并支持用HTTP/HTTPS从网络获取数据。不用编写一行代码,即可实现天气预报、股票行情、航班查询和快递查询等
    的头像 发表于 03-05 08:24 343次阅读
    AWTK 开源串口<b class='flag-5'>屏</b>开发(11) - <b class='flag-5'>天气预报</b>