打印

【零知ESP8266教程】快速入门18 ESP8266HTTPClient库 获取天气请求

[复制链接]
596|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
roc2two|  楼主 | 2019-10-31 14:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

上次我们一起学习用ESP8266开发板创建一个热点,即发送射频信号,就像自己的智能手机可以打开热点,使得他人连接,我们智能手机的角色就是向外发送射频信号,然而,用自己的手机去连接WiFi,那手机充当的角色就是接收射频信号的啦。。

同理,零知ESP8266开发板是WiFi模块,既然有发送信号的功能(创建热点),当然也有接收信号的功能。这次的分享我们来让ESP8266开发板接收信息,一起开始实现吧。
一、硬件
电脑,windows系统
零知ESP8266开发板
micro-usb线
二、
(1)软件库:
本示例使用零知-ESP8266来获取天气信息,首先需要安装库:

也可以在GitHub下载,注意要下载5.~版本

(2)解压,然后打开零知开源软件,界面如下:

(3)安装到库




也可以解压直接复制到你lingzhi_library存放的位置

这样就完成安装了,届时要记得刷新一下,关闭软件。

三、
重新打开零知开源软件,然后烧录以下代码:

/**
* Demo:
*    演示Http请求天气接口信息
* [url=home.php?mod=space&uid=187600]@author[/url] 云上上云
* [url=home.php?mod=space&uid=212281]@date[/url] 2019/06/01
*/
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>

//以下三个定义为调试定义
#define DebugBegin(baud_rate)    Serial.begin(baud_rate)
#define DebugPrintln(message)    Serial.println(message)
#define DebugPrint(message)    Serial.print(message)

const char* AP_SSID     = "**********";         //  **********-- 使用时请修改为当前你的 wifi ssid
const char* AP_PSK = "**********";         //  **********-- 使用时请修改为当前你的 wifi 密码
const char* HOST = "http://api.seniverse.com";
const char* APIKEY = "wcmquevztdy1jpca";        //API KEY
const char* CITY = "shenzhen";
const char* LANGUAGE = "zh-Hans";//zh-Hans 简体中文  会显示乱码

const unsigned long BAUD_RATE = 115200;                   // serial connection speed
const unsigned long HTTP_TIMEOUT = 5000;               // max respone time from server

// 我们要从此网页中提取的数据的类型
struct WeatherData {
  char city[16];//城市名称
  char weather[32];//天气介绍(多云...)
  char temp[16];//温度
  char udate[32];//更新时间
};

HTTPClient http;
String GetUrl;
String response;
WeatherData weatherData;

void setup() {
  // put your setup code here, to run once:
  WiFi.mode(WIFI_STA);     //设置esp8266 工作模式
  DebugBegin(BAUD_RATE);
  DebugPrint("Connecting to ");//
  DebugPrintln(AP_SSID);
  WiFi.begin(AP_SSID, AP_PSK);   //连接wifi
  WiFi.setAutoConnect(true);
  while (WiFi.status() != WL_CONNECTED) {
    //这个函数是wifi连接状态,返回wifi链接状态
    delay(500);
    DebugPrint(".");
  }
  DebugPrintln("");
  DebugPrintln("WiFi connected");
  DebugPrintln("IP address: " + WiFi.localIP());

  //拼接get请求url  
  GetUrl = String(HOST) + "/v3/weather/now.json?key=";
  GetUrl += APIKEY;
  GetUrl += "&location=";
  GetUrl += CITY;
  GetUrl += "&language=";
  GetUrl += LANGUAGE;
  //设置超时
  http.setTimeout(HTTP_TIMEOUT);
  //设置请求url
  http.begin(GetUrl);
  //以下为设置一些头  其实没什么用 最重要是后端服务器支持
  http.setUserAgent("esp8266");//用户代理版本
  http.setAuthorization("esp8266","yssy");//用户校验信息
}

void loop() {
  //心知天气  发送http  get请求
  int httpCode = http.GET();
  if (httpCode > 0) {
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
      //判断请求是否成功
      if (httpCode == HTTP_CODE_OK) {
        //读取响应内容
        response = http.getString();
        DebugPrintln("Get the data from Internet!");
        DebugPrintln(response);
        //解析响应内容
        if (parseUserData(response, &weatherData)) {
          //打印响应内容
          printUserData(&weatherData);
        }
      }
  } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
  }
  http.end();
  delay(1000);//每1s调用一次
}

/**
* [url=home.php?mod=space&uid=1170026]@desc[/url] 解析数据 Json解析
* 数据格式如下:
* {
*    "results": [
*        {
*            "location": {
*                "id": "WX4FBXXFKE4F",
*                "name": "北京",
*                "country": "CN",
*                "path": "北京,北京,中国",
*                "timezone": "Asia/Shanghai",
*                "timezone_offset": "+08:00"
*            },
*            "now": {
*                "text": "多云",
*                "code": "4",
*                "temperature": "23"
*            },
*            "last_update": "2017-09-13T09:51:00+08:00"
*        }
*    ]
*}
*/
bool parseUserData(String content, struct WeatherData* weatherData) {
//    -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小
//   如果你使用StaticJsonBuffer时才需要
//    const size_t BUFFER_SIZE = 1024;
//   在堆栈上分配一个临时内存池
//    StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
//    -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替
  DynamicJsonBuffer jsonBuffer;

  JsonObject& root = jsonBuffer.parseObject(content);

  if (!root.success()) {
    DebugPrintln("JSON parsing failed!");
    return false;
  }

  //复制我们感兴趣的字符串
  strcpy(weatherData->city, root["results"][0]["location"]["name"]);
  strcpy(weatherData->weather, root["results"][0]["now"]["text"]);
  strcpy(weatherData->temp, root["results"][0]["now"]["temperature"]);
  strcpy(weatherData->udate, root["results"][0]["last_update"]);
  //  -- 这不是强制复制,你可以使用指针,因为他们是指向“内容”缓冲区内,所以你需要确保
  //   当你读取字符串时它仍在内存中
  return true;
}

// 打印从JSON中提取的数据
void printUserData(const struct WeatherData* weatherData) {
  DebugPrintln("Print parsed data :");
  DebugPrint("City : ");
  DebugPrint(weatherData->city);
  DebugPrint(", \t");
  DebugPrint("Weather : ");
  DebugPrint(weatherData->weather);
  DebugPrint(",\t");
  DebugPrint("Temp : ");
  DebugPrint(weatherData->temp);
  DebugPrint(" C");
  DebugPrint(",\t");
  DebugPrint("Last Updata : ");
  DebugPrint(weatherData->udate);
  DebugPrintln("\r\n");
}

2、验证,上传程序。

四、点击“调试”,就可看到结果啦,如下图:


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

75

主题

85

帖子

1

粉丝