合宙ESP32C3使用TFT_eSPI库操作ST7735s屏幕彩色时钟-Arduino中文社区 - Powered by Discuz! Archiver

topdog 发表于 2022-5-21 13:35

合宙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名称和密码修改一下,就可以烧录了!








miao_miao 发表于 2022-5-30 10:10

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



注释掉后时间全都重叠在一起了。发现TFT_eSPI官方示例下的Sprite/Orrery可以实现时间刷新而不闪烁,希望楼主有时间可以写一个利用sprite显示时钟的帖子。

myself1820 发表于 2022-5-21 23:00

谢谢楼主,我的买回来就吃灰了

topdog 发表于 2022-5-21 23:08

myself1820 发表于 2022-5-21 23:00
谢谢楼主,我的买回来就吃灰了

玩一下吧。

miao_miao 发表于 2022-5-29 13:24

跟楼主一样的硬件,烧录楼主提供的程序,每秒刷新都会闪一下。请问楼主,这是正常的吗?

topdog 发表于 2022-5-29 14:25

正常的。

topdog 发表于 2022-5-29 14:28

miao_miao 发表于 2022-5-29 13:24
跟楼主一样的硬件,烧录楼主提供的程序,每秒刷新都会闪一下。请问楼主,这是正常的吗? ...

https://www.arduino.cn/thread-108525-1-1.html
里面的气象站做一下。

miao_miao 发表于 2022-5-29 17:11

topdog 发表于 2022-5-29 14:25
正常的。

怎样才能让它不闪?

miao_miao 发表于 2022-5-29 17:16

topdog 发表于 2022-5-29 14:28
https://www.arduino.cn/thread-108525-1-1.html
里面的气象站做一下。

好的,才发现评论还有下一页。

topdog 发表于 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


页: [1] 2 3
查看完整版本: 合宙ESP32C3使用TFT_eSPI库操作ST7735s屏幕彩色时钟