我是靠谱客的博主 年轻茉莉,这篇文章主要介绍ESP8266获取网络天气,现在分享给大家,希望可以做个参考。

使用ESP8266模块来获取网络数据(天气,时间等),还是挺简单的。

一步一步来。

1.初始化串口与相关IO

使得MCU可正常使用串口的发送与接收,以及一些IO控制ESP8266的使能端与电源。

2检测模块

通电后等待几秒钟,串口发送"ATrn",检测有回应"OK"则代表模块在线使用。

3.连接路由热点

发送"AT+CWJAP?rn"可以获取当前连接的路由,如果没有连接正确的路由,则使用"AT+CWLAPrn"命令获取当前路由列表。

使用"AT+CWJAP="ssid_str","password_str"rn"连接相关路由热点,ssid_str为热点名,password_str为密码。注意其中的转义符号。

4.连接网络天气服务器

这个可以自己百度搜索,我使用的api.yytianqi.com:80,还有api.k780.com:88。冒号前是服务器,冒号后是端口。

以yytianqi举例,可以上他们的网站查看API说明。使用前需要注册一个账号。(k780有公共测试的秘钥不需要注册也能使用)

网站:http://www.yytianqi.com/api.html

发送"AT+CIPSTART="TCP","api.yytianqi.com",80rn"使用TCP方式连接服务器,然后就可以与之通信。这时可以使用AT命令进入透传模式,不过我不建议这样,因为推出透传模式有点坑。所以推荐直接使用发送命令:"AT+CIPSEND=numrn",num是实际需要发送字符串的字节数。继续,使用GET命令请求数据"GET http://api.yytianqi.com/observe?city=CH280601&key=xxxxrn",xxxx是自己的秘钥,注册后网站提供,"city="后面是城市编号。

这时服务器会返回相关的数据,数据是JSON格式。前面我写过冠以JSON在KEIL上的移植使用。这里正好用上了。通常服务器返回数据后会自动关闭TCP连接。不过为了保险最好发送"AT+CIPCLOSErn"关闭与服务器的连接。

5.数据解析

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{ "code": 1, "msg": "Sucess", "counts": 28, //访问的剩余次数。 "data": { "cityId": "CH010100", //城市id "cityName": "北京", //城市名称 "lastUpdate": "2016-03-09 17:10:00", //实况更新时间 "tq": "多云", //天气现象 "numtq": "01", //天气现象编码 "qw": "5.0", //当前气温 "fl": "微风", //当前风力 "numfl": 0, //当前风力编码 "fx": "无持续风向", //当前风向 "numfx": "0", //当前风向编码 "sd": "10" //相对湿度 } }

理论上,JSON数据也就是特定格式的字符串,可以自己对字符串进行解析而不需要移植JSON。开始我也试过,比如使用strstr()函数寻找特定字符串,但最终发现不稳健而且麻烦。原因是服务器返回的数据模式不是每次都固定不变,比如某个内容,有时使用字符型,有时直接数字,打个比方也即是12和"12"的区别,甚至有时是浮点型有时又会变成整型数据。而且各个内容顺序不保证一样。所以还是建议移植JSON。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//天气内容结构 typedef struct { char numtq[6];//天气状况号 char qw[6];//气温 char numfl[6];//风力号 char numfx[6];//风向号 char sd[6];//湿度 char counts;//剩余次数 char ok;//完成 } _weatherType; //获取json内某个item的天气相关内容 并转为字符串形式 static void _getValue(const cJSON *item ,char val[]) { switch(item->type) { case cJSON_False: break; case cJSON_True: break; case cJSON_NULL: break; case cJSON_Number: if( item->valuedouble - item->valueint > 0.001)//真正的小数 { sprintf(val,"%.1f",item->valuedouble); }else{ if( item->valueint <=99999 ) sprintf(val,"%d",item->valueint); } break; case cJSON_String: sprintf(val,"%.5s",item->valuestring);//节省内存,暂时限定字符数5 break; case cJSON_Array: break; case cJSON_Object: break; } } //使用CJSON方式 获取天气内容 char JsonDataAnalyze(const char*pdata, _weatherType* ptq) { cJSON *json; cJSON *counts,*data,*numtq,*numfl,*numfx,*sd,*qw; ptq->ok=0; pdata = strstr((const char*)pdata,":{"); json=cJSON_Parse(pdata+1); if (!json) { printf("rnErr:NULL before: [%s]rn",cJSON_GetErrorPtr());} else { counts = cJSON_GetObjectItem(json,"counts"); if( !counts ) { printf("rnErr2:counts before: [%s]rn",cJSON_GetErrorPtr()); }else { if(counts->valueint >0) { data = cJSON_GetObjectItem(json,"data"); if( !data ){ printf("rnErr:3 before: [%s]rn",cJSON_GetErrorPtr()); }else{ numtq = cJSON_GetObjectItem(data,"numtq"); _getValue(numtq,ptq->numtq); numfl = cJSON_GetObjectItem(data,"numfl"); _getValue(numfl,ptq->numfl); numfx = cJSON_GetObjectItem(data,"numfx"); _getValue(numfx,ptq->numfx); sd = cJSON_GetObjectItem(data,"sd"); _getValue(sd,ptq->sd); qw = cJSON_GetObjectItem(data,"qw"); _getValue(qw,ptq->qw); ptq->ok = 1; } } } cJSON_Delete(json); } return ptq->ok ; }

数据内容会有些UTF格式汉字,我使用的串口屏只支持GBK汉字,只是测试所以没有做UTF到GBK的转换,直接使用函数映射相关中文内容。如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//注意设置本文档编码方式为GB2312或GBK //根据编号返回天气状况汉字描述 char* weather_tq_str(char num) { switch(num) { case 0:return "晴"; case 1:return "多云"; case 2:return "阴"; case 3:return "阵雨"; case 4:return "雷阵雨"; case 5:return "雷阵雨伴有冰雹"; case 6:return "雨夹雪"; case 7:return "小雨"; case 8:return "中雨"; case 9:return "大雨"; case 10:return "暴雨"; case 11:return "大暴雨"; case 12:return "特大暴雨"; case 13:return "阵雪"; case 14:return "小雪"; case 15:return "中雪"; case 16:return "大雪"; case 17:return "暴雪"; case 18:return "雾"; case 19:return "冻雨"; case 20:return "沙尘暴"; case 21:return "小到中雨"; case 22:return "中到大雨"; case 23:return "大到暴雨"; case 24:return "暴雨到大暴雨"; case 25:return "大暴雨到特大暴雨"; case 26:return "小到中雪"; case 27:return "中到大雪"; case 28:return "大到暴雪"; case 29:return "浮尘"; case 30:return "扬沙"; case 31:return "强沙尘暴"; case 32:return "浓雾"; case 49:return "强浓雾"; case 53:return "霾"; case 54:return "中度霾"; case 55:return "重度霾"; case 56:return "严重霾"; case 57:return "大雾"; case 58:return "特强浓雾"; case 100:return "刮风"; } return "Unknown"; } //根据编号返回风向汉字描述 char* weather_fx_str(char num) { switch(num) { case 0:return "无持续风向"; case 1:return "东北风"; case 2:return "东风"; case 3:return "东南风"; case 4:return "南风"; case 5:return "西南风"; case 6:return "西风"; case 7:return "西北风"; case 8:return "北风"; case 9:return "旋转风"; } return "Unknown"; }

6.实际效果

最后

以上就是年轻茉莉最近收集整理的关于ESP8266获取网络天气的全部内容,更多相关ESP8266获取网络天气内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部