【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 
  实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块 
  项目实验之二十四:带 LVGL 的 ESP32 CYD:显示时间和日期的数字时钟 
 
实验开源代码 
 
 
			
			
			/*
   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
   实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块
   项目实验之二十四:带 LVGL 的 ESP32 CYD:显示时间和日期的数字时钟
 */
 
 #include <lvgl.h> // 引入LVGL图形库
 #include <TFT_eSPI.h> // 引入TFT_eSPI库,用于驱动TFT显示屏
 #include <WiFi.h> // 引入WiFi库,用于WiFi连接
 #include <HTTPClient.h> // 引入HTTPClient库,用于发起HTTP请求
 #include <ArduinoJson.h> // 引入ArduinoJson库,用于处理JSON数据
 
 // 替换为您的网络凭据
 const char* ssid = "zhz3";// WiFi名称
 const char* password = "z156721";// WiFi密码
 
 // 指定您想要获取时间的时区:https://worldtimeapi.org/api/timezone 
 // 葡萄牙时区示例:"Europe/Lisbon"
 const char* timezone = "Europe/Lisbon"; // 设置时区
 
 // 存储日期和时间
 String current_date; // 当前日期
 String current_time; // 当前时间
 
 // 存储小时、分钟、秒
 static int32_t hour; // 小时
 static int32_t minute; // 分钟
 static int32_t second; // 秒
 bool sync_time_date = false; // 是否同步日期和时间
 
 #define SCREEN_WIDTH 240 // 屏幕宽度
 #define SCREEN_HEIGHT 320 // 屏幕高度
 
 #define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8)) // 绘图缓冲区大小
 uint32_t draw_buf[DRAW_BUF_SIZE / 4]; // 绘图缓冲区
 
 // 如果启用了日志记录,它将告知用户库中发生了什么
 void log_print(lv_log_level_t level, const char * buf) {
   LV_UNUSED(level); // 未使用的参数
   Serial.println(buf); // 打印日志
   Serial.flush(); // 清空串口缓冲区
 }
 
 String format_time(int time) { // 格式化时间为两位数
   return (time < 10) ? "0" + String(time) : String(time);
 }
 
 static lv_obj_t * text_label_time; // 时间标签
 static lv_obj_t * text_label_date; // 日期标签
 
 static void timer_cb(lv_timer_t * timer){ // 定时器回调函数
   LV_UNUSED(timer);
   second++;
   if(second > 59) { // 秒数超过59则进位
     second = 0;
     minute++;
     if(minute > 59) { // 分钟超过59则进位
       minute = 0;
       hour++;
       sync_time_date = true; // 设置同步日期和时间标志
       Serial.println(sync_time_date);
       Serial.println("\n\n\n\n\n\n\n\n");
       if(hour > 23) { // 小时超过23则归零
         hour = 0;
       }
     }
   }
 
   String hour_time_f = format_time(hour); // 格式化小时
   String minute_time_f = format_time(minute); // 格式化分钟
   String second_time_f = format_time(second); // 格式化秒
 
   String final_time_str = String(hour_time_f) + ":" + String(minute_time_f) + ":"  + String(second_time_f); // 组合成最终时间字符串
   //Serial.println(final_time_str);
   lv_label_set_text(text_label_time, final_time_str.c_str()); // 设置时间标签文本
   lv_label_set_text(text_label_date, current_date.c_str()); // 设置日期标签文本
 }
 
 void lv_create_main_gui(void) { // 创建主GUI界面
   // 从WorldTimeAPI获取时间和日期
   while(hour==0 && minute==0 && second==0) {
     get_date_and_time();
   }
   Serial.println("Current Time: " + current_time); // 打印当前时间
   Serial.println("Current Date: " + current_date); // 打印当前日期
 
   lv_timer_t * timer = lv_timer_create(timer_cb, 1000, NULL); // 创建定时器
   lv_timer_ready(timer); // 定时器立即执行
 
   // 创建居中对齐的时间文本标签
   text_label_time = lv_label_create(lv_screen_active()); // 创建标签
   lv_label_set_text(text_label_time, ""); // 设置标签文本为空
   lv_obj_align(text_label_time, LV_ALIGN_CENTER, 0, -30); // 设置标签位置
   // 设置字体类型和大小
   static lv_style_t style_text_label;
   lv_style_init(&style_text_label); // 初始化样式
   lv_style_set_text_font(&style_text_label, &lv_font_montserrat_48); // 设置字体为48号
   lv_obj_add_style(text_label_time, &style_text_label, 0); // 应用样式
 
   // 创建居中对齐的日期文本标签
   text_label_date = lv_label_create(lv_screen_active()); // 创建标签
   lv_label_set_text(text_label_date, current_date.c_str()); // 设置标签文本
   lv_obj_align(text_label_date, LV_ALIGN_CENTER, 0, 40); // 设置标签位置
   // 设置字体类型和大小
   static lv_style_t style_text_label2;
   lv_style_init(&style_text_label2); // 初始化样式
   lv_style_set_text_font(&style_text_label2, &lv_font_montserrat_30); // 设置字体为30号
   lv_obj_add_style(text_label_date, &style_text_label2, 0); // 应用样式
   lv_obj_set_style_text_color((lv_obj_t*) text_label_date, lv_palette_main(LV_PALETTE_GREY), 0); // 设置文本颜色为灰色
 }
 
 void get_date_and_time() { // 获取日期和时间
   if (WiFi.status() == WL_CONNECTED) { // 如果WiFi已连接
     HTTPClient http; // 创建HTTPClient对象
 
     // 构造API端点
     String url = String("http://worldtimeapi.org/api/timezone/") + timezone;
     http.begin(url); // 初始化HTTP请求
     int httpCode = http.GET(); // 发起GET请求
 
     if (httpCode > 0) { // 如果请求成功
       // 检查响应
       if (httpCode == HTTP_CODE_OK) { // 如果响应码为OK
         String payload = http.getString(); // 获取响应内容
         //Serial.println("Time information:");
         //Serial.println(payload);
         // 解析JSON以提取时间
         JsonDocument doc; // 创建JSON文档
         DeserializationError error = deserializeJson(doc, payload); // 反序列化JSON
         if (!error) { // 如果没有错误
           const char* datetime = doc["datetime"]; // 获取datetime字段
           // 将datetime分割为日期和时间
           String datetime_str = String(datetime);
           int splitIndex = datetime_str.indexOf('T');
           current_date = datetime_str.substring(0, splitIndex); // 提取日期部分
           current_time = datetime_str.substring(splitIndex + 1, splitIndex + 9); // 提取时间部分
           hour = current_time.substring(0, 2).toInt(); // 提取小时
           minute = current_time.substring(3, 5).toInt(); // 提取分钟
           second = current_time.substring(6, 8).toInt(); // 提取秒
         } else { // 如果反序列化失败
           Serial.print("deserializeJson() failed: ");
           Serial.println(error.c_str()); // 打印错误信息
         }
       }
     } else { // 如果请求失败
       Serial.printf("GET request failed, error: %s\n", http.errorToString(httpCode).c_str()); // 打印错误信息
       sync_time_date = true; // 设置同步日期和时间标志
     }
     http.end(); // 关闭连接
   } else { // 如果WiFi未连接
     Serial.println("Not connected to Wi-Fi"); // 打印未连接信息
   }
 }
 
 void setup() {
   String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch(); // LVGL库版本
   Serial.begin(115200); // 初始化串口通信
   Serial.println(LVGL_Arduino); // 打印LVGL库版本
 
   // 连接到WiFi
   WiFi.begin(ssid, password); // 初始化WiFi连接
   Serial.print("Connecting"); // 打印连接信息
   while (WiFi.status() != WL_CONNECTED) { // 等待WiFi连接
     delay(500); // 延时
     Serial.print("."); // 打印点以显示进度
   }
   Serial.print("\nConnected to Wi-Fi network with IP Address: "); // 打印连接成功的信息
   Serial.println(WiFi.localIP()); // 打印IP地址
 
   // 开始LVGL图形库的初始化
 lv_init();
 // 注册打印函数,用于调试
 lv_log_register_print_cb(log_print);
 
 // 创建一个显示对象
 lv_display_t * disp;
 // 使用TFT_eSPI库初始化TFT显示屏
 disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf)); // 创建显示对象,设置屏幕宽高和绘图缓冲区
 lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270); // 设置屏幕旋转方向为270度
 
 // 函数用于绘制GUI
 lv_create_main_gui();
 }
 
 void loop() {
   // 从WorldTimeAPI获取日期和时间
   if(sync_time_date) { // 如果需要同步日期和时间
     sync_time_date = false; // 重置同步标志
     get_date_and_time(); // 获取日期和时间
     while(hour==0 && minute==0 && second==0) { // 如果获取的时间无效(即小时、分钟、秒都为0)
       get_date_and_time(); // 再次尝试获取日期和时间
     }
   }
   lv_task_handler();  // 让LVGL执行GUI任务
   lv_tick_inc(5);     // 告诉LVGL已经过去了5毫秒
   delay(5);           // 等待5毫秒
 } 复制代码