合宙ESP32C3使用TFT_eSPI库操作ST7735s屏幕彩色时钟
本帖最后由 topdog 于 2022-6-6 10:12 编辑合宙ESP32C3使用TFT_eSPI库操作ST7735s屏幕彩色时钟,效果图:
程序如下:
#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 longgmtOffset_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 :)
}
使用子画面(Sprite)改进后的效果,消除了画面的闪烁。
#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 longgmtOffset_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();
}
下载好附件,导入IDE,把WiFi名称和密码修改一下,就可以烧录了!
topdog 发表于 2022-5-29 23:02
tft.fillScreen(TFT_BLACK);
如果把上述语句注释掉,就不会闪烁了,你会看到打印的字体出现在屏幕上。
注释掉后时间全都重叠在一起了。发现TFT_eSPI官方示例下的Sprite/Orrery可以实现时间刷新而不闪烁,希望楼主有时间可以写一个利用sprite显示时钟的帖子。 谢谢楼主,我的买回来就吃灰了 myself1820 发表于 2022-5-21 23:00
谢谢楼主,我的买回来就吃灰了
玩一下吧。
跟楼主一样的硬件,烧录楼主提供的程序,每秒刷新都会闪一下。请问楼主,这是正常的吗? 正常的。 miao_miao 发表于 2022-5-29 13:24
跟楼主一样的硬件,烧录楼主提供的程序,每秒刷新都会闪一下。请问楼主,这是正常的吗? ...
https://www.arduino.cn/thread-108525-1-1.html
里面的气象站做一下。 topdog 发表于 2022-5-29 14:25
正常的。
怎样才能让它不闪? topdog 发表于 2022-5-29 14:28
https://www.arduino.cn/thread-108525-1-1.html
里面的气象站做一下。
好的,才发现评论还有下一页。 本帖最后由 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