概述
使用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.数据解析
{
"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。
//天气内容结构
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的转换,直接使用函数映射相关中文内容。如下:
//注意设置本文档编码方式为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获取网络天气所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复