2041浏览
查看: 2041|回复: 11

天气时钟(基于esp8266)

[复制链接]
最近老师发奖励,就要了个esp8266,想着做点什么东西,正好就看到了天气时钟,想着做一个来看看天气和时间。
准备:
       1、esp8266 (NodeMCU V3

          2、OLED 屏幕128x64    (4pin llc)

          3、杜邦线若干

接线:
       esp8266             OLED
              3.3v------------vcc


              GND----------GND


               D1------------SCL


               D2------------SDA


天气时钟(基于esp8266)图4




程序:

  1. //引入必要的头文件
  2. #include <ArduinoJson.h>
  3. #include <ESP8266WiFi.h>
  4. #include <SPI.h>
  5. #include <U8g2lib.h>
  6. #include <WiFiUdp.h>
  7. #include <TimeLib.h>
  8. #include <DNSServer.h>
  9. #include <ESP8266WebServer.h>
  10. WiFiUDP Udp;
  11. unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口
  12. //网络校时的相关配置
  13. static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,使用阿里云
  14. int timeZone = 8; //时区设置,采用东8区
  15. //保存断网前的最新数据
  16. int results_0_now_temperature_int_old;
  17. String results_0_now_text_str_old;
  18. int results_0_daily_1_high_int_old;
  19. int results_0_daily_1_low_int_old;
  20. String results_0_daily_1_text_day_str_old;
  21. //函数声明
  22. time_t getNtpTime();
  23. void sendNTPpacket(IPAddress &address);
  24. void oledClockDisplay();
  25. void sendCommand(int command, int value);
  26. void initdisplay();
  27. void connectWiFi();
  28. void parseInfo_now(WiFiClient client,int i);
  29. void parseInfo_fut(WiFiClient client,int i);
  30. //
  31. boolean isNTPConnected = false;
  32. const unsigned char xing[] U8X8_PROGMEM = {
  33.     0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
  34.     0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00}; /*星*/
  35. const unsigned char liu[] U8X8_PROGMEM = {
  36.     0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
  37.     0x20, 0x02, 0x20, 0x04, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x04, 0x20, 0x02, 0x20, 0x00, 0x00}; /*六*/
  38. typedef struct
  39. {                  //存储配置结构体
  40.     int tz;        //时间戳
  41. } config_type;
  42. config_type config;
  43. WiFiClient clientNULL;
  44. DNSServer dnsServer;
  45. ESP8266WebServer server(80);
  46. //----------WIFI连接配置----------
  47. const char* ssid     = "XXX";       // 连接WiFi名(此处使用XXX为示例)                                   
  48. const char* password = "12345678";          // 连接WiFi密码(此处使用12345678为示例)
  49.                                             // 请将您需要连接的WiFi密码填入引号中
  50. //----------天气API配置----------
  51. const char* host = "api.seniverse.com";   // 将要连接的服务器地址  
  52. const int httpPort = 80;              // 将要连接的服务器端口      
  53. // 心知天气HTTP请求所需信息
  54. String reqUserKey = "XXXXXX";   // 私钥
  55. String reqLocation = "hangzhou";            // 城市
  56. String reqUnit = "c";                      // 摄氏/华氏
  57. //----------设置屏幕----------
  58. U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
  59. int sta = 0;
  60. //----------初始化OLED----------
  61. void initdisplay()
  62. {
  63.     u8g2.begin();
  64.     u8g2.enableUTF8Print();
  65. }
  66. //----------用于获取实时天气的函数(0)----------
  67. void TandW(){
  68.   String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
  69.                   + "&location=" + reqLocation +
  70.                   "&language=en&unit=" +reqUnit;
  71.   // 向心知天气服务器服务器请求信息并对信息进行解析
  72.   httpRequest(reqRes,0);
  73.   //延迟,需要低于20次/分钟
  74.   delay(5000);
  75. }
  76. void display_1(int results_0_now_temperature_int,String results_0_now_text_str);//声明函数,用于显示温度、天气
  77. //----------获取3天预报(1)----------
  78. void threeday(){
  79.   // 建立心知天气API当前天气请求资源地址
  80.   String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
  81.                   + "&location=" + reqLocation + "&language=en&unit=" +
  82.                   reqUnit + "&start=0&days=3";
  83.   // 向心知天气服务器服务器请求信息并对信息进行解析
  84.   httpRequest(reqRes,1);
  85.   delay(5000);
  86. }
  87. void clock_display(time_t prevDisplay){
  88.     server.handleClient();
  89.     dnsServer.processNextRequest();
  90.     if (timeStatus() != timeNotSet)
  91.     {
  92.         if (now() != prevDisplay)
  93.         { //时间改变时更新显示
  94.             prevDisplay = now();
  95.             oledClockDisplay();
  96.         }
  97.     }
  98. }
  99. void setup(){
  100.   Serial.begin(9600);         
  101.   Serial.println("");
  102.   initdisplay();
  103.   // 连接WiFi
  104.   
  105.   
  106.   u8g2.clearBuffer();
  107.   u8g2.setFont(u8g2_font_unifont_t_chinese2);
  108.   u8g2.setCursor(0, 14);
  109.   u8g2.print("Waiting for WiFi");
  110.   u8g2.setCursor(0, 30);
  111.   u8g2.print("connection...");
  112.   u8g2.sendBuffer();
  113.   connectWiFi();
  114.   Udp.begin(localPort);
  115.   setSyncProvider(getNtpTime);
  116.   setSyncInterval(300); //每300秒同步一次时间
  117.   
  118. }
  119. time_t prevDisplay = 0; //当时钟已经显示
  120. void loop(){
  121.     if (sta>=0 && sta<=250){
  122.       clock_display(prevDisplay);
  123.       
  124.     }else if(sta == 251){
  125.       TandW();
  126.       
  127.     }else{
  128.       threeday();
  129.       
  130.     }
  131.     ++sta;
  132.     if(sta==253){
  133.       sta = 0;
  134.     }
  135. }
  136. // 向心知天气服务器服务器请求信息并对信息进行解析
  137. void httpRequest(String reqRes,int stat){
  138.   WiFiClient client;
  139.   // 建立http请求信息
  140.   String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
  141.                               "Host: " + host + "\r\n" +
  142.                               "Connection: close\r\n\r\n";
  143.   Serial.println("");
  144.   Serial.print("Connecting to "); Serial.print(host);
  145.   // 尝试连接服务器
  146.   if (client.connect(host, 80)){
  147.     Serial.println(" Success!");
  148.     // 向服务器发送http请求信息
  149.     client.print(httpRequest);
  150.     Serial.println("Sending request: ");
  151.     Serial.println(httpRequest);  
  152.     // 获取并显示服务器响应状态行
  153.     String status_response = client.readStringUntil('\n');
  154.     Serial.print("status_response: ");
  155.     Serial.println(status_response);
  156.     // 使用find跳过HTTP响应头
  157.     if (client.find("\r\n\r\n")) {
  158.       Serial.println("Found Header End. Start Parsing.");
  159.     }
  160.     if (stat == 0){
  161.       
  162.       // 利用ArduinoJson库解析心知天气响应信息(实时数据)
  163.       parseInfo_now(client,1);
  164.     }else if(stat == 1){
  165.       parseInfo_fut(client,1);
  166.     }
  167.   }
  168.   else {
  169.     Serial.println(" connection failed!");
  170.     if (stat == 0){
  171.       
  172.       // 利用ArduinoJson库解析心知天气响应信息(实时数据)
  173.       parseInfo_now(clientNULL,0);
  174.     }else if(stat == 1){
  175.       parseInfo_fut(clientNULL,0);
  176.     }
  177.   }
  178.    
  179.   //断开客户端与服务器连接工作
  180.   client.stop();
  181. }
  182. // 连接WiFi
  183. void connectWiFi(){
  184.   WiFi.begin(ssid, password);                  // 启动网络连接
  185.   Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  186.   Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  187.   
  188.   int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  189.   while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。
  190.     delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
  191.     Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  192.   }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
  193.                                                // 这个读秒是通过变量i每隔一秒自加1来实现的。                                             
  194.   Serial.println("");                          // WiFi连接成功后
  195.   Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  196.   Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  197.   Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。  
  198. }
  199. // 利用ArduinoJson库解析心知天气响应信息(实时)
  200. void parseInfo_now(WiFiClient client,int i){
  201.   if(i==1){
  202.   const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  203.   DynamicJsonDocument doc(capacity);
  204.   
  205.   deserializeJson(doc, client);
  206.   
  207.   JsonObject results_0 = doc["results"][0];
  208.   
  209.   JsonObject results_0_now = results_0["now"];
  210.   const char* results_0_now_text = results_0_now["text"]; // "Sunny"
  211.   const char* results_0_now_code = results_0_now["code"]; // "0"
  212.   const char* results_0_now_temperature = results_0_now["temperature"]; // "32"
  213.   
  214.   const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00"
  215.   // 通过串口监视器显示以上信息
  216.   String results_0_now_text_str = results_0_now["text"].as<String>();
  217.   int results_0_now_code_int = results_0_now["code"].as<int>();
  218.   int results_0_now_temperature_int = results_0_now["temperature"].as<int>();
  219.   String results_0_last_update_str = results_0["last_update"].as<String>();   
  220.   Serial.println(F("======Weahter Now======="));
  221.   Serial.print(F("Weather Now: "));
  222.   Serial.print(results_0_now_text_str);
  223.   Serial.print(F(" "));
  224.   Serial.println(results_0_now_code_int);
  225.   Serial.print(F("Temperature: "));
  226.   Serial.println(results_0_now_temperature_int);
  227.   Serial.print(F("Last Update: "));
  228.   Serial.println(results_0_last_update_str);
  229.   Serial.println(F("========================"));
  230.   display_0(results_0_now_temperature_int,results_0_now_text_str);
  231.   results_0_now_text_str_old = results_0_now_text_str;
  232.   results_0_now_temperature_int_old = results_0_now_temperature_int;
  233.   }
  234.   else{
  235.     display_0(results_0_now_temperature_int_old,results_0_now_text_str_old);
  236.   }
  237. }
  238. //----------输出实时天气----------
  239. void display_0(int results_0_now_temperature_int,String results_0_now_text_str){
  240.   //显示输出
  241.   u8g2.clearBuffer();
  242.   u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  243.   u8g2.setCursor(15, 14);
  244.   u8g2.print("杭州实时天气");
  245.   u8g2.setFont(u8g2_font_logisoso24_tr);
  246.   u8g2.setCursor(45, 44);
  247.   u8g2.print(results_0_now_temperature_int);
  248.   u8g2.setCursor(35, 61);
  249.   u8g2.setFont(u8g2_font_unifont_t_chinese2);
  250.   u8g2.print(results_0_now_text_str);
  251.   u8g2.sendBuffer();
  252. }
  253. // 利用ArduinoJson库解析心知天气响应信息(预测)
  254. void parseInfo_fut(WiFiClient client,int i){
  255.   if(i==1){
  256.    
  257.   
  258.   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;
  259.   
  260.   DynamicJsonDocument doc(capacity);
  261.   
  262.   deserializeJson(doc, client);
  263.   
  264.   JsonObject results_0 = doc["results"][0];
  265.   
  266.   JsonArray results_0_daily = results_0["daily"];
  267.   
  268.   JsonObject results_0_daily_0 = results_0_daily[0];
  269.   const char* results_0_daily_0_date = results_0_daily_0["date"];
  270.   const char* results_0_daily_0_text_day = results_0_daily_0["text_day"];
  271.   const char* results_0_daily_0_code_day = results_0_daily_0["code_day"];
  272.   const char* results_0_daily_0_text_night = results_0_daily_0["text_night"];
  273.   const char* results_0_daily_0_code_night = results_0_daily_0["code_night"];
  274.   const char* results_0_daily_0_high = results_0_daily_0["high"];
  275.   const char* results_0_daily_0_low = results_0_daily_0["low"];
  276.   const char* results_0_daily_0_rainfall = results_0_daily_0["rainfall"];
  277.   const char* results_0_daily_0_precip = results_0_daily_0["precip"];
  278.   const char* results_0_daily_0_wind_direction = results_0_daily_0["wind_direction"];
  279.   const char* results_0_daily_0_wind_direction_degree = results_0_daily_0["wind_direction_degree"];
  280.   const char* results_0_daily_0_wind_speed = results_0_daily_0["wind_speed"];
  281.   const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"];
  282.   const char* results_0_daily_0_humidity = results_0_daily_0["humidity"];
  283.   
  284.   JsonObject results_0_daily_1 = results_0_daily[1];
  285.   const char* results_0_daily_1_date = results_0_daily_1["date"];
  286.   const char* results_0_daily_1_text_day = results_0_daily_1["text_day"];
  287.   const char* results_0_daily_1_code_day = results_0_daily_1["code_day"];
  288.   const char* results_0_daily_1_text_night = results_0_daily_1["text_night"];
  289.   const char* results_0_daily_1_code_night = results_0_daily_1["code_night"];
  290.   const char* results_0_daily_1_high = results_0_daily_1["high"];
  291.   const char* results_0_daily_1_low = results_0_daily_1["low"];
  292.   const char* results_0_daily_1_rainfall = results_0_daily_1["rainfall"];
  293.   const char* results_0_daily_1_precip = results_0_daily_1["precip"];
  294.   const char* results_0_daily_1_wind_direction = results_0_daily_1["wind_direction"];
  295.   const char* results_0_daily_1_wind_direction_degree = results_0_daily_1["wind_direction_degree"];
  296.   const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"];
  297.   const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"];
  298.   const char* results_0_daily_1_humidity = results_0_daily_1["humidity"];
  299.   
  300.   JsonObject results_0_daily_2 = results_0_daily[2];
  301.   const char* results_0_daily_2_date = results_0_daily_2["date"];
  302.   const char* results_0_daily_2_text_day = results_0_daily_2["text_day"];
  303.   const char* results_0_daily_2_code_day = results_0_daily_2["code_day"];
  304.   const char* results_0_daily_2_text_night = results_0_daily_2["text_night"];
  305.   const char* results_0_daily_2_code_night = results_0_daily_2["code_night"];
  306.   const char* results_0_daily_2_high = results_0_daily_2["high"];
  307.   const char* results_0_daily_2_low = results_0_daily_2["low"];
  308.   const char* results_0_daily_2_rainfall = results_0_daily_2["rainfall"];
  309.   const char* results_0_daily_2_precip = results_0_daily_2["precip"];
  310.   const char* results_0_daily_2_wind_direction = results_0_daily_2["wind_direction"];
  311.   const char* results_0_daily_2_wind_direction_degree = results_0_daily_2["wind_direction_degree"];
  312.   const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"];
  313.   const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"];
  314.   const char* results_0_daily_2_humidity = results_0_daily_2["humidity"];
  315.   
  316.   const char* results_0_last_update = results_0["last_update"];
  317.   
  318.   // 从以上信息中摘选几个通过串口监视器显示
  319.   String results_0_daily_0_date_str = results_0_daily_0["date"].as<String>();
  320.   String  results_0_daily_0_text_day_str = results_0_daily_0["text_day"].as<String>();
  321.   int results_0_daily_0_code_day_int = results_0_daily_0["code_day"].as<int>();
  322.   String results_0_daily_0_text_night_str = results_0_daily_0["text_night"].as<String>();
  323.   int results_0_daily_0_code_night_int = results_0_daily_0["code_night"].as<int>();
  324.   int results_0_daily_0_high_int = results_0_daily_0["high"].as<int>();
  325.   int results_0_daily_0_low_int = results_0_daily_0["low"].as<int>();
  326.   String results_0_last_update_str = results_0["last_update"].as<String>();
  327.   int results_0_daily_1_high_int = results_0_daily_1["high"].as<int>();
  328.   int results_0_daily_1_low_int = results_0_daily_1["low"].as<int>();
  329.   String results_0_daily_1_text_day_str = results_0_daily_1["text_day"].as<String>();
  330.   Serial.println(F("======Today Weahter ======="));
  331.   Serial.print(F("DATE: "));
  332.   Serial.println(results_0_daily_0_date_str);
  333.   Serial.print(F("Day Weather: "));
  334.   Serial.print(results_0_daily_0_text_day_str);
  335.   Serial.print(F(" "));
  336.   Serial.println(results_0_daily_0_code_day_int);
  337.   Serial.print(F("Night Weather: "));
  338.   Serial.print(results_0_daily_0_text_night_str);
  339.   Serial.print(F(" "));
  340.   Serial.println(results_0_daily_0_code_night_int);
  341.   Serial.print(F("High: "));
  342.   Serial.println(results_0_daily_0_high_int);
  343.   Serial.print(F("LOW: "));
  344.   Serial.println(results_0_daily_0_low_int);
  345.   Serial.print(F("Last Update: "));
  346.   Serial.println(results_0_last_update_str);
  347.   Serial.println(F("=============================="));
  348.   display_1(results_0_daily_1_high_int,results_0_daily_1_low_int,results_0_daily_1_text_day_str);
  349.   results_0_daily_1_high_int_old=results_0_daily_1_high_int;
  350.   results_0_daily_1_low_int_old=results_0_daily_1_low_int;
  351.   results_0_daily_1_text_day_str_old=results_0_daily_1_text_day_str;
  352. }else{
  353.   display_1(results_0_daily_1_high_int_old,results_0_daily_1_low_int_old,results_0_daily_1_text_day_str_old);
  354. }
  355.   
  356. }
  357. //----------预测明天天气----------
  358. void display_1(int results_0_daily_1_high_int,int results_0_daily_1_low_int,String results_0_daily_1_text_day_str){
  359.   //显示输出
  360.   u8g2.clearBuffer();
  361.   u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  362.   u8g2.setCursor(15, 14);
  363.   u8g2.print("杭州明天天气");
  364.   
  365.   u8g2.setFont(u8g2_font_logisoso24_tr);
  366.   u8g2.setCursor(20, 46);
  367.   u8g2.print(results_0_daily_1_low_int);
  368.   u8g2.setCursor(56, 46);
  369.   u8g2.print("~");
  370.   u8g2.setCursor(75, 46);
  371.   u8g2.print(results_0_daily_1_high_int);
  372.   
  373.   u8g2.setCursor(30, 62);
  374.   u8g2.setFont(u8g2_font_unifont_t_chinese2);
  375.   u8g2.print(results_0_daily_1_text_day_str);
  376.   u8g2.sendBuffer();
  377. }
  378. /*-------- NTP 代码 ----------*/
  379. const int NTP_PACKET_SIZE = 48;     // NTP时间在消息的前48个字节里
  380. byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区
  381. time_t getNtpTime()
  382. {
  383.     IPAddress ntpServerIP; // NTP服务器的地址
  384.     while (Udp.parsePacket() > 0)
  385.         ; // 丢弃以前接收的任何数据包
  386.     Serial.println("Transmit NTP Request");
  387.     // 从池中获取随机服务器
  388.     WiFi.hostByName(ntpServerName, ntpServerIP);
  389.     Serial.print(ntpServerName);
  390.     Serial.print(": ");
  391.     Serial.println(ntpServerIP);
  392.     sendNTPpacket(ntpServerIP);
  393.     uint32_t beginWait = millis();
  394.     while (millis() - beginWait < 1500)
  395.     {
  396.         int size = Udp.parsePacket();
  397.         if (size >= NTP_PACKET_SIZE)
  398.         {
  399.             Serial.println("Receive NTP Response");
  400.             isNTPConnected = true;
  401.             Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
  402.             unsigned long secsSince1900;
  403.             // 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
  404.             secsSince1900 = (unsigned long)packetBuffer[40] << 24;
  405.             secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
  406.             secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
  407.             secsSince1900 |= (unsigned long)packetBuffer[43];
  408.             Serial.println(secsSince1900);
  409.             Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
  410.             return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
  411.         }
  412.     }
  413.     Serial.println("No NTP Response :-("); //无NTP响应
  414.     isNTPConnected = false;
  415.     return 0; //如果未得到时间则返回0
  416. }
  417. // 向给定地址的时间服务器发送NTP请求
  418. void sendNTPpacket(IPAddress &address)
  419. {
  420.     memset(packetBuffer, 0, NTP_PACKET_SIZE);
  421.     packetBuffer[0] = 0b11100011; // LI, Version, Mode
  422.     packetBuffer[1] = 0;          // Stratum, or type of clock
  423.     packetBuffer[2] = 6;          // Polling Interval
  424.     packetBuffer[3] = 0xEC;       // Peer Clock Precision
  425.     // 8 bytes of zero for Root Delay & Root Dispersion
  426.     packetBuffer[12] = 49;
  427.     packetBuffer[13] = 0x4E;
  428.     packetBuffer[14] = 49;
  429.     packetBuffer[15] = 52;
  430.     Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
  431.     Udp.write(packetBuffer, NTP_PACKET_SIZE);
  432.     Udp.endPacket();
  433. }
  434. void oledClockDisplay()
  435. {
  436.     int years, months, days, hours, minutes, seconds, weekdays;
  437.     years = year();
  438.     months = month();
  439.     days = day();
  440.     hours = hour();
  441.     minutes = minute();
  442.     seconds = second();
  443.     weekdays = weekday();
  444.     Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
  445.     u8g2.clearBuffer();
  446.     u8g2.setFont(u8g2_font_unifont_t_chinese2);
  447.     u8g2.setCursor(0, 14);
  448.     if (isNTPConnected)
  449.     {
  450.         if(timeZone>=0)
  451.         {
  452.             u8g2.print("当前时间(UTC+");
  453.             u8g2.print(timeZone);
  454.             u8g2.print(")");
  455.         }
  456.         else
  457.         {
  458.             u8g2.print("当前时间(UTC");
  459.             u8g2.print(timeZone);
  460.             u8g2.print(")");
  461.         }
  462.     }
  463.     else
  464.         u8g2.print("无网络!"); //如果上次对时失败,则会显示无网络
  465.     String currentTime = "";
  466.     if (hours < 10)
  467.         currentTime += 0;
  468.     currentTime += hours;
  469.     currentTime += ":";
  470.     if (minutes < 10)
  471.         currentTime += 0;
  472.     currentTime += minutes;
  473.     currentTime += ":";
  474.     if (seconds < 10)
  475.         currentTime += 0;
  476.     currentTime += seconds;
  477.     String currentDay = "";
  478.     currentDay += years;
  479.     currentDay += "/";
  480.     if (months < 10)
  481.         currentDay += 0;
  482.     currentDay += months;
  483.     currentDay += "/";
  484.     if (days < 10)
  485.         currentDay += 0;
  486.     currentDay += days;
  487.     u8g2.setFont(u8g2_font_logisoso24_tr);
  488.     u8g2.setCursor(0, 44);
  489.     u8g2.print(currentTime);
  490.     u8g2.setCursor(0, 61);
  491.     u8g2.setFont(u8g2_font_unifont_t_chinese2);
  492.     u8g2.print(currentDay);
  493.     u8g2.drawXBM(80, 48, 16, 16, xing);
  494.     u8g2.setCursor(95, 62);
  495.     u8g2.print("期");
  496.     if (weekdays == 1)
  497.         u8g2.print("日");
  498.     else if (weekdays == 2)
  499.         u8g2.print("一");
  500.     else if (weekdays == 3)
  501.         u8g2.print("二");
  502.     else if (weekdays == 4)
  503.         u8g2.print("三");
  504.     else if (weekdays == 5)
  505.         u8g2.print("四");
  506.     else if (weekdays == 6)
  507.         u8g2.print("五");
  508.     else if (weekdays == 7)
  509.         u8g2.drawXBM(111, 49, 16, 16, liu);
  510.     u8g2.sendBuffer();
  511. }
复制代码
效果图:天气时钟(基于esp8266)图1天气时钟(基于esp8266)图2天气时钟(基于esp8266)图3


木子呢  管理员

发表于 2023-7-7 13:15:37

666
回复

使用道具 举报

腿毛利小五郎  初级技匠

发表于 2023-7-8 15:12:24

强啊!!!
回复

使用道具 举报

想不出一个好名字  见习技师
 楼主|

发表于 2023-7-9 12:49:55

这个天气时钟需要用心知天气的api来获取天气,所以要开通心知天气(免费版就行),获取私钥。然后下载心知天气上的城市列表,找到自己的城市后面的拼音拼写填到String reqLocation = "hangzhou"; 的引号中。然后把u8g2.print("杭州实时天气");括号中的杭州改成自己的城市名,u8g2.print("杭州明天天气");
括号中的杭州改成自己的城市名。
回复

使用道具 举报

三春牛-创客  初级技神

发表于 2023-7-10 21:31:46

厉害厉害!
回复

使用道具 举报

三春牛-创客  初级技神

发表于 2023-7-10 21:32:50

赞啊!!
回复

使用道具 举报

ETO.  见习技师

发表于 2023-7-11 22:03:21

厉害厉害
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-7-11 22:05:29

厉害厉害
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-7-11 22:07:36

赞赞赞赞赞
回复

使用道具 举报

罗罗罗  中级技师

发表于 2024-4-14 11:32:37

666
回复

使用道具 举报

999888777666  学徒

发表于 2024-5-4 21:52:20

哪个大神能给我一个密匙啊?谢谢!
回复

使用道具 举报

999888777666  学徒

发表于 2024-5-4 21:53:23

想不出一个好名字 发表于 2023-7-9 12:49
这个天气时钟需要用心知天气的api来获取天气,所以要开通心知天气(免费版就行),获取私钥。然后下载心知 ...

大神,能给我一个密匙吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail