美文网首页我爱编程
如何用ESP8266做一个天气预报

如何用ESP8266做一个天气预报

作者: 买模块找张松 | 来源:发表于2018-06-15 17:36 被阅读11次

    1、硬件

    用一个四博智联提供的nodemcu。一个OLED屏,一个USB线,4根杜邦线,可以上网的路由器,电脑。

         3V3---VCC

         GND---GND

         GPIO4(D2)---SDA

         GPIO5(D1)---SCL

    2、设置路由器

    把路由器账号设置为把路由器账号设置为

    账号:xh003

    密码:zxd+19901120=

    3、烧录程序

    打开ESP_TOOLS下载工具,选择8266.

    工具下载:http://bbs.doit.am/forum.php?mod ... 6&highlight=TOO

    点击START.等待烧录完成。

    烧录完成后复位一下nodemcu。等待10s左右。

    测试结果如下:

    Arduino代码如下:

    #include

    #include

    #include

    #include "OLED.h"

    static const char logo[] PROGMEM={

    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xe0,0xff,0x03,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x1f,0x1c,0xf0,0x1f,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x0f,0x00,0x80,0x7f,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xff,0x01,0x00,0xfc,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xfe,0x03,0x00,0xf8,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0x07,0x00,0xf8,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xf8,0x0f,0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xf0,0x1f,0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xf0,0x1f,0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xf0,0x1f,0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xf0,0x1f,0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xf0,0x3f,0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xf0,0x1f,0x00,0xf8,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xf0,0x0f,0x00,0xf8,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xf8,0x03,0x00,0xfc,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xfc,0x00,0x00,0x7e,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x7f,0x00,0x00,0x7f,0xf8,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x00,0x00,0x00,0x80,0x1f,0x00,0x80,0x7f,0xf8,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x00,0x00,0x00,0xe0,0x07,0x00,0xc0,0x3f,0xf0,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x00,0x00,0x00,0xf8,0x01,0x00,0xe0,0x3f,0xf0,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x00,0x00,0x7f,0x00,0x00,0xf8,0x3f,0xf0,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x00,0xe0,0x1f,0x00,0x00,0xfe,0x0f,0xf0,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x00,0xf8,0x03,0x00,0x80,0xff,0x0f,0xf8,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x00,0x7e,0x00,0x00,0xe0,0xff,0x01,0xf0,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x00,0x1f,0x00,0x00,0xf8,0xff,0x00,0xf8,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0xc0,0x0f,0x00,0x00,0xfe,0x7f,0x00,0xfc,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0xe0,0x03,0x00,0x80,0xff,0x1f,0x00,0xfe,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0xf8,0x01,0x00,0xe0,0xff,0x07,0x00,0xfe,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x7c,0x00,0x00,0xfc,0xff,0x00,0x00,0xfc,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x3e,0x00,0x00,0xff,0x07,0x00,0x00,0xfc,0xff,0xff,0xff,0x7f,

    0xff,0xff,0x7f,0x00,0x0f,0x00,0xc0,0xff,0x07,0x00,0x00,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x80,0x07,0x00,0xf0,0xff,0xff,0x0f,0xc0,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xc0,0x03,0x00,0xf8,0xff,0xff,0x3f,0xf8,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xc0,0x01,0x00,0xfe,0xf8,0xc7,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xe1,0x01,0x00,0x7f,0xc0,0x03,0x87,0x00,0xfe,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xe1,0x00,0xc0,0x7f,0x80,0x01,0x86,0x00,0xfe,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x63,0x00,0xe0,0x7f,0x80,0x01,0x86,0x00,0xfe,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x63,0x00,0xe0,0x7f,0x8c,0x31,0x86,0xc3,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x67,0x00,0xc0,0x7f,0x8c,0x31,0x86,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x6f,0x00,0xc0,0x7f,0x8c,0x31,0x86,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x7f,0x00,0xc0,0x7f,0x8c,0x31,0x86,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0x7f,0x00,0xc0,0x7f,0x8c,0x31,0x86,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x00,0x80,0x7f,0x80,0x01,0x86,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x01,0x00,0x7f,0x80,0x01,0x86,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x03,0x00,0x7c,0xc0,0x03,0x87,0x83,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x07,0x00,0xf8,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x0f,0x00,0xe0,0xff,0x7f,0xf0,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xfe,0x07,0xfc,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,

    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f

    };

    //GPIO4(SDA) GPIO5(SCL)

    OLED display(4, 5);

    const char* ssid     = "xh003";         // XXXXXX -- 使用时请修改为当前你的 wifi ssid

    const char* password = "zxd+19901120=";         // XXXXXX -- 使用时请修改为当前你的 wifi 密码

    const char* host = "api.seniverse.com";

    const char* APIKEY = "wcmquevztdy1jpca";        //API KEY

    const char* city = "shenzhen";

    const char* language = "en";//zh-Hans 简体中文  会显示乱码

    const unsigned long BAUD_RATE = 115200;                   // serial connection speed

    const unsigned long HTTP_TIMEOUT = 5000;               // max respone time from server

    const size_t MAX_CONTENT_SIZE = 1000;                   // max size of the HTTP response

    // 我们要从此网页中提取的数据的类型

    struct UserData {

      char city[16];//城市名称

      char weather[32];//天气介绍(多云...)

      char temp[16];//温度

      char udate[32];//更新时间

    };

    WiFiClient client;

    char response[MAX_CONTENT_SIZE];

    char endOfHeaders[] = "\r\n\r\n";

    /**

    * @Desc 初始化操作

    */

    void setup() {

      WiFi.mode(WIFI_STA);     //设置esp8266 工作模式

      Serial.begin(BAUD_RATE);

      delay(10);

      Serial.println();

      Serial.println();

      Serial.print("Connecting to ");//写几句提示,哈哈

      Serial.println(ssid);

      WiFi.begin(ssid, password);   //连接wifi

      while (WiFi.status() != WL_CONNECTED) {

        //这个函数是wifi连接状态,返回wifi链接状态

        delay(100);

        Serial.print(".");

      }

      Serial.println("");

      Serial.println("WiFi connected");

      delay(100);

      Serial.println("IP address: ");

      Serial.println(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址

      client.setTimeout(HTTP_TIMEOUT);

    }

    /**

    * @Desc  主函数

    */

    void loop() {

       //初始化oled

      display.begin();

      //测试显示信息

      display.print("Hello DOIT",2,3);

      display.print("www.doit.am",4,3);

      delay(2*1000);

      display.clear();

      while (!client.connected()){

         if (!client.connect(host, 80)){

             Serial.println("connection....");

             delay(100);

         }

      }

      if (sendRequest(host, city, APIKEY) && skipResponseHeaders()) {

        clrEsp8266ResponseBuffer();

        readReponseContent(response, sizeof(response));

        UserData userData;

        if (parseUserData(response, &userData)) {

          printUserData(&userData);

        }

      }

      delay(300);//每5s调用一次

    }

    /**

    * @发送请求指令

    */

    bool sendRequest(const char* host, const char* cityid, const char* apiKey) {

      // We now create a URI for the request

      //心知天气

      String GetUrl = "/v3/weather/now.json?key=";

      GetUrl += apiKey;

      GetUrl += "&location=";

      GetUrl += city;

      GetUrl += "&language=";

      GetUrl += language;

      // This will send the request to the server

      client.print(String("GET ") + GetUrl + " HTTP/1.1\r\n" +

                   "Host: " + host + "\r\n" +

                   "Connection: close\r\n\r\n");

      Serial.println("create a request:");

      Serial.println(String("GET ") + GetUrl + " HTTP/1.1\r\n" +

                   "Host: " + host + "\r\n" +

                   "Connection: close\r\n");

      delay(100);

      return true;

    }

    /**

    * @Desc 跳过 HTTP 头,使我们在响应正文的开头

    */

    bool skipResponseHeaders() {

      // HTTP headers end with an empty line

      bool ok = client.find(endOfHeaders);

      if (!ok) {

        Serial.println("No response or invalid response!");

      }

      return ok;

    }

    /**

    * @Desc 从HTTP服务器响应中读取正文

    */

    void readReponseContent(char* content, size_t maxSize) {

      size_t length = client.peekBytes(content, maxSize);

      delay(100);

      Serial.println("Get the data from Internet!");

      content[length] = 0;

      Serial.println(content);

      Serial.println("Read data Over!");

      client.flush();//这句代码需要加上  不然会发现每隔一次client.find会失败

    }

    /**

    * @Desc 解析数据

    * 数据格式如下:

    * {

    *    "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(char* content, struct UserData* userData) {

    //    -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小

    //   如果你使用StaticJsonBuffer时才需要

    //    const size_t BUFFER_SIZE = 1024;

    //   在堆栈上分配一个临时内存池

    //    StaticJsonBuffer jsonBuffer;

    //    -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替

      DynamicJsonBuffer jsonBuffer;

      JsonObject& root = jsonBuffer.parseObject(content);

      if (!root.success()) {

        Serial.println("JSON parsing failed!");

        return false;

      }

      //复制我们感兴趣的字符串

      strcpy(userData->city, root["results"][0]["location"]["name"]);

      strcpy(userData->weather, root["results"][0]["now"]["text"]);

      strcpy(userData->temp, root["results"][0]["now"]["temperature"]);

      strcpy(userData->udate, root["results"][0]["last_update"]);

      //  -- 这不是强制复制,你可以使用指针,因为他们是指向“内容”缓冲区内,所以你需要确保

      //   当你读取字符串时它仍在内存中

      return true;

    }

    // 打印从JSON中提取的数据

    void printUserData( struct UserData* userData) {

      Serial.println("Print parsed data :");

      display.print("City: ",0,0);

      display.print(userData->city,0,6);

      display.print("Weat: ",2,0);

      display.print(userData->weather,2,6);

      display.print("Temp: ",4,0);

      display.print(userData->temp,4,6);

    // display.print("Last Updata : ",7,2);

    display.print(userData->udate,6,0);

    // display.print("\r\n");

    delay(4*1000);

    }

    // 关闭与HTTP服务器连接

    void stopConnect() {

      Serial.println("Disconnect");

      client.stop();

    }

    void clrEsp8266ResponseBuffer(void){

        memset(response, 0, MAX_CONTENT_SIZE);      //清空

    }

    转载地址:http://bbs.doit.am/forum.php?mod=viewthread&tid=442&extra=

    相关文章

      网友评论

        本文标题:如何用ESP8266做一个天气预报

        本文链接:https://www.haomeiwen.com/subject/prbmeftx.html