ESP32-Ardunio 心知天气 hhtps 获取数据 +NTP对时

这里是用ESP32做了从机,一定周期打印 时间,天气数据。 

编译环境是 vscode-PlatformIO

#include "Arduino.h"
#include 
#include 
#include 
// WiFi相关
const char *ssid = "233";
const char *password = "12345678";


//心知天气 相关
String API = "SJ3cQqGjCfr2Ej1oS";
String CITY = "luoyang";

// 定时器相关
u32_t cnt = 0;

void Get_Now_Time() ; //NTP 获取当前时间/日期
void Get_Today_Weather(String api, String city) ;//https 获取当日天气
void Get_Rencent_Weather(String api, String city) ;//https 获取 今明后 三日天气

void IRAM_ATTR Tim0_Handle(void) //定时器回调函数
{
     ++cnt;
     if(cnt == 300) //五分钟一个循环
     {
        cnt =0;
     }
}



void setup()
{
    Serial.begin(115200);
    Serial.println("串口初始化成功");

    hw_timer_t *tim0 = timerBegin(0, 8000, true); //建立定时器  //80MHZ 进行 8000预分频后 每秒 计数10000次
    timerAlarmWrite(tim0, 10000-1, true);//设置 自动重装载值 10000-1 
    timerAttachInterrupt(tim0, Tim0_Handle, true);//绑定定时器
    timerAlarmEnable(tim0);

}

void loop()
{
    switch (cnt) 
    {
    case 3:
        if (WiFi.status() != WL_CONNECTED)
        {
            WiFi.begin(ssid, password);
            vTaskDelay(100);
        }
        Serial.println("WiFi开启");
        ++cnt;
        break;

    case 8:
        Serial.println("现在的时间是");
        Get_Now_Time();
        Serial.println("今天的天气是");
        Get_Today_Weather(API, CITY);
        Serial.println("近三天的天气是");
        Get_Rencent_Weather(API, CITY);
        ++cnt;
        break;
 

    case 18:
        Serial.println("WiFi关闭");
        WiFi.disconnect(true); //关闭wifi ,降低功耗  
        WiFi.mode(WIFI_OFF);
        ++cnt;

    default:
        break;
    }
}

void Get_Now_Time()
{
    while (WiFi.status() != WL_CONNECTED)
    {
        WiFi.begin(ssid, password);
        vTaskDelay(100);
    }

    configTime(3600 * 7, 3600, "us.pool.ntp.org");

    static struct tm timeinfo;

    if (!getLocalTime(&timeinfo))
    {
        if (!getLocalTime(&timeinfo))
            return;
    }

    Serial.println(&timeinfo, "#T-%Y-%m-%d-%w-%H:%M:%S");//我需要的 时间 年月日 + 星期几 + 时分秒
    vTaskDelay(2);
}
void Get_Today_Weather(String api, String city)
{
    while (WiFi.status() != WL_CONNECTED)
    {
        WiFi.begin(ssid, password);
        vTaskDelay(100);
    }

    String url_xinzhi = "";
    url_xinzhi = "https://api.seniverse.com/v3/weather/now.json?key=";
    url_xinzhi += api;
    url_xinzhi += "&location=";
    url_xinzhi += city;
    url_xinzhi += "&language=en&unit=c";

    DynamicJsonDocument doc(2048); //分配内存,动态

    HTTPClient http;
    char data[100] = {"#w:"};

    http.begin(url_xinzhi);

    int httpGet = http.GET();

    if (httpGet > 0)
    {
        if (httpGet == HTTP_CODE_OK)
        {
            String json = http.getString();

            //Serial.println(json);  //打印接受到的消息

            deserializeJson(doc, json);
            
            /*  从doc 中提取出 需要的数据 */
            /*  code :天气码   temperature:气温  */
            strcat(data, doc["results"][0]["now"]["code"].as());
            strcat(data, ":");
            strcat(data, doc["results"][0]["now"]["temperature"].as());
            strcat(data, "$");

            Serial.println(data);//我需要的天气数据
        }
    }
    http.end();
}
void Get_Rencent_Weather(String api, String city)
{

    while (WiFi.status() != WL_CONNECTED)
    {
        WiFi.begin(ssid, password);
        vTaskDelay(100);
    }

    String url_xinzhi = "";
    url_xinzhi = "https://api.seniverse.com/v3/weather/daily.json?key=";
    url_xinzhi += api;
    url_xinzhi += "&location=";
    url_xinzhi += city;
    url_xinzhi += "&language=en&unit=c";
    url_xinzhi += "&start=0&days=3";

    DynamicJsonDocument doc(2048); //分配内存,动态

    HTTPClient http;
    char data[100] = {"#W:"};

    http.begin(url_xinzhi);

    int httpGet = http.GET();

    if (httpGet > 0)
    {
        if (httpGet == HTTP_CODE_OK)
        {
            String json = http.getString();

            //Serial.println(json); //打印接收到的消息

            deserializeJson(doc, json);

            // JsonObject root = doc.as();
            // JsonArray results = root["results"];
            // const char *a = results[0]["last_update"];
            // const char *b = results[0]["daily"][0]["text_day"];
                        
            /*  从doc 中提取出 需要的数据 */
            /* code_day白天天气码,code_night晚上天气码 */
            strcat(data, doc["results"][0]["daily"][0]["code_day"].as());
            strcat(data, ":");
            strcat(data, doc["results"][0]["daily"][1]["code_day"].as());
            strcat(data, ":");
            strcat(data, doc["results"][0]["daily"][2]["code_day"].as());
            strcat(data, ":");

            strcat(data, doc["results"][0]["daily"][0]["code_night"].as());
            strcat(data, ":");
            strcat(data, doc["results"][0]["daily"][1]["code_night"].as());
            strcat(data, ":");
            strcat(data, doc["results"][0]["daily"][2]["code_night"].as());
            strcat(data, "$");

            Serial.println(data);
        }
    }
    http.end();
}

/*BUG 

如果程序编译没有报错, 并且烧录成功后,
    不止一次,多次弹出/打印出 下面文本

这个其实就是 ESP32 Reset/复位时 会打印的信息
多次复位, 多为代码逻辑问题,引起了ESP32自动复位

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


如果是自带usb串口 的开发板,(烧录超级简单的示例程序  可以正常运行,说明板子一般是没问题的)
    那么可以肯定,(坚信不疑)
    一定(多数情况下)是:  代码的逻辑问题

  包括但不限于  变量生命周期错判,赋值时内存溢出,野指针,形参实参                数据类型错用,.........,

    看个人习惯了,这种错误一不留神就找出来了

----------------------------------------------------------
检错步骤(建议):
    1.代码最好 功能化,模块化

    2.在 setup 函数第一句/最开始就 delay(5000);//延时5s

    3.在每一段代码块中,多设置例如

      Serial.println("标签 1.1 ##"); 的语句, 设置

    4.烧录完成后即刻打开串口,观察串口输出数据

         观察 自己设置的标签, 清楚知道程序运行到哪里了

    5.这时,突然打印出-上述文本-, 观察相隔最近的标签, 就是这附近出毛病了,

    6.修改完成成后,再次烧录运行,观察是否能正常运行到下一个标签处

-------------------------------------------------------------------------

    分享下自己找了一天的bug,

    正常的
    String json = http.getString();
    deserializeJson(doc, json);

    错误的
    deserializeJson(doc, http.getString());

    可能原因:
    http.getString() 返回类型为 string算是个数组, c++/c 函数 返回 |函数内定义的| 数组类型数据,存不住,生命周期太短了,
    
    https://blog.csdn.net/qq_41989885/article/details/104932634
*/


心知天气返回数据 

获取今日天气 url

可以直接在 浏览器上面的访问框内输入这个 url,看看浏览器中显示的内容就是 返回数据

https: //api.seniverse.com/v3/weather/now.json?key=SJ3cQqGjCfr2Ej1oS&location=luoyang&language=en&unit=c&start=0&days=5

返回数据
HTTPGET is 200 //请求成功才返回下面数据

{
    "results": [
        {
            "location": {
                "id": "WQPUYY7S4GV2",
                "name": "Luoyang",
                "country": "CN",
                "path": "Luoyang,Luoyang,Henan,China",
                "timezone": "Asia/Shanghai",
                "timezone_offset": "+08:00"
            },
            "now": {
                "text": "Cloudy",
                "code": "4",
                "temperature": "29"
            },
            "last_update": "2022-08-02T12:34:30+08:00"
        }
    ]
}



获取今日起三天天气 url  
//非vip用户最多获取近三日天气数据,记得自己注册一个心知天气账号,修改下 API ,也就是?

可以直接在 浏览器上面的访问框内输入这个 url,看看浏览器中显示的内容就是 返回数据

key=SJ3cQqGjCfr2Ej1oS ,这个要改称自己账号的API 私钥
https: //api.seniverse.com/v3/weather/now.json?key=SJ3cQqGjCfr2Ej1oS&location=luoyang&language=en&unit=c&start=0&days=3
 

返回数据
HTTPGET is 200 //请求成功才返回下面数据

{
    "results": [
        {
            "location": {
                "id": "WQPUYY7S4GV2",
                "name": "Luoyang",
                "country": "CN",
                "path": "Luoyang,Luoyang,Henan,China",
                "timezone": "Asia/Shanghai",
                "timezone_offset": "+08:00"
            },
            "daily": [
                {
                    "date": "2022-08-02",
                    "text_day": "Shower",
                    "code_day": "10",
                    "text_night": "Cloudy",
                    "code_night": "4",
                    "high": "34",
                    "low": "24",
                    "rainfall": "5.40",
                    "precip": "0.96",
                    "wind_direction": "SE",
                    "wind_direction_degree": "135",
                    "wind_speed": "8.4",
                    "wind_scale": "2",
                    "humidity": "81"
                },
                {
                    "date": "2022-08-03",
                    "text_day": "Shower",
                    "code_day": "10",
                    "text_night": "Cloudy",
                    "code_night": "4",
                    "high": "35",
                    "low": "25",
                    "rainfall": "5.40",
                    "precip": "0.96",
                    "wind_direction": "SE",
                    "wind_direction_degree": "135",
                    "wind_speed": "8.4",
                    "wind_scale": "2",
                    "humidity": "84"
                },
                {
                    "date": "2022-08-04",
                    "text_day": "Sunny",
                    "code_day": "0",
                    "text_night": "Clear",
                    "code_night": "1",
                    "high": "36",
                    "low": "26",
                    "rainfall": "0.00",
                    "precip": "0.00",
                    "wind_direction": "SE",
                    "wind_direction_degree": "135",
                    "wind_speed": "3.0",
                    "wind_scale": "1",
                    "humidity": "83"
                }
            ],
            "last_update": "2022-08-02T08:00:00+08:00"
        }
    ]
}

https: //api.seniverse.com/v3/weather/daily.json?key=SJ3cQqGjCfr2Ej1oS&location=luoyang&language=en&unit=c&start=0&days=5


{
    "results": [
        {
            "location": {
                "id": "WQPUYY7S4GV2",
                "name": "Luoyang",
                "country": "CN",
                "path": "Luoyang,Luoyang,Henan,China",
                "timezone": "Asia/Shanghai",
                "timezone_offset": "+08:00"
            },
            "now": {
                "text": "Cloudy",
                "code": "4",
                "temperature": "31"
            },
            "last_update": "2022-08-02T13:24:14+08:00"
        }
    ]
}

{
    "results": [
        {
            "location": {
                "id": "WQPUYY7S4GV2",
                "name": "Luoyang",
                "country": "CN",
                "path": "Luoyang,Luoyang,Henan,China",
                "timezone": "Asia/Shanghai",
                "timezone_offset": "+08:00"
            },
            "daily": [
                {
                    "date": "2022-08-02",
                    "text_day": "Shower",
                    "code_day": "10",
                    "text_night": "Cloudy",
                    "code_night": "4",
                    "high": "34",
                    "low": "24",
                    "rainfall": "5.40",
                    "precip": "0.96",
                    "wind_direction": "SE",
                    "wind_direction_degree": "135",
                    "wind_speed": "8.4",
                    "wind_scale": "2",
                    "humidity": "81"
                },
                {
                    "date": "2022-08-03",
                    "text_day": "Shower",
                    "code_day": "10",
                    "text_night": "Cloudy",
                    "code_night": "4",
                    "high": "35",
                    "low": "25",
                    "rainfall": "5.40",
                    "precip": "0.96",
                    "wind_direction": "SE",
                    "wind_direction_degree": "135",
                    "wind_speed": "8.4",
                    "wind_scale": "2",
                    "humidity": "84"
                },
                {
                    "date": "2022-08-04",
                    "text_day": "Sunny",
                    "code_day": "0",
                    "text_night": "Clear",
                    "code_night": "1",
                    "high": "36",
                    "low": "26",
                    "rainfall": "0.00",
                    "precip": "0.00",
                    "wind_direction": "SE",
                    "wind_direction_degree": "135",
                    "wind_speed": "3.0",
                    "wind_scale": "1",
                    "humidity": "83"
                }
            ],
            "last_update": "2022-08-02T08:00:00+08:00"
        }
    ]
}

还有一篇和这个有关

vscode Ardunio PlatformIO导入自己写的.c.h文件的正确方法_—=-_-=—的博客-CSDN博客

心知天气 常用接口:
天气实况 · 心知天气获取指定城市的天气实况。付费用户可获取全部数据,免费用...https://seniverse.yuque.com/books/share/e52aa43f-8fe9-4ffa-860d-96c0f3cf1c49/nyiu3t
未来15天逐日天气预报和昨日天气 · 心知天气获取指定城市未来最多 15 天每天的白天和夜间预报,以...https://seniverse.yuque.com/books/share/e52aa43f-8fe9-4ffa-860d-96c0f3cf1c49/sl6gvt

整点实况 · 心知天气获取全国所有市区县(3000+)的天气实况数据更新频率...https://seniverse.yuque.com/books/share/e52aa43f-8fe9-4ffa-860d-96c0f3cf1c49/weather_obs

你可能感兴趣的:(esp32-ardunio,c++)