四行代码制作你的esp8266天气时钟——基于NodeMCU、OLED模块

OLED:开学了,好闲呀!

炸鸡:给你找个无休的工作,怎么样。。。。。。

ESP8266:

物料

0.96OLED屏幕,esp8266(NodeMCU)开发板,杜邦线

可以自制PCB美化硬件组合

配置方法:(四行代码)

1.填上wifi或者热点的名称和密码

2.输入知心天气的密钥和城市名称

 硬件配置:0.96OLED spiOLED屏幕,按照程序用杜邦线连接OLED和esp8266。其他屏幕还需要改图示一行驱动构造代码。不懂的可以查看U8g2的实例代码,尝试选择合适自己的驱动构造。

深入学习Arduino u8g2 OLED库,一篇就够_单片机菜鸟哥的博客-CSDN博客_u8g2

连线:

 clock=*/ 14, /* data=*/ 13, /* cs=*/ 16, /* dc=*/ 5, /* reset=*/ 4

 功能描述:

开机等待wifi连接,扫描并连接,获取成功后进入显示界面

当wifi断开连接时,不显示图标,会利用esp8266定时器进行计时,但是天气信息不会更新

再次连接时,显示图标,更新天气、时间信息

在屏幕的显示位置会随时间左右移动,延长OLED屏幕的寿命

改进方向:

主要是基于手机热点测试的,对一直连接的wifi适配需要改进优化;

U8G2是个强大的屏幕驱动库,可以加上炫酷吊炸天的动画,但是有点麻烦

下面是总的代码,能不能点个赞(求求你这个帅哥)



/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : weather_forecast
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200601
程序目的/Purpose          : 
通过心知天气(www.seniverse.com)免费服务获取天气预报信息(三日)。
-----------------------------------------------------------------------
其它说明 / Other Description
心知天气API文档说明: https://www.seniverse.com/docs
 
本程序为太极创客团队制作的免费视频教程《零基础入门学用物联网 》中一部分。该教程系统的
向您讲述ESP8266的物联网应用相关的软件和硬件知识。以下是该教程目录页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/                                  
***********************************************************************/
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <ESP8266HTTPClient.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
/
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0
#include "TimerInterrupt_Generic.h"
//#define BUILTIN_LED     16       // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
volatile bool statusLed = false;
volatile uint32_t lastMillis = 0;
#define TIMER_INTERVAL_MS       1000

U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 14, /* data=*/ 13, /* cs=*/ 16, /* dc=*/ 5, /* reset=*/ 4);

const char* ssid     = "xiaomi";       // 连接WiFi名(此处使用taichi-maker为示例)
                                            // 请将您需要连接的WiFi名填入引号中
const char* password = "wsyj8.45l";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
 
const char* host = "api.seniverse.com";   // 将要连接的服务器地址  
const int httpPort = 80;              // 将要连接的服务器端口      
 
// 心知天气HTTP请求所需信息
String reqUserKey = "SPNgRfLgk05CtB5gr";   // 私钥
String reqLocation = "haerbin";            // 城市
String reqUnit = "c";                      // 摄氏/华氏
HTTPClient http;

String GetUrl;

String response;
int m=0;
int h=0;
int s=0;
int ss=0;
String day_we=" ";
String night_we=" ";
int high=0;
int low=0;
char test=' ';
int con_update=1;
int a1,a2,a3,a4;
int start_x=0;

u8g2_uint_t U8X8_PROGMEM screenWidth;
u8g2_uint_t U8X8_PROGMEM screenHeight;
int day_now=0;
struct DAY_INF{
  int day_weather;
  int night_weather;
  int high;
  int low;  
 }day_inf[3]={{0,0,0,0},{0,0,0,0},{0,0,0,0}};

ESP8266Timer ITimer;
void IRAM_ATTR TimerHandler()
{//中断服务函数
  // 向心知天气服务器服务器请求信息并对信息进行解析
  s++;
  if(s==60){
    s=0;
    m++;
    if(m==60){
      m=0;
      h++;
      if(h==24){
        h=0;
        day_now++;
      }
        
  }
}

  
 //Serial.println(millis());
#if (TIMER_INTERRUPT_DEBUG > 0)
  //Serial.println("Delta ms = " + String(millis() - lastMillis));
  lastMillis = millis();
#endif
}
void setup(){
  Serial.begin(115200);  
    u8g2.begin();  
   u8g2.enableUTF8Print();
   screenWidth = u8g2.getDisplayWidth();
    screenHeight = u8g2.getDisplayHeight();
   wait();        
 // Serial.println("");
  /
 // Serial.print(F("\\nStarting TimerInterruptTest on "));// Serial.println(ARDUINO_BOARD);
 // Serial.println(ESP8266_TIMER_INTERRUPT_VERSION);
 // Serial.println(TIMER_INTERRUPT_GENERIC_VERSION);
 // Serial.print(F("CPU Frequency = "));// Serial.print(F_CPU / 1000000);// Serial.println(F(" MHz"));
  // Interval in microsecs
  if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler))
  {
    lastMillis = millis();
   // Serial.print(F("Starting ITimer OK, millis() = "));// Serial.println(lastMillis);
    // Serial.println(BUILTIN_LED);
  }
  else
   // Serial.println(F("Can't set ITimer correctly. Select another freq. or interval"));
/
  // 连接WiFi
  connectWiFi();

  GetUrl = "http://quan.suning.com/getSysTime.do";
  http.setTimeout(5000);
  http.begin(GetUrl);
  while(0==httpRequest()||0==get_time()){      
      
     } 
}
const unsigned char BMP_qing_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x30,0x00,0x0c,0x60,
0x00,0x0e,0x00,0x7e,0x04,0x00,0xff,0x01,0x80,0xff,0x01,0xc0,0xff,0x03,0xc0,0xff,
0x03,0xce,0xff,0x73,0xce,0xff,0x73,0xc0,0xff,0x03,0xc0,0xff,0x03,0x80,0xff,0x01,
0x80,0xff,0x01,0x00,0xfe,0x00,0x60,0x18,0x0e,0x30,0x00,0x0c,0x00,0x18,0x00,0x00,
0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,};
const unsigned char BMP_xue_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x18,0x00,0x00,0xd9,0x00,0x00,0xfb,0x00,0x20,0x7e,0x04,0x60,
0x3c,0x06,0x6c,0x18,0x36,0x78,0x18,0x1e,0xf0,0x18,0x0e,0xfc,0x99,0x1f,0x0c,0xff,
0x30,0x00,0x3c,0x00,0x00,0x3c,0x00,0x0c,0xff,0x30,0xf8,0x99,0x3f,0xf0,0x18,0x0f,
0x78,0x18,0x1e,0x6c,0x18,0x36,0x60,0x3c,0x06,0x60,0x7e,0x04,0x00,0xff,0x00,0x00,
0xdb,0x00,0x00,0x18,0x00,0x00,0x00,0x00,};
const unsigned char BMP_duoyun_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,
0x08,0x30,0x00,0x90,0x01,0x00,0xe0,0x07,0x00,0xc0,0x0f,0x80,0x87,0x0f,0xe0,0x8f,
0xcf,0xe0,0x1f,0x0f,0xf0,0x3f,0x00,0xf8,0x3f,0x00,0xfe,0xbf,0x01,0xfe,0xff,0x07,
0xff,0xff,0x07,0xff,0xff,0x0f,0xfe,0xff,0x0f,0xfe,0xff,0x07,0xf8,0xff,0x03,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
const unsigned char BMP_yin_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x70,0x00,0x00,0xfc,0x01,0x00,0xfc,0x03,0x00,0xe3,0x03,0xe0,0xcf,0x07,0xf0,0xdf,
0x3f,0xf0,0xbf,0x7f,0xf8,0x3f,0xfe,0xfe,0x7f,0xf8,0xfe,0xff,0xf7,0xff,0xff,0xef,
0xff,0xff,0x6f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xfe,0xff,0x0f,0xfe,0xff,0x07,0xf8,
0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,};
const unsigned char BMP_xiaoyu_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3f,0x00,0x80,0x7f,0x00,0x80,0x7f,0x00,0xc0,0xff,0x00,0xf0,0xff,0x07,0xf0,0xff,
0x0f,0xf0,0xff,0x0f,0xf0,0xff,0x1f,0xf0,0xff,0x0f,0xf0,0xff,0x0f,0xe0,0xff,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
const unsigned char BMP_dayu_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x1f,0x00,0x80,0x7f,0x00,0xc0,0x7f,0x00,0xe0,0xff,0x00,0xf0,0xff,0x07,0xf8,0xff,
0x0f,0xf8,0xff,0x1f,0xf8,0xff,0x1f,0xf8,0xff,0x1f,0xf0,0xff,0x0f,0xe0,0xff,0x0f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x02,0xc0,0x18,0x03,0x40,0x1c,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
const unsigned char BMP_wifi_24X18[] U8X8_PROGMEM= { 
0x00,0xff,0x00,0xe0,0xff,0x07,0xf8,0xff,0x1f,0xfc,0xc3,0x3f,0x7e,0x00,0x7e,0x1f,
0x00,0xf8,0x0e,0x00,0x60,0x00,0xff,0x00,0xc0,0xff,0x03,0xe0,0xff,0x07,0xe0,0x81,
0x07,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x7e,0x00,0x00,0x7c,0x00,
0x00,0x3c,0x00,0x00,0x18,0x00,};

const unsigned char BMP_mai_24X24[] U8X8_PROGMEM= { 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xe0,0x81,0x07,0xf0,0xc7,0x1f,0x38,0xef,0x3d,0x1c,0x7c,
0x30,0x0c,0x38,0x30,0x0c,0x38,0x30,0x1c,0x7c,0x30,0x38,0xef,0x3c,0xf0,0xc7,0x1f,
0xe0,0x81,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
const unsigned char BMP_wu_20X20[] U8X8_PROGMEM= { 
0xc0,0x01,0x00,0xf0,0x07,0x00,0x1c,0x0c,0x00,0x0c,0x18,0x00,0x06,0x70,0x00,0x02,
0xf0,0x01,0x03,0x00,0x02,0x03,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
0x07,0xfe,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0f,0xfe,0xff,0x0f,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x07,0xfe,0xff,0x07,};
void duizhao(int a,int y,int x){
  if(a>=0&&a<=3)u8g2.drawXBM(y+start_x, x,  24, 24, BMP_qing_24X24);//晴
  if(a>=4&&a<=8)u8g2.drawXBM(y+start_x, x,  24, 24, BMP_duoyun_24X24);//多云
  if(a==9)u8g2.drawXBM(y+start_x, x,  24, 24, BMP_yin_24X24);//阴
  if(a==13)u8g2.drawXBM(y+start_x, x,  24, 24, BMP_xiaoyu_24X24);//小雨
  if((a>=10&&a<=12)||(a>=14&&a<=19))u8g2.drawXBM(y+start_x, x,  24, 24, BMP_dayu_24X24);//大雨
  if(a>=20&&a<=25)u8g2.drawXBM(y+start_x, x, 24, 24, BMP_xue_24X24);//雪
  if(a>=26&&a<=31&&a!=30)u8g2.drawXBM(y+start_x, x, 24, 24, BMP_mai_24X24);//霾
  if(a==30)u8g2.drawXBM(y+start_x+2, x+1, 20, 20, BMP_wu_20X20);//雾
}
void DisplayWeather(){
  for(int i=day_now;i<=day_now+1&&i<3;i++){
    duizhao(day_inf[i].day_weather,60*(i-day_now),20);
    duizhao(day_inf[i].night_weather,60*(i-day_now)+30,20);
  }
}

void wait(){
  u8g2.firstPage();
  do {
    u8g2.drawXBM(48, 1, 24, 18, BMP_wifi_24X18);
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.setCursor(0,50);
    u8g2.print("wait for WiFi");
  } while ( u8g2.nextPage() );
}
void shaoping(){
  static int dir=1;
 // Serial.printf("防止烧屏\n");
  if(dir==1){
    start_x++;
    if(start_x>60){dir=0;}
  }
  else{
    start_x--;
    if(start_x<=0){dir=1;}
    }
  }

void loop(){
  static int WiFi_status=1;
  u8g2.firstPage();
  ss++;
  if(ss>=10*60){
    ss=0;
    }
  if(ss%10==0){
    if(WiFi.status()== WL_CONNECTED){
       // Serial.printf("有网络\n");
        WiFi_status=1;
       httpRequest();
       get_time();
    }
    else{
     // Serial.printf("无网络\n");
      WiFi_status=0;
    }
  }

  if(ss%100==0){
    shaoping();
  }
   //Serial.printf("ss:%d\n",ss);
  do {
    if(WiFi_status==1){
       start_x=0;
       u8g2.drawXBM(90, 0, 24, 18, BMP_wifi_24X18);
    }
      // 建立心知天气API当前天气请求资源地址
      
    DisplayWeather();
    u8g2.setFont(u8g2_font_ncenB18_tr);
    u8g2.setCursor(start_x,18);
    if(h<13)u8g2.print(h);
    else u8g2.print(h-12);
    u8g2.print(':');
    if(m<10)
      u8g2.print('0');
    u8g2.print(m);
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.print(" :");
    
    if(s<10)
      u8g2.print('0');
    u8g2.print(s);
    
    
    u8g2.setCursor(start_x,60);
    u8g2.print(day_inf[day_now].high);
    u8g2.print(" / ");
    u8g2.print(day_inf[day_now].low);

    //u8g2.drawStr(0,11,results_0_daily_0_text_day_str);
  } while ( u8g2.nextPage() );
  delay(20);
  
}
 
// 向心知天气服务器服务器请求信息并对信息进行解析
int httpRequest(){
  WiFiClient client;
  String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + "&language=en&unit=" +
                  reqUnit + "&start=0&days=3";  
  // 建立http请求信息
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";
 // Serial.println(""); 
 // Serial.print("Connecting to ");// Serial.print(host);
 
  // 尝试连接服务器
  if (client.connect(host, 80)){//有网络
   // Serial.println(" Success!"); 
    // 向服务器发送http请求信息
    client.print(httpRequest);
   // Serial.println("Sending request: ");
   // Serial.println(httpRequest);  
 
    // 获取并显示服务器响应状态行 
    String status_response = client.readStringUntil('\n');
   // Serial.print("status_response: ");
   // Serial.println(status_response);

    // 使用find跳过HTTP响应头
    if (client.find("\r\n\r\n")) {
     // Serial.println("Found Header End. Start Parsing.");
    }
   // Serial.println("Found Header End. Start Parsing.");
    // 利用ArduinoJson库解析心知天气响应信息
    //digitalWrite(BUILTIN_LED, 0);  //Toggle LED Pin
    //断开客户端与服务器连接工作
    parseInfo(client);
    client.stop(); 
    return 1;
  }
  else {
   // Serial.println(" httpRequest(): connection failed!");
    //断开客户端与服务器连接工作
    client.stop(); 
    return 0;
  }   
  
}
 
// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
 // Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
 // Serial.print(ssid);// Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  delay(2000);
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(500);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
   // Serial.print(i++);// Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。                                              
 // Serial.println("");                          // WiFi连接成功后
 // Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
 // Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
 // Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。  
}
 
// 利用ArduinoJson库解析心知天气响应信息
int parseInfo(WiFiClient client){ 
 // Serial.println(F("开始解析"));
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 3*JSON_OBJECT_SIZE(14) + 860;
  DynamicJsonDocument doc(capacity);
  deserializeJson(doc, client);
  JsonObject results_0 = doc["results"][0];
  JsonArray results_0_daily = results_0["daily"];
  JsonObject results_0_daily_0 = results_0_daily[0];
  const char* results_0_daily_0_date = results_0_daily_0["date"]; 
  const char* results_0_daily_0_text_day = results_0_daily_0["text_day"]; 
  const char* results_0_daily_0_code_day = results_0_daily_0["code_day"];
  const char* results_0_daily_0_text_night = results_0_daily_0["text_night"]; 
  const char* results_0_daily_0_code_night = results_0_daily_0["code_night"]; 
  const char* results_0_daily_0_high = results_0_daily_0["high"];
  const char* results_0_daily_0_low = results_0_daily_0["low"]; 
  const char* results_0_daily_0_rainfall = results_0_daily_0["rainfall"];
  const char* results_0_daily_0_precip = results_0_daily_0["precip"]; 
  const char* results_0_daily_0_wind_direction = results_0_daily_0["wind_direction"]; 
  const char* results_0_daily_0_wind_direction_degree = results_0_daily_0["wind_direction_degree"];
  const char* results_0_daily_0_wind_speed = results_0_daily_0["wind_speed"];
  const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"];
  const char* results_0_daily_0_humidity = results_0_daily_0["humidity"];
  
  JsonObject results_0_daily_1 = results_0_daily[1];
  const char* results_0_daily_1_date = results_0_daily_1["date"];
  const char* results_0_daily_1_text_day = results_0_daily_1["text_day"];
  const char* results_0_daily_1_code_day = results_0_daily_1["code_day"];
  const char* results_0_daily_1_text_night = results_0_daily_1["text_night"]; 
  const char* results_0_daily_1_code_night = results_0_daily_1["code_night"]; 
  const char* results_0_daily_1_high = results_0_daily_1["high"];
  const char* results_0_daily_1_low = results_0_daily_1["low"]; 
  const char* results_0_daily_1_rainfall = results_0_daily_1["rainfall"]; 
  const char* results_0_daily_1_precip = results_0_daily_1["precip"]; 
  const char* results_0_daily_1_wind_direction = results_0_daily_1["wind_direction"];
  const char* results_0_daily_1_wind_direction_degree = results_0_daily_1["wind_direction_degree"]; 
  const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"];
  const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"];
  const char* results_0_daily_1_humidity = results_0_daily_1["humidity"]; 
  
  JsonObject results_0_daily_2 = results_0_daily[2];
  const char* results_0_daily_2_date = results_0_daily_2["date"];
  const char* results_0_daily_2_text_day = results_0_daily_2["text_day"];
  const char* results_0_daily_2_code_day = results_0_daily_2["code_day"];
  const char* results_0_daily_2_text_night = results_0_daily_2["text_night"];
  const char* results_0_daily_2_code_night = results_0_daily_2["code_night"];
  const char* results_0_daily_2_high = results_0_daily_2["high"]; 
  const char* results_0_daily_2_low = results_0_daily_2["low"]; 
  const char* results_0_daily_2_rainfall = results_0_daily_2["rainfall"];
  const char* results_0_daily_2_precip = results_0_daily_2["precip"]; 
  const char* results_0_daily_2_wind_direction = results_0_daily_2["wind_direction"]; 
  const char* results_0_daily_2_wind_direction_degree = results_0_daily_2["wind_direction_degree"]; 
  const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"];
  const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"]; 
  const char* results_0_daily_2_humidity = results_0_daily_2["humidity"]; 
  
  const char* results_0_last_update = results_0["last_update"]; 
  
  // 从以上信息中摘选几个通过串口监视器显示
  String results_0_daily_0_date_str = results_0_daily_0["date"].as<String>();
  String  results_0_daily_0_text_day_str = results_0_daily_0["text_day"].as<String>(); 
  int results_0_daily_0_code_day_int = results_0_daily_0["code_day"].as<int>(); 
  String results_0_daily_0_text_night_str = results_0_daily_0["text_night"].as<String>(); 
  int results_0_daily_0_code_night_int = results_0_daily_0["code_night"].as<int>(); 
  int results_0_daily_0_high_int = results_0_daily_0["high"].as<int>();
  int results_0_daily_0_low_int = results_0_daily_0["low"].as<int>();
  String results_0_last_update_str = results_0["last_update"].as<String>();

  String results_0_daily_1_date_str = results_0_daily_1["date"].as<String>();
  String  results_0_daily_1_text_day_str = results_0_daily_1["text_day"].as<String>(); 
  int results_0_daily_1_code_day_int = results_0_daily_1["code_day"].as<int>(); 
  String results_0_daily_1_text_night_str = results_0_daily_1["text_night"].as<String>(); 
  int results_0_daily_1_code_night_int = results_0_daily_1["code_night"].as<int>(); 
  int results_0_daily_1_high_int = results_0_daily_1["high"].as<int>();
  int results_0_daily_1_low_int = results_0_daily_1["low"].as<int>();

  String results_0_daily_2_date_str = results_0_daily_2["date"].as<String>();
  String  results_0_daily_2_text_day_str = results_0_daily_2["text_day"].as<String>(); 
  int results_0_daily_2_code_day_int = results_0_daily_2["code_day"].as<int>(); 
  String results_0_daily_2_text_night_str = results_0_daily_2["text_night"].as<String>(); 
  int results_0_daily_2_code_night_int = results_0_daily_2["code_night"].as<int>(); 
  int results_0_daily_2_high_int = results_0_daily_2["high"].as<int>();
  int results_0_daily_2_low_int = results_0_daily_2["low"].as<int>();
 // Serial.println(F("解析结束"));

  if(results_0_daily_0_date_str=="null")
  {
    return 0;
    }
 // Serial.println(F("======Today Weahter ======="));
 // Serial.print(F("DATE: "));
 // Serial.println(results_0_daily_0_date_str);
  
 // Serial.print(F("Day   Weather: "));
 // Serial.print(results_0_daily_0_text_day);
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_0_code_day_int);
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_1_text_day);//
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_1_code_day_int);//
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_2_text_day);
 // Serial.print(F(" "));
 // Serial.println(results_0_daily_2_code_day_int);
  
 // Serial.print(F("Night Weather: "));
 // Serial.print(results_0_daily_0_text_night_str);
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_0_code_night_int);
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_1_text_night_str);
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_1_code_night_int);
 // Serial.print(F(" "));
 // Serial.print(results_0_daily_2_text_night_str);
 // Serial.print(F(" "));
 // Serial.println(results_0_daily_2_code_night_int);
  
 // Serial.print(F("High: "));
 // Serial.println(results_0_daily_0_high_int);
 // Serial.print(F("LOW: "));
 // Serial.println(results_0_daily_0_low_int);
 // Serial.print(F("Last Update: "));
 // Serial.println(results_0_last_update_str);
 // Serial.println(F("=============================="));
  

  
  day_inf[0].day_weather=results_0_daily_0["code_day"].as<int>(); 
  day_inf[0].night_weather=results_0_daily_0["code_night"].as<int>(); 
  day_inf[0].high=results_0_daily_0_high_int;
  day_inf[0].low=results_0_daily_0_low_int;
  
  day_inf[1].day_weather=results_0_daily_1["code_day"].as<int>(); 
  day_inf[1].night_weather=results_0_daily_1["code_night"].as<int>();
  day_inf[1].high=results_0_daily_1_high_int;
  day_inf[1].low=results_0_daily_1_low_int;
  
  day_inf[2].day_weather=results_0_daily_2["code_day"].as<int>(); 
  day_inf[2].night_weather=results_0_daily_2["code_night"].as<int>();
  day_inf[2].high=results_0_daily_2_high_int;
  day_inf[2].low=results_0_daily_2_low_int;
  
  day_now=0;
  return 1;
}

int get_time(){
 // Serial.println(F("开始获取时间"));
   int httpCode = http.GET();
   //Serial.println(F("获取时间结束"));
   if(ss==0){
    con_update=1;
    }
    if(con_update==0){
     // Serial.printf("上次已经取得准确时间数据");
      }
    else{
        if (httpCode > 0) {
         // Serial.printf("[HTTP] GET... code: %d\n", httpCode);
          if (httpCode == HTTP_CODE_OK) {
              //读取响应内容
              response = http.getString();
             // Serial.println(response);
              h=int((char)response[24]-'0')*10+int((char)response[25]-'0');
              m=int((char)response[27]-'0')*10+int((char)response[28]-'0');
              s=int((char)response[30]-'0')*10+int((char)response[31]-'0');
              con_update=0;        
          }
          http.end(); 
          return 1;
        } 
        else {
           // Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
            http.end();          
        }
  }
  return 0;   
 }

  • 26
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是基于esp8266和0.96寸OLED显示屏的天气时钟代码,采用了BME280传感器获取温度、湿度和气压数据,并通过WiFi连接获取天气信息并实时更新显示: ```c++ #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266HTTPClient.h> #include <SSD1306Wire.h> #include <OLEDDisplayUi.h> // WiFi设置 const char* ssid = "YourSSID"; // 你的WiFi名称 const char* password = "YourPassword"; // 你的WiFi密码 // 服务器设置 const String serverName = "http://api.openweathermap.org/data/2.5/weather?q=Shenzhen&appid=YourAPIKey"; // 你的OpenWeatherMap API Key和城市名称 // OLED显示屏设置 SSD1306Wire display(0x3c, D2, D1); OLEDDisplayUi ui(&display); // BME280传感器设置 Adafruit_BME280 bme; // 时间设置 unsigned long currentTime = millis(); unsigned long previousTime = 0; const long interval = 60000; // 更新时间间隔,单位为毫秒 void setup() { Serial.begin(115200); // 初始化OLED显示屏 display.init(); display.setContrast(255); display.setFont(ArialMT_Plain_10); // 初始化BME280传感器 if (!bme.begin(0x76)) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1); } // 连接WiFi WiFi.begin(ssid, password); Serial.print("Connecting to "); Serial.println(ssid); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); } void loop() { currentTime = millis(); if (currentTime - previousTime >= interval) { // 获取天气信息 if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(serverName); int httpResponseCode = http.GET(); if (httpResponseCode > 0) { String payload = http.getString(); Serial.println(payload); // 解析JSON数据 const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + 60; DynamicJsonDocument doc(capacity); deserializeJson(doc, payload); const char* description = doc["weather"][0]["description"]; float temp = doc["main"]["temp"]; float humidity = doc["main"]["humidity"]; float pressure = doc["main"]["pressure"]; // 显示天气信息 display.clear(); display.drawString(0, 0, "Weather in Shenzhen"); display.drawString(0, 12, description); display.drawString(0, 24, "Temp: " + String(temp) + " C"); display.drawString(0, 36, "Humidity: " + String(humidity) + " %"); display.drawString(0, 48, "Pressure: " + String(pressure) + " hPa"); display.display(); } else { Serial.println("Error on HTTP request"); } http.end(); } else { Serial.println("WiFi Disconnected"); } previousTime = currentTime; } } ``` 需要注意的是,需要在OpenWeatherMap网站上注册账号并申请API Key,替换代码中的YourAPIKey和城市名称。 此外,如果你的OLED显示屏型号不同,可能需要修改相关的设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值