ESP8266获取网络天气

22 篇文章 13 订阅

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

一步一步来。

1、初始化串口与相关IO

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

2、检测模块

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

3、连接路由热点

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

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

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

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("\r\nErr:NULL before: [%s]\r\n",cJSON_GetErrorPtr());}
    else
    {
        counts = cJSON_GetObjectItem(json,"counts");
        if( !counts )
        {
            printf("\r\nErr2:counts before: [%s]\r\n",cJSON_GetErrorPtr());
        }else
        {
            if(counts->valueint >0)
            {
                data = cJSON_GetObjectItem(json,"data");
                if( !data ){
                    printf("\r\nErr:3 before: [%s]\r\n",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、实际效果

 

 

 


————————————————
版权声明:本文为CSDN博主「林子xxx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangzibigan/article/details/86063406

https://blog.csdn.net/wangzibigan/article/details/86063406

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 ESP8266获取心知天气的数据。以下是一些步骤供参考: 1. 首先,你需要在心知天气官网上注册并获取 API 密钥。这个密钥将用于访问心知天气的 API 接口。 2. 确保你的 ESP8266 设备已经连接到互联网,并且你已经在 Arduino IDE 中安装了 ESP8266 的开发环境。 3. 在 Arduino IDE 中创建一个新的项目,并添加 ESP8266 相关的库。 4. 在代码中引入必要的库,并定义你的 Wi-Fi SSID 和密码,以及心知天气的 API 密钥。 ```cpp #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> const char* ssid = "YourWiFiSSID"; const char* password = "YourWiFiPassword"; const char* apiKey = "YourHeartknowWeatherAPIKey"; ``` 5. 在 `setup()` 函数中,连接到 Wi-Fi 网络。 ```cpp void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); } ``` 6. 在 `loop()` 函数中,使用 HTTPClient 库发送 GET 请求获取心知天气的数据。 ```cpp void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; String url = "https://api.seniverse.com/v3/weather/now.json?key=" + String(apiKey) + "&location=your_location"; http.begin(url); int httpCode = http.GET(); if (httpCode > 0) { if (httpCode == HTTP_CODE_OK) { String payload = http.getString(); // 在这里解析返回的 JSON 数据并提取相应的天气信息 // 使用 ArduinoJson 库进行 JSON 解析 StaticJsonDocument<200> doc; deserializeJson(doc, payload); JsonObject weather = doc["results"][0]["now"]; String weatherText = weather["text"]; int temperature = weather["temperature"]; Serial.print("Weather: "); Serial.println(weatherText); Serial.print("Temperature: "); Serial.println(temperature); } } else { Serial.println("Error on HTTP request"); } http.end(); delay(60000); // 每隔一分钟获取一次天气数据 } } ``` 请注意,上述代码中的 `your_location` 应替换为你想要获取天气信息的目标位置。 这只是一个简单的示例,你可以根据自己的需求进行修改和扩展。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值