如何用ESP8266做一个天气预报

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=

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容