如何用ESP8266做一個天氣預(yù)報

1讼溺、硬件

用一個四博智聯(lián)提供的nodemcu楣号。一個OLED屏,一個USB線怒坯,4根杜邦線炫狱,可以上網(wǎng)的路由器,電腦剔猿。

? ???3V3---VCC

? ???GND---GND

? ???GPIO4(D2)---SDA

? ???GPIO5(D1)---SCL

2视译、設(shè)置路由器

把路由器賬號設(shè)置為把路由器賬號設(shè)置為

賬號:xh003

密碼:zxd+19901120=

3、燒錄程序

打開ESP_TOOLS下載工具归敬,選擇8266.

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

點擊START.等待燒錄完成酷含。

燒錄完成后復(fù)位一下nodemcu。等待10s左右汪茧。

測試結(jié)果如下:

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

// 我們要從此網(wǎng)頁中提取的數(shù)據(jù)的類型

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);? ???//設(shè)置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) {

? ? //這個函數(shù)是wifi連接狀態(tài),返回wifi鏈接狀態(tài)

? ? 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??主函數(shù)

*/

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調(diào)用一次

}

/**

* @發(fā)送請求指令

*/

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 頭舱污,使我們在響應(yīng)正文的開頭

*/

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服務(wù)器響應(yīng)中讀取正文

*/

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();//這句代碼需要加上??不然會發(fā)現(xiàn)每隔一次client.find會失敗

}

/**

* @Desc 解析數(shù)據(jù)

* 數(shù)據(jù)格式如下:

* {

*? ? "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) {

//? ? -- 根據(jù)我們需要解析的數(shù)據(jù)來計算JSON緩沖區(qū)最佳大小

//? ?如果你使用StaticJsonBuffer時才需要

//? ? const size_t BUFFER_SIZE = 1024;

//? ?在堆棧上分配一個臨時內(nèi)存池

//? ? StaticJsonBuffer jsonBuffer;

//? ? -- 如果堆棧的內(nèi)存池太大呀舔,使用 DynamicJsonBuffer jsonBuffer 代替

??DynamicJsonBuffer jsonBuffer;

??JsonObject& root = jsonBuffer.parseObject(content);

??if (!root.success()) {

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

? ? return false;

??}

??//復(fù)制我們感興趣的字符串

??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"]);

??//??-- 這不是強制復(fù)制,你可以使用指針慌闭,因為他們是指向“內(nèi)容”緩沖區(qū)內(nèi)别威,所以你需要確保

??//? ?當你讀取字符串時它仍在內(nèi)存中

??return true;

}

// 打印從JSON中提取的數(shù)據(jù)

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);

}

// 關(guān)閉與HTTP服務(wù)器連接

void stopConnect() {

??Serial.println("Disconnect");

??client.stop();

}

void clrEsp8266ResponseBuffer(void){

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

}

轉(zhuǎn)載地址:http://bbs.doit.am/forum.php?mod=viewthread&tid=442&extra=

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市驴剔,隨后出現(xiàn)的幾起案子省古,更是在濱河造成了極大的恐慌,老刑警劉巖丧失,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豺妓,死亡現(xiàn)場離奇詭異,居然都是意外死亡布讹,警方通過查閱死者的電腦和手機琳拭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來描验,“玉大人白嘁,你說我怎么就攤上這事”炝鳎” “怎么了絮缅?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵鲁沥,是天一觀的道長。 經(jīng)常有香客問我耕魄,道長画恰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任吸奴,我火速辦了婚禮允扇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘则奥。我一直安慰自己考润,他們只是感情好,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布读处。 她就那樣靜靜地躺著额划,像睡著了一般。 火紅的嫁衣襯著肌膚如雪档泽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天揖赴,我揣著相機與錄音馆匿,去河邊找鬼。 笑死燥滑,一個胖子當著我的面吹牛渐北,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铭拧,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼赃蛛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搀菩?” 一聲冷哼從身側(cè)響起呕臂,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肪跋,沒想到半個月后歧蒋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡州既,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年谜洽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吴叶。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡阐虚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚌卤,到底是詐尸還是另有隱情实束,我是刑警寧澤奥秆,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站磕洪,受9級特大地震影響吭练,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜析显,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一鲫咽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谷异,春花似錦舌涨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尺上,卻和暖如春材蛛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怎抛。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工卑吭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人马绝。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓豆赏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親富稻。 傳聞我的和親對象是個殘疾皇子掷邦,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容