数码之家

 找回密码
 立即注册
搜索
查看: 953|回复: 16

求个ESP32的网络时钟+室内温湿度整合

[复制链接]
发表于 2023-5-30 14:11:06 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 martinku 于 2023-5-30 14:27 编辑

最近在玩ESP32的小板子,现在手上有自己整合起来的网络时钟程序,带日期、时间和天气预报显示,每十秒自动切换时间日期、本地实时天气和明天天气,现在手里还整了个DHT11的室内温湿度显示小程序,实时显示室内温湿度。想把这个实时显示温湿度的功能放到网络时钟那个程序里,这样就能实现4屏自动切换,时间日期——》本地实时天气——》明天天气预报——》室内温湿度等四屏轮番切换。硬件是ESP8266+0.96OLED四线iic通讯,我独立的两个程序的源码都有,现在想求教把室内温湿度放到网络时钟里轮番显示的代码,请坛里的高手们指教一下怎么做,编程用的arduino,我附上两个程序的源代码,求教怎样整合起来。

网络时钟程序://引入必要的头文件
#include <Arduino.h>
#include <DHT.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include <Adafruit_Sensor.h>
#include <DHT_U.h>
#define DHTPIN 14  //根据硬件连接确定引脚编号
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h,t;

#include <ArduinoJson.h>
#include <WiFi.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <DNSServer.h>
#include <WebServer.h>
WiFiUDP Udp;
unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口

//网络校时的相关配置
static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,使用阿里云
int timeZone = 8; //时区设置,采用东8区

//保存断网前的最新数据
int results_0_now_temperature_int_old;
String results_0_now_text_str_old;
int results_0_daily_1_high_int_old;
int results_0_daily_1_low_int_old;
String results_0_daily_1_text_day_str_old;

//函数声明
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
void oledClockDisplay();
void sendCommand(int command, int value);
void initdisplay();
void connectWiFi();
void parseInfo_now(WiFiClient client,int i);
void parseInfo_fut(WiFiClient client,int i);
//
boolean isNTPConnected = false;

const unsigned char xing[] U8X8_PROGMEM = {
    0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
    0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00}; /*星*/
const unsigned char liu[] U8X8_PROGMEM = {
    0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
    0x20, 0x02, 0x20, 0x04, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x04, 0x20, 0x02, 0x20, 0x00, 0x00}; /*六*/

typedef struct
{                  //存储配置结构体
    int tz;        //时间戳
} config_type;
config_type config;

WiFiClient clientNULL;
DNSServer dnsServer;
WebServer server(80);


//----------WIFI连接配置----------
const char* ssid     = "HDS668";       // 连接WiFi名(此处使用XXX为示例)
const char* password = "anby9835";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
//----------天气API配置----------
const char* host = "api.seniverse.com";   // 将要连接的服务器地址
const int httpPort = 80;              // 将要连接的服务器端口

// 心知天气HTTP请求所需信息
String reqUserKey = "SXXXXX";   // 私钥
String reqLocation = "taian";            // 城市自行更改(一定用拼音小写,例如:beijing)
String reqUnit = "c";                      // 摄氏/华氏

//----------设置屏幕----------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
int sta = 0;
//----------初始化OLED----------
void initdisplay()
{
    u8g2.begin();
    u8g2.enableUTF8Print();
}
//----------用于获取实时天气的函数(0)----------
void TandW(){
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation +
                  "&language=en&unit=" +reqUnit;
  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes,0);
  //延迟,需要低于20次/分钟
  delay(5000);
}
void display_1(int results_0_now_temperature_int,String results_0_now_text_str);//声明函数,用于显示温度、天气


//----------获取3天预报(1)----------
void threeday(){
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + "&language=en&unit=" +
                  reqUnit + "&start=0&days=3";

  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes,1);
  delay(5000);
}

void clock_display(time_t prevDisplay){
    server.handleClient();
    dnsServer.processNextRequest();
    if (timeStatus() != timeNotSet)
    {
        if (now() != prevDisplay)
        { //时间改变时更新显示
            prevDisplay = now();
            oledClockDisplay();
        }
    }
}


void setup(){
  Serial.begin(9600);
  Serial.println("");
  initdisplay();
  // 连接WiFi



  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.setCursor(0, 14);
  u8g2.print("Waiting for WiFi");
  u8g2.setCursor(0, 30);
  u8g2.print("connection...");
  u8g2.sendBuffer();
  connectWiFi();
  Udp.begin(localPort);
  setSyncProvider(getNtpTime);
  setSyncInterval(300); //每300秒同步一次时间


}

time_t prevDisplay = 0; //当时钟已经显示

void loop(){
    if (sta>=0 && sta<=250){
      clock_display(prevDisplay);

    }else if(sta == 251){
      TandW();

    }else{
      threeday();

    }

    ++sta;

    if(sta==253){
      sta = 0;
    }
}

// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes,int stat){
  WiFiClient client;

  // 建立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.");
    }
    if (stat == 0){

      // 利用ArduinoJson库解析心知天气响应信息(实时数据)
      parseInfo_now(client,1);
    }else if(stat == 1){
      parseInfo_fut(client,1);
    }
  }
  else {
    Serial.println(" connection failed!");
    if (stat == 0){

      // 利用ArduinoJson库解析心知天气响应信息(实时数据)
      parseInfo_now(clientNULL,0);
    }else if(stat == 1){
      parseInfo_fut(clientNULL,0);
    }
  }

  //断开客户端与服务器连接工作
  client.stop();
}

// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接

  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。
    delay(1000);                               // 如果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库解析心知天气响应信息(实时)
void parseInfo_now(WiFiClient client,int i){

  if(i==1){
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  DynamicJsonDocument doc(capacity);

  deserializeJson(doc, client);

  JsonObject results_0 = doc["results"][0];

  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Sunny"
  const char* results_0_now_code = results_0_now["code"]; // "0"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "32"

  const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00"

  // 通过串口监视器显示以上信息
  String results_0_now_text_str = results_0_now["text"].as<String>();
  int results_0_now_code_int = results_0_now["code"].as<int>();
  int results_0_now_temperature_int = results_0_now["temperature"].as<int>();
  String results_0_last_update_str = results_0["last_update"].as<String>();

  Serial.println(F("======Weahter Now======="));
  Serial.print(F("Weather Now: "));
  Serial.print(results_0_now_text_str);
  Serial.print(F(" "));
  Serial.println(results_0_now_code_int);
  Serial.print(F("Temperature: "));
  Serial.println(results_0_now_temperature_int);
  Serial.print(F("Last Update: "));
  Serial.println(results_0_last_update_str);
  Serial.println(F("========================"));
  display_0(results_0_now_temperature_int,results_0_now_text_str);
  results_0_now_text_str_old = results_0_now_text_str;
  results_0_now_temperature_int_old = results_0_now_temperature_int;
  }
  else{
    display_0(results_0_now_temperature_int_old,results_0_now_text_str_old);
  }

}
//----------输出实时天气----------
void display_0(int results_0_now_temperature_int,String results_0_now_text_str){
  //显示输出
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  u8g2.setCursor(15, 14);
  u8g2.print("泰安实时天气");//地址自行更改
  u8g2.setFont(u8g2_font_logisoso24_tr);
  u8g2.setCursor(45, 44);
  u8g2.print(results_0_now_temperature_int);
  u8g2.setCursor(35, 61);
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.print(results_0_now_text_str);
  u8g2.sendBuffer();
}


// 利用ArduinoJson库解析心知天气响应信息(预测)
void parseInfo_fut(WiFiClient client,int i){
  if(i==1){


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

  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_1_text_day_str = results_0_daily_1["text_day"].as<String>();

  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_str);
  Serial.print(F(" "));
  Serial.println(results_0_daily_0_code_day_int);
  Serial.print(F("Night Weather: "));
  Serial.print(results_0_daily_0_text_night_str);
  Serial.print(F(" "));
  Serial.println(results_0_daily_0_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("=============================="));
  display_1(results_0_daily_1_high_int,results_0_daily_1_low_int,results_0_daily_1_text_day_str);
  results_0_daily_1_high_int_old=results_0_daily_1_high_int;
  results_0_daily_1_low_int_old=results_0_daily_1_low_int;
  results_0_daily_1_text_day_str_old=results_0_daily_1_text_day_str;
}else{
  display_1(results_0_daily_1_high_int_old,results_0_daily_1_low_int_old,results_0_daily_1_text_day_str_old);
}



}
//----------预测明天天气----------
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){
  //显示输出
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  u8g2.setCursor(13, 14);
  u8g2.print("泰安明天天气");//地址自行更改

  u8g2.setFont(u8g2_font_logisoso24_tr);
  u8g2.setCursor(14, 46);
  u8g2.print(results_0_daily_1_low_int);
  u8g2.setCursor(55, 46);
  u8g2.print("~");
  u8g2.setCursor(78, 46);
  u8g2.print(results_0_daily_1_high_int);

  u8g2.setCursor(30, 62);
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.print(results_0_daily_1_text_day_str);
  u8g2.sendBuffer();
}



/*-------- NTP 代码 ----------*/

const int NTP_PACKET_SIZE = 48;     // NTP时间在消息的前48个字节里
byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区

time_t getNtpTime()
{
    IPAddress ntpServerIP; // NTP服务器的地址

    while (Udp.parsePacket() > 0)
        ; // 丢弃以前接收的任何数据包
    Serial.println("Transmit NTP Request");
    // 从池中获取随机服务器
    WiFi.hostByName(ntpServerName, ntpServerIP);
    Serial.print(ntpServerName);
    Serial.print(": ");
    Serial.println(ntpServerIP);
    sendNTPpacket(ntpServerIP);
    uint32_t beginWait = millis();
    while (millis() - beginWait < 1500)
    {
        int size = Udp.parsePacket();
        if (size >= NTP_PACKET_SIZE)
        {
            Serial.println("Receive NTP Response");
            isNTPConnected = true;
            Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
            unsigned long secsSince1900;
            // 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
            secsSince1900 = (unsigned long)packetBuffer[40] << 24;
            secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
            secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
            secsSince1900 |= (unsigned long)packetBuffer[43];
            Serial.println(secsSince1900);
            Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
            return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
        }
    }
    Serial.println("No NTP Response :-("); //无NTP响应
    isNTPConnected = false;
    return 0; //如果未得到时间则返回0
}

// 向给定地址的时间服务器发送NTP请求
void sendNTPpacket(IPAddress &address)
{
    memset(packetBuffer, 0, NTP_PACKET_SIZE);
    packetBuffer[0] = 0b11100011; // LI, Version, Mode
    packetBuffer[1] = 0;          // Stratum, or type of clock
    packetBuffer[2] = 6;          // Polling Interval
    packetBuffer[3] = 0xEC;       // Peer Clock Precision
    // 8 bytes of zero for Root Delay & Root Dispersion
    packetBuffer[12] = 49;
    packetBuffer[13] = 0x4E;
    packetBuffer[14] = 49;
    packetBuffer[15] = 52;
    Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
    Udp.write(packetBuffer, NTP_PACKET_SIZE);
    Udp.endPacket();
}

void oledClockDisplay()
{
    int years, months, days, hours, minutes, seconds, weekdays;
    years = year();
    months = month();
    days = day();
    hours = hour();
    minutes = minute();
    seconds = second();
    weekdays = weekday();
    Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(0, 14);
    if (isNTPConnected)
    {
        if(timeZone>=0)
        {
            u8g2.print("当前时间(UTC+");
            u8g2.print(timeZone);
            u8g2.print(")");
        }
        else
        {
            u8g2.print("当前时间(UTC");
            u8g2.print(timeZone);
            u8g2.print(")");
        }
    }
    else
        u8g2.print("无网络!"); //如果上次对时失败,则会显示无网络
    String currentTime = "";
    if (hours < 10)
        currentTime += 0;
    currentTime += hours;
    currentTime += ":";
    if (minutes < 10)
        currentTime += 0;
    currentTime += minutes;
    currentTime += ":";
    if (seconds < 10)
        currentTime += 0;
    currentTime += seconds;
    String currentDay = "";
    currentDay += years;
    currentDay += "/";
    if (months < 10)
        currentDay += 0;
    currentDay += months;
    currentDay += "/";
    if (days < 10)
        currentDay += 0;
    currentDay += days;

    u8g2.setFont(u8g2_font_logisoso24_tr);
    u8g2.setCursor(0, 44);
    u8g2.print(currentTime);
    u8g2.setCursor(0, 61);
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.print(currentDay);
    u8g2.drawXBM(80, 48, 16, 16, xing);
    u8g2.setCursor(95, 62);
    u8g2.print("期");
    if (weekdays == 1)
        u8g2.print("日");
    else if (weekdays == 2)
        u8g2.print("一");
    else if (weekdays == 3)
        u8g2.print("二");
    else if (weekdays == 4)
        u8g2.print("三");
    else if (weekdays == 5)
        u8g2.print("四");
    else if (weekdays == 6)
        u8g2.print("五");
    else if (weekdays == 7)
        u8g2.drawXBM(111, 49, 16, 16, liu);
    u8g2.sendBuffer();
}
温湿度显示程序:

#include <Arduino.h>
#include <U8g2lib.h>
#include <DHT.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ U8X8_PIN_NONE);
//设置用于连接温湿度传感器的引脚
#define DHTPIN 14  //根据硬件连接确定引脚编号
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h,t;
void setup()
{
  Serial.begin(115200);
  pinMode(DHTPIN,INPUT);
  dht.begin();
  u8g2.begin();
  u8g2.enableUTF8Print();
  dht.begin();
}

void loop()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312b);
  u8g2.setFontDirection(0);

  u8g2.setCursor(0, 14);
  u8g2.print("室内温度:");

  u8g2.setCursor(69, 14);
  u8g2.print(t);

  u8g2.setCursor(114, 14);
  u8g2.print("℃");
  
u8g2.setCursor(0, 29);
  u8g2.print("室内湿度:");
  
  u8g2.setCursor(69, 29);
  u8g2.print(h);  

  u8g2.setCursor(115, 29);
  u8g2.print("%");


if(t>18 and t<27)
{
  u8g2.setCursor(40, 46);
  u8g2.print("温度适宜");
}
else if(t<=18)
{
  u8g2.setCursor(40, 46);
  u8g2.print("寒>>>冷");
}
else if(t>27 and t<29)
{
  u8g2.setCursor(40, 46);
  u8g2.print("室温偏高");
}
else if(t>=29)
{
  u8g2.setCursor(40, 46);
  u8g2.print("炎>>>热");
}
else
{
  u8g2.setCursor(40, 46);
  u8g2.print("请检查接线");
}


if(h<=40)
{
  u8g2.setCursor(35, 62);
  u8g2.print("湿度较低");
}
else if(h>40 and h<70)
{
  u8g2.setCursor(35, 62);
  u8g2.print("湿度适宜");
}
else if(h>=70)
{
  u8g2.setCursor(35, 62);
  u8g2.print("湿度较高");
}




  u8g2.sendBuffer();
  
  delay(1000);


  // h = dht.readHumidity();
  // t = dht.readTemperature();               
  // Serial.print("Temperature:");                     
  // Serial.println(t);                                    
  // delay(1000);
  // Serial.print("Humidity:");                           
  // Serial.print(h);                                    
  // Serial.println("%");
  // delay(1000);
}


发表于 2023-5-30 14:29:26 | 显示全部楼层
高手啊 虽然看不懂
回复 支持 反对

使用道具 举报

发表于 2023-5-30 14:30:57 | 显示全部楼层
楼主这两个程序都是网上找的别人的吧?如果都是你自己写的,那你应该很容易就能自己整合
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-30 14:32:33 | 显示全部楼层
lemontreenm 发表于 2023-5-30 14:30
楼主这两个程序都是网上找的别人的吧?如果都是你自己写的,那你应该很容易就能自己整合 ...

找的凑起来的,要是自己写的肯定能整起来了。
回复 支持 反对

使用道具 举报

发表于 2023-5-30 14:39:01 | 显示全部楼层
楼主,请教一下,你这个室内温度和湿度是从哪里获取的,在你真实的家里有传感器吗,还是从网上获取,那这样不准确的吧。
回复 支持 反对

使用道具 举报

发表于 2023-5-30 14:40:22 | 显示全部楼层
有看到,这个应该加装了温湿度模块,可以采集的,不好意思啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-30 14:51:29 | 显示全部楼层
简单快乐42585 发表于 2023-5-30 14:40
有看到,这个应该加装了温湿度模块,可以采集的,不好意思啊

温湿度是真实的传感器采集,DHT11
回复 支持 反对

使用道具 举报

发表于 2023-5-30 15:26:01 | 显示全部楼层
之前的都能拼凑,这两拼不起来吗?是这个温湿度代码比较特殊吗?
回复 支持 反对

使用道具 举报

发表于 2023-5-30 16:04:55 | 显示全部楼层
研究一下,整合起来应该不难
回复 支持 反对

使用道具 举报

发表于 2023-5-30 16:48:47 | 显示全部楼层
#include <Arduino.h>
#include <DHT.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include <Adafruit_Sensor.h>
#include <DHT_U.h>
#define DHTPIN 14  //根据硬件连接确定引脚编号
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h,t;

#include <ArduinoJson.h>
#include <WiFi.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <DNSServer.h>
#include <WebServer.h>
WiFiUDP Udp;
unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口

//网络校时的相关配置
static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,使用阿里云
int timeZone = 8; //时区设置,采用东8区

//保存断网前的最新数据
int results_0_now_temperature_int_old;
String results_0_now_text_str_old;
int results_0_daily_1_high_int_old;
int results_0_daily_1_low_int_old;
String results_0_daily_1_text_day_str_old;

//函数声明
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
void oledClockDisplay();
void sendCommand(int command, int value);
void initdisplay();
void connectWiFi();
void parseInfo_now(WiFiClient client,int i);
void parseInfo_fut(WiFiClient client,int i);
//
boolean isNTPConnected = false;

const unsigned char xing[] U8X8_PROGMEM = {
    0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
    0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00}; /*星*/
const unsigned char liu[] U8X8_PROGMEM = {
    0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
    0x20, 0x02, 0x20, 0x04, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x04, 0x20, 0x02, 0x20, 0x00, 0x00}; /*六*/

typedef struct
{                  //存储配置结构体
    int tz;        //时间戳
} config_type;
config_type config;

WiFiClient clientNULL;
DNSServer dnsServer;
WebServer server(80);


//----------WIFI连接配置----------
const char* ssid     = "HDS668";       // 连接WiFi名(此处使用XXX为示例)
const char* password = "anby9835";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
//----------天气API配置----------
const char* host = "api.seniverse.com";   // 将要连接的服务器地址
const int httpPort = 80;              // 将要连接的服务器端口

// 心知天气HTTP请求所需信息
String reqUserKey = "SXXXXX";   // 私钥
String reqLocation = "taian";            // 城市自行更改(一定用拼音小写,例如:beijing)
String reqUnit = "c";                      // 摄氏/华氏

//----------设置屏幕----------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
int sta = 0;
//----------初始化OLED----------
void initdisplay()
{
    u8g2.begin();
    u8g2.enableUTF8Print();
}
//----------用于获取实时天气的函数(0)----------
void TandW(){
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation +
                  "&language=en&unit=" +reqUnit;
  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes,0);
  //延迟,需要低于20次/分钟
  delay(5000);
}
void display_1(int results_0_now_temperature_int,String results_0_now_text_str);//声明函数,用于显示温度、天气


//----------获取3天预报(1)----------
void threeday(){
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + "&language=en&unit=" +
                  reqUnit + "&start=0&days=3";

  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes,1);
  delay(5000);
}

void clock_display(time_t prevDisplay){
    server.handleClient();
    dnsServer.processNextRequest();
    if (timeStatus() != timeNotSet)
    {
        if (now() != prevDisplay)
        { //时间改变时更新显示
            prevDisplay = now();
            oledClockDisplay();
        }
    }
}


void setup(){
  Serial.begin(9600);
  Serial.println("");
  initdisplay();
  // 连接WiFi



  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.setCursor(0, 14);
  u8g2.print("Waiting for WiFi");
  u8g2.setCursor(0, 30);
  u8g2.print("connection...");
  u8g2.sendBuffer();
  connectWiFi();
  Udp.begin(localPort);
  setSyncProvider(getNtpTime);
  setSyncInterval(300); //每300秒同步一次时间

  pinMode(DHTPIN,INPUT);//初始化温度传感器引脚及程序BG4RFF2023.05.30
  dht.begin();
}

time_t prevDisplay = 0; //当时钟已经显示

void DispRealTMP()//原来的loop直接改为显示实际温度BG4RFF2023.05.30
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312b);
  u8g2.setFontDirection(0);

  u8g2.setCursor(0, 14);
  u8g2.print("室内温度:");

  u8g2.setCursor(69, 14);
  u8g2.print(t);

  u8g2.setCursor(114, 14);
  u8g2.print("℃");
  
u8g2.setCursor(0, 29);
  u8g2.print("室内湿度:");
  
  u8g2.setCursor(69, 29);
  u8g2.print(h);  

  u8g2.setCursor(115, 29);
  u8g2.print("%");


if(t>18 and t<27)
{
  u8g2.setCursor(40, 46);
  u8g2.print("温度适宜");
}
else if(t<=18)
{
  u8g2.setCursor(40, 46);
  u8g2.print("寒>>>冷");
}
else if(t>27 and t<29)
{
  u8g2.setCursor(40, 46);
  u8g2.print("室温偏高");
}
else if(t>=29)
{
  u8g2.setCursor(40, 46);
  u8g2.print("炎>>>热");
}
else
{
  u8g2.setCursor(40, 46);
  u8g2.print("请检查接线");
}


if(h<=40)
{
  u8g2.setCursor(35, 62);
  u8g2.print("湿度较低");
}
else if(h>40 and h<70)
{
  u8g2.setCursor(35, 62);
  u8g2.print("湿度适宜");
}
else if(h>=70)
{
  u8g2.setCursor(35, 62);
  u8g2.print("湿度较高");
}




  u8g2.sendBuffer();
  
  delay(5000);


  // h = dht.readHumidity();
  // t = dht.readTemperature();               
  // Serial.print("Temperature:");                     
  // Serial.println(t);                                    
  // delay(1000);
  // Serial.print("Humidity:");                           
  // Serial.print(h);                                    
  // Serial.println("%");
  // delay(1000);
}


void loop(){
    if (sta>=0 && sta<=250){
      clock_display(prevDisplay);

    }else if(sta == 251){
      TandW();

    }else{
      threeday();

    }

    ++sta;

    if(sta==253){
      sta = 0;
      DispRealTMP();//放这也可以,不想改太多BG4RFF
    }
}

// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes,int stat){
  WiFiClient client;

  // 建立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.");
    }
    if (stat == 0){

      // 利用ArduinoJson库解析心知天气响应信息(实时数据)
      parseInfo_now(client,1);
    }else if(stat == 1){
      parseInfo_fut(client,1);
    }
  }
  else {
    Serial.println(" connection failed!");
    if (stat == 0){

      // 利用ArduinoJson库解析心知天气响应信息(实时数据)
      parseInfo_now(clientNULL,0);
    }else if(stat == 1){
      parseInfo_fut(clientNULL,0);
    }
  }

  //断开客户端与服务器连接工作
  client.stop();
}

// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接

  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。
    delay(1000);                               // 如果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库解析心知天气响应信息(实时)
void parseInfo_now(WiFiClient client,int i){

  if(i==1){
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  DynamicJsonDocument doc(capacity);

  deserializeJson(doc, client);

  JsonObject results_0 = doc["results"][0];

  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Sunny"
  const char* results_0_now_code = results_0_now["code"]; // "0"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "32"

  const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00"

  // 通过串口监视器显示以上信息
  String results_0_now_text_str = results_0_now["text"].as<String>();
  int results_0_now_code_int = results_0_now["code"].as<int>();
  int results_0_now_temperature_int = results_0_now["temperature"].as<int>();
  String results_0_last_update_str = results_0["last_update"].as<String>();

  Serial.println(F("======Weahter Now======="));
  Serial.print(F("Weather Now: "));
  Serial.print(results_0_now_text_str);
  Serial.print(F(" "));
  Serial.println(results_0_now_code_int);
  Serial.print(F("Temperature: "));
  Serial.println(results_0_now_temperature_int);
  Serial.print(F("Last Update: "));
  Serial.println(results_0_last_update_str);
  Serial.println(F("========================"));
  display_0(results_0_now_temperature_int,results_0_now_text_str);
  results_0_now_text_str_old = results_0_now_text_str;
  results_0_now_temperature_int_old = results_0_now_temperature_int;
  }
  else{
    display_0(results_0_now_temperature_int_old,results_0_now_text_str_old);
  }

}
//----------输出实时天气----------
void display_0(int results_0_now_temperature_int,String results_0_now_text_str){
  //显示输出
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  u8g2.setCursor(15, 14);
  u8g2.print("泰安实时天气");//地址自行更改
  u8g2.setFont(u8g2_font_logisoso24_tr);
  u8g2.setCursor(45, 44);
  u8g2.print(results_0_now_temperature_int);
  u8g2.setCursor(35, 61);
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.print(results_0_now_text_str);
  u8g2.sendBuffer();
}


// 利用ArduinoJson库解析心知天气响应信息(预测)
void parseInfo_fut(WiFiClient client,int i){
  if(i==1){


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

  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_1_text_day_str = results_0_daily_1["text_day"].as<String>();

  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_str);
  Serial.print(F(" "));
  Serial.println(results_0_daily_0_code_day_int);
  Serial.print(F("Night Weather: "));
  Serial.print(results_0_daily_0_text_night_str);
  Serial.print(F(" "));
  Serial.println(results_0_daily_0_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("=============================="));
  display_1(results_0_daily_1_high_int,results_0_daily_1_low_int,results_0_daily_1_text_day_str);
  results_0_daily_1_high_int_old=results_0_daily_1_high_int;
  results_0_daily_1_low_int_old=results_0_daily_1_low_int;
  results_0_daily_1_text_day_str_old=results_0_daily_1_text_day_str;
}else{
  display_1(results_0_daily_1_high_int_old,results_0_daily_1_low_int_old,results_0_daily_1_text_day_str_old);
}



}
//----------预测明天天气----------
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){
  //显示输出
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  u8g2.setCursor(13, 14);
  u8g2.print("泰安明天天气");//地址自行更改

  u8g2.setFont(u8g2_font_logisoso24_tr);
  u8g2.setCursor(14, 46);
  u8g2.print(results_0_daily_1_low_int);
  u8g2.setCursor(55, 46);
  u8g2.print("~");
  u8g2.setCursor(78, 46);
  u8g2.print(results_0_daily_1_high_int);

  u8g2.setCursor(30, 62);
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.print(results_0_daily_1_text_day_str);
  u8g2.sendBuffer();
}



/*-------- NTP 代码 ----------*/

const int NTP_PACKET_SIZE = 48;     // NTP时间在消息的前48个字节里
byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区

time_t getNtpTime()
{
    IPAddress ntpServerIP; // NTP服务器的地址

    while (Udp.parsePacket() > 0)
        ; // 丢弃以前接收的任何数据包
    Serial.println("Transmit NTP Request");
    // 从池中获取随机服务器
    WiFi.hostByName(ntpServerName, ntpServerIP);
    Serial.print(ntpServerName);
    Serial.print(": ");
    Serial.println(ntpServerIP);
    sendNTPpacket(ntpServerIP);
    uint32_t beginWait = millis();
    while (millis() - beginWait < 1500)
    {
        int size = Udp.parsePacket();
        if (size >= NTP_PACKET_SIZE)
        {
            Serial.println("Receive NTP Response");
            isNTPConnected = true;
            Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
            unsigned long secsSince1900;
            // 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
            secsSince1900 = (unsigned long)packetBuffer[40] << 24;
            secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
            secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
            secsSince1900 |= (unsigned long)packetBuffer[43];
            Serial.println(secsSince1900);
            Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
            return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
        }
    }
    Serial.println("No NTP Response :-("); //无NTP响应
    isNTPConnected = false;
    return 0; //如果未得到时间则返回0
}

// 向给定地址的时间服务器发送NTP请求
void sendNTPpacket(IPAddress &address)
{
    memset(packetBuffer, 0, NTP_PACKET_SIZE);
    packetBuffer[0] = 0b11100011; // LI, Version, Mode
    packetBuffer[1] = 0;          // Stratum, or type of clock
    packetBuffer[2] = 6;          // Polling Interval
    packetBuffer[3] = 0xEC;       // Peer Clock Precision
    // 8 bytes of zero for Root Delay & Root Dispersion
    packetBuffer[12] = 49;
    packetBuffer[13] = 0x4E;
    packetBuffer[14] = 49;
    packetBuffer[15] = 52;
    Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
    Udp.write(packetBuffer, NTP_PACKET_SIZE);
    Udp.endPacket();
}

void oledClockDisplay()
{
    int years, months, days, hours, minutes, seconds, weekdays;
    years = year();
    months = month();
    days = day();
    hours = hour();
    minutes = minute();
    seconds = second();
    weekdays = weekday();
    Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(0, 14);
    if (isNTPConnected)
    {
        if(timeZone>=0)
        {
            u8g2.print("当前时间(UTC+");
            u8g2.print(timeZone);
            u8g2.print(")");
        }
        else
        {
            u8g2.print("当前时间(UTC");
            u8g2.print(timeZone);
            u8g2.print(")");
        }
    }
    else
        u8g2.print("无网络!"); //如果上次对时失败,则会显示无网络
    String currentTime = "";
    if (hours < 10)
        currentTime += 0;
    currentTime += hours;
    currentTime += ":";
    if (minutes < 10)
        currentTime += 0;
    currentTime += minutes;
    currentTime += ":";
    if (seconds < 10)
        currentTime += 0;
    currentTime += seconds;
    String currentDay = "";
    currentDay += years;
    currentDay += "/";
    if (months < 10)
        currentDay += 0;
    currentDay += months;
    currentDay += "/";
    if (days < 10)
        currentDay += 0;
    currentDay += days;

    u8g2.setFont(u8g2_font_logisoso24_tr);
    u8g2.setCursor(0, 44);
    u8g2.print(currentTime);
    u8g2.setCursor(0, 61);
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.print(currentDay);
    u8g2.drawXBM(80, 48, 16, 16, xing);
    u8g2.setCursor(95, 62);
    u8g2.print("期");
    if (weekdays == 1)
        u8g2.print("日");
    else if (weekdays == 2)
        u8g2.print("一");
    else if (weekdays == 3)
        u8g2.print("二");
    else if (weekdays == 4)
        u8g2.print("三");
    else if (weekdays == 5)
        u8g2.print("四");
    else if (weekdays == 6)
        u8g2.print("五");
    else if (weekdays == 7)
        u8g2.drawXBM(111, 49, 16, 16, liu);
    u8g2.sendBuffer();
}
//没有环境,没编译,试试吧
回复 支持 反对

使用道具 举报

发表于 2023-5-30 17:21:01 | 显示全部楼层
环境整起,验证/编译通过了的,硬件就没有了

打赏

参与人数 1家元 +80 收起 理由
martinku + 80 熱心助人

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2023-5-30 21:20:35 | 显示全部楼层
martinku 发表于 2023-5-30 14:32
找的凑起来的,要是自己写的肯定能整起来了。

能凑起来一个就能把这两个凑一起,虽然对于新手来说过程中难免会有一些问题出现但是也能锻炼一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-31 08:08:32 | 显示全部楼层
bg4rff 发表于 2023-5-30 16:48
#include
#include
#ifdef U8X8_HAVE_HW_SPI

好的,我试下,感谢您的指教。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-31 08:43:11 | 显示全部楼层
martinku 发表于 2023-5-31 08:08
好的,我试下,感谢您的指教。

已编译上传测试正常,感谢bg4rff大侠的精心整理,高手一出手,效果立竿见影了,在下虚心受教。

打赏

参与人数 1家元 +70 收起 理由
bg4rff + 70 歡迎探討

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2023-5-31 09:58:52 | 显示全部楼层
martinku 发表于 2023-5-31 08:43
已编译上传测试正常,感谢bg4rff大侠的精心整理,高手一出手,效果立竿见影了,在下虚心受教。 ...

举手之劳而已,互相学习
回复 支持 反对

使用道具 举报

发表于 2023-5-31 10:56:13 来自手机浏览器 | 显示全部楼层
好东西,点赞收藏,下步来慢慢研究!
回复 支持 反对

使用道具 举报

发表于 2023-5-31 12:20:25 | 显示全部楼层
ESP32可以用micropython玩,简单易入手。
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-27 09:32 , Processed in 0.218400 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表