1、硬件 用一個四博智聯提供的nodemcu。一個OLED屏,一個USB線,4根杜邦線,可以上網的路由器,電腦。
212119wminzingec86jmz1.png (228.21 KB, 下載次數: 39)
下載附件
2018-6-16 04:17 上傳
3V3---VCC GND---GND GPIO4(D2)---SDA GPIO5(D1)---SCL
2、設置路由器 把路由器賬號設置為把路由器賬號設置為 賬號:xh003 密碼:zxd+19901120= 3、燒錄程序 打開ESP_TOOLS下載工具,選擇8266.
212138icdmd51lkx5y3mqo.png (99.12 KB, 下載次數: 54)
下載附件
2018-6-16 04:17 上傳
點擊START.等待燒錄完成。
燒錄完成后復位一下nodemcu。等待10s左右。 測試結果如下:
212201h3j9aplay3p2n24h.png (81.73 KB, 下載次數: 59)
下載附件
2018-6-16 04:17 上傳
212201wir44e55w6g0o4eo.png (103.3 KB, 下載次數: 48)
下載附件
2018-6-16 04:17 上傳
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[] = "";
/** * @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" + "Host: " + host + "" + "Connection: close"); Serial.println("create a request:"); Serial.println(String("GET ") + GetUrl + " HTTP/1.1" + "Host: " + host + "" + "Connection: close"); 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(""); delay(4*1000); }
// 關閉與HTTP服務器連接 void stopConnect() { Serial.println("Disconnect"); client.stop(); }
void clrEsp8266ResponseBuffer(void){ memset(response, 0, MAX_CONTENT_SIZE); //清空 }
|