| 
 1、硬件 用一个四博智联提供的nodemcu。一个OLED屏,一个USB线,4根杜邦线,可以上网的路由器,电脑。  
 
     3V3---VCC      GND---GND      GPIO4(D2)---SDA      GPIO5(D1)---SCL  
2、设置路由器 把路由器账号设置为把路由器账号设置为 账号:xh003 密码:zxd+19901120= 3、烧录程序 打开ESP_TOOLS下载工具,选择8266.  
点击START.等待烧录完成。  
烧录完成后复位一下nodemcu。等待10s左右。 测试结果如下:  
 
 
#include <ArduinoJson.h> #include <Wire.h> #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<BUFFER_SIZE> 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);      //清空 }  
 |