Arduino爱好者

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3136|回复: 25

合宙ESP32C3使用TFT_eSPI库操作ST7735s屏幕彩色时钟

[复制链接]
发表于 2022-5-21 13:35 | 显示全部楼层 |阅读模式
本帖最后由 topdog 于 2022-6-6 10:12 编辑

合宙ESP32C3使用TFT_eSPI库操作ST7735s屏幕彩色时钟,效果图:

Ck.gif

程序如下:

[pre]#include <WiFi.h>
#include "FontYahei24.h"
#include "time.h"
#include "sntp.h"

#include <SPI.h>
#include <TFT_eSPI.h>

const char* ssid    = "WiFi名称";
const char* password = "WiFi密码";


const char* ntpServer1 = "cn.ntp.org.cn";   //中国
const char* ntpServer2 = "edu.ntp.org.cn";    //中国教育网
const long  gmtOffset_sec = 8 * 3600;   //参数就是用来修正时区的,比如对于我们东八区(UTC/GMT+08:00)来说该参数就需要填写 8 * 3600
const int   daylightOffset_sec = 0;     //使用夏令时 daylightOffset_sec 就填写3600,否则就填写0;

const char* time_zone = "CST-8";  // 亚洲/上海时区规则,包括日光调整规则(可选)

TFT_eSPI tft = TFT_eSPI();

void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("No time available (yet)");
    return;
  }
  
  tft.fillScreen(TFT_BLACK);
  tft.loadFont(FONTYAHEI24);
  tft.setCursor(0, 0);
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.print("上海时间日期: ");
  tft.println();
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.print(&timeinfo, "%H");
  tft.print("时");
  tft.print(&timeinfo, "%M");
  tft.print("分");
  tft.print(&timeinfo, "%S");
  tft.print("秒");
  tft.println();
  tft.unloadFont();
  tft.setTextColor(TFT_CYAN, TFT_BLACK);
  tft.setTextFont(4);
  tft.print(&timeinfo, "%F");
  tft.unloadFont();
  delay(1000);
}


// 回调函数(通过NTP调整时间时调用get)
void timeavailable(struct timeval *t)
{
  tft.println("Got time adjustment from NTP!");
  printLocalTime();
}

void setup()
{
  Serial.begin(115200);

  // 设置通知回调功能
  sntp_set_time_sync_notification_cb( timeavailable );

  /**
    NTP服务器地址可以通过DHCP获取,
    注意:该调用应该在esp32通过DHCP获取IP地址之前进行,
    否则SNTP选项42将默认被拒绝。
    注意:configTime()函数在DHCP-client运行后调用
    将覆盖获取的NTP服务器地址
  */
  sntp_servermode_dhcp(1);    // (optional)

  /**
     这将设置已配置的ntp服务器和常量 TimeZone/daylightOffset
     如果你的时区不需要一年两次调整日光偏移,应该是可以的,
     在这种情况下,时间调整将不会自动处理。
  */
  //configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);

  /**
     使用daylightOffset处理时区的更方便的方法
     将是使用包括日光调整网规则的TimeZone定义指定一个环境变量。
     可以从中获得专区的规则列表 https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
  */
  configTzTime(time_zone, ntpServer1, ntpServer2);
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextFont(2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setCursor(0, 0);
  //connect to WiFi
  tft.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    tft.print("。");
  }
  tft.println(" CONNECTED");  
}

void loop()
{  
  printLocalTime();     // it will take some time to sync time :)
}[/pre]


使用子画面(Sprite)改进后的效果,消除了画面的闪烁。

[pre]#include <WiFi.h>
#include <WiFiMulti.h>
#include "FontYahei24.h"
#include "time.h"
#include "sntp.h"
#include <SPI.h>
#include <TFT_eSPI.h>

const char* ssid    = "WiFi名称";
const char* password = "WiFi密码";

const char* ntpServer1 = "cn.ntp.org.cn";   //中国
const char* ntpServer2 = "edu.ntp.org.cn";    //中国教育网
const long  gmtOffset_sec = 8 * 3600;   //参数就是用来修正时区的,比如对于我们东八区(UTC/GMT+08:00)来说该参数就需要填写 8 * 3600
const int   daylightOffset_sec = 0;     //使用夏令时 daylightOffset_sec 就填写3600,否则就填写0;

const char* time_zone = "CST-8";  // 亚洲/上海时区规则,包括日光调整规则(可选)


TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft); //创建子画面实体
WiFiMulti WiFiMulti;

void printLocalTime()
{      
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    tft.println("No time available (yet)");
    return;
    }

// 设置子画面的颜色深度为8(或16)位
  spr.setColorDepth(8);
  // 创建子画面清晰的背景大小设置色彩为黑色
  spr.createSprite(160, 80);
  //spr.fillSprite(TFT_BLACK); // 这是可选的,因为我们稍后会填充Sprite
  spr.setTextWrap(true);  //这样我们就可以打印Sprite过去的结束   
  
  
  spr.loadFont(FONTYAHEI24);
  spr.setTextDatum(MR_DATUM); //顶部中心基准对齐,十种对齐效果之一
  spr.setCursor(0, 0);
  spr.setTextColor(TFT_RED, TFT_BLACK);
  spr.print("上海时间日期: ");
  spr.println();
  spr.setTextColor(TFT_GREEN, TFT_BLACK);
  spr.print(&timeinfo, "%H");
  spr.print("时");
  spr.print(&timeinfo, "%M");
  spr.print("分");
  spr.print(&timeinfo, "%S");
  spr.print("秒");
  spr.println();
  spr.unloadFont();
  spr.setTextColor(TFT_CYAN, TFT_BLACK);
  spr.setTextFont(4);
  spr.print(&timeinfo, "%F");
  spr.pushSprite(0,0);  //将子画面推到 x, y 处的TFT
  spr.deleteSprite();   //删除子画面

  delay(1000);
  
}

void timeavailable(struct timeval *t)
{
  tft.println("Got time adjustment from NTP!");
  printLocalTime();
}


void setup()
{
  Serial.begin(115200);  

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(ssid, password);  
  
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);


  tft.setTextFont(2);
  tft.setTextColor(TFT_WHITE);
  
  tft.setCursor(0, 0);
  
  tft.printf("Connecting to %s ", ssid);  
  while ((WiFiMulti.run() != WL_CONNECTED)) {
    delay(500);
    tft.print(".");
  }
  tft.println(" CONNECTED");
  
sntp_set_time_sync_notification_cb( timeavailable );
sntp_servermode_dhcp(1);   
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);  
}

void loop()
{  
printLocalTime();
}[/pre]



下载好附件,导入IDE,把WiFi名称和密码修改一下,就可以烧录了!


esp32c3_tft_espi_ChineseFont_Time_st7735s.rar (52.49 KB, 下载次数: 103)





发表于 2022-5-30 10:10 | 显示全部楼层
topdog 发表于 2022-5-29 23:02
tft.fillScreen(TFT_BLACK);
如果把上述语句注释掉,就不会闪烁了,你会看到打印的字体出现在屏幕上。

注释掉后时间全都重叠在一起了。发现TFT_eSPI官方示例下的Sprite/Orrery可以实现时间刷新而不闪烁,希望楼主有时间可以写一个利用sprite显示时钟的帖子。
发表于 2022-5-21 23:00 | 显示全部楼层
谢谢楼主,我的买回来就吃灰了
 楼主| 发表于 2022-5-21 23:08 | 显示全部楼层
myself1820 发表于 2022-5-21 23:00
谢谢楼主,我的买回来就吃灰了

玩一下吧。
发表于 2022-5-29 13:24 来自手机 | 显示全部楼层
跟楼主一样的硬件,烧录楼主提供的程序,每秒刷新都会闪一下。请问楼主,这是正常的吗?
 楼主| 发表于 2022-5-29 14:28 | 显示全部楼层
miao_miao 发表于 2022-5-29 13:24
跟楼主一样的硬件,烧录楼主提供的程序,每秒刷新都会闪一下。请问楼主,这是正常的吗? ...

https://www.arduino.cn/thread-108525-1-1.html
里面的气象站做一下。
发表于 2022-5-29 17:11 来自手机 | 显示全部楼层
topdog 发表于 2022-5-29 14:25
正常的。

怎样才能让它不闪?
发表于 2022-5-29 17:16 来自手机 | 显示全部楼层
topdog 发表于 2022-5-29 14:28
https://www.arduino.cn/thread-108525-1-1.html
里面的气象站做一下。

好的,才发现评论还有下一页。
 楼主| 发表于 2022-5-29 23:02 | 显示全部楼层
本帖最后由 topdog 于 2022-5-29 23:13 编辑
miao_miao 发表于 2022-5-29 17:11
怎样才能让它不闪?

tft.fillScreen(TFT_BLACK);
如果把上述语句注释掉,就不会闪烁了,你会看到打印的字体出现在屏幕上。

闪烁主要是你的视觉暂存引起的
你试试在时间和日期位置遮盖一下。

参考一下这篇:
https://www.arduino.cn/thread-107064-1-1.html


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

本版积分规则

小黑屋|Archiver|手机版|Arduino爱好者

GMT+8, 2022-12-6 11:30 , Processed in 0.073249 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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