ESP32/ESP8266基于Arduino框架下驱动1.8“tft_oled屏幕仿数码管时钟

ESP32/ESP8266基于Arduino框架下驱动1.8"tft_oled屏幕仿数码管时钟


  • 📍相关篇《ESP32基于Arduino框架下U8g2驱动I2C OLED 时间显示》
  • 📺效果演示:
    在这里插入图片描述
  • 🌿屏幕显示部分,采用使用TFT_eSPI库驱动,利用该库自带的特有字体显示。
  • 🌿屏幕采用128*160 1.8"tft_Oled屏幕。
  • 🌿本工程仅在esp32上做了验证,esp8266上显示应该也没有问题。
✨主要是熟悉对屏幕驱动显示库的使用,结合利用网络获取时间作为显示内容。

📓所需库

  • 🔖所依赖库都可以在Arduino IDE管理库中搜索并直接安装到。
  • 🌿TFT_eSPI(屏幕驱动显示)
  • 🌿NTPClient (获取网络时间)

⛳注意事项

  • 🌿安装好库后,需要自行手动修改TFT_eSPI库目录下的User_Setup.h配置。根据个人使用的屏幕进行修改。
    • 🔖如果是esp32:(引脚可以根据个人使用情况设定)
// For ESP32 Dev board (only tested with GC9A01 display)
// The hardware SPI can be mapped to any pins

#define TFT_MOSI 23 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 18
#define TFT_CS   5  // Chip select control pin
#define TFT_DC   19  // Data Command control pin
#define TFT_RST  21  // Reset pin (could connect to Arduino RESET pin)
#define TFT_BL   22  // LED back-light

– 🔖如果是esp8266

// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS   PIN_D8  // Chip select control pin D8
#define TFT_DC   PIN_D3  // Data Command control pin
#define TFT_RST  PIN_D4  // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST  -1    // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V

//#define TFT_BL PIN_D1  // LED back-light (only for ST7789 with backlight control pin)
//#define TOUCH_CS PIN_D2     // Chip select pin (T_CS) of touch screen

SDA ---- D7
SCL ---- D5
CS  ---- D8
DC  ---- D3
BL ---- 3.3V
RST ---- D4或3.3v

📝程序代码

/*
 An example digital clock using a TFT LCD screen to show the time.
 Demonstrates use of the font printing routines. (Time updates but date does not.)
 
 For a more accurate clock, it would be better to use the RTClib library.
 But this is just a demo. 
 
 This examples uses the hardware SPI only. Non-hardware SPI
 is just too slow (~8 times slower!)
 
 Based on clock sketch by Gilchrist 6/2/2014 1.0
 Updated by Bodmer
A few colour codes:
 
code	color
0x0000	Black
0xFFFF	White
0xBDF7	Light Gray
0x7BEF	Dark Gray
0xF800	Red
0xFFE0	Yellow
0xFBE0	Orange
0x79E0	Brown
0x7E0	Green
0x7FF	Cyan
0x1F	Blue
0xF81F	Pink

 */
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
//  #include <WiFiClient.h>//3.0.2新增
//  #include <ESP8266HTTPClient.h>
#endif
// 获取网络时间相关库
#include <NTPClient.h>
#include <WiFiUdp.h>//esp32/esp8266核心固件自带
#include <SPI.h>
//屏幕显示
#include <TFT_eSPI.h>  // Graphics and font library for ST7735 driver chip
#include <SPI.h>

#define SERIAL_DEBUG  //是否开启串口调试信息输出

TFT_eSPI tft = TFT_eSPI();               // Invoke library, pins defined in User_Setup.h
TFT_eSprite sprite = TFT_eSprite(&tft);  // 创建双缓冲区

// 定义一个字符串数组
const char weekdays_en[][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

// 网络时间相关定义
const char *ssid = "#######";  // 填写WiFi账号
const char *password = "********";   // WiFi密码
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp.aliyun.com");  // NTP服务器地址

uint32_t targetTime = 0;  // for next 1 second timeout
//定义时间用变量
int16_t currentYear = 0;
int16_t currentWeekDay = 0;
int16_t currentMonth = 0;
int16_t currentMonthDay = 0;
int16_t currentHour = 0;
int16_t currentMin = 0;
int16_t currentSec = 0;

byte omm = 99;
bool initial = 1;
byte xcolon = 0;
unsigned int colour = 0;
uint8_t ss,mm;
void updateTime();

void setup(void) {

#ifdef SERIAL_DEBUG
  Serial.begin(115200);  // 初始化串口通信,波特率为115200
#endif
  // ===网络时间初始化设定===
  // 连接WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {  // 等待WiFi连接成功
    delay(500);
#ifdef SERIAL_DEBUG
    Serial.print(".");
#endif
  }
  timeClient.begin();               // 初始化NTPClient
  timeClient.setTimeOffset(28800);  // 时区设置,时间偏移为28800秒(8小时)
  // ===TFT初始化设定===
  tft.begin();                    // 初始化显示寄存器
  tft.setRotation(1);             // 设置显示屏旋转角度(0表示不旋转,根据需要调整)0, 1, 2, 3 分别代表 0°、90°、180°、270°,可设置4为镜像。
  sprite.setColorDepth(16);       // 设置颜色深度(根据你的需求)
  sprite.setSwapBytes(true);      // 设置字节顺序,将RGB颜色顺序转换为BGR以正确显示颜色。
  sprite.createSprite(160, 128);  // 创建一个128x160像素的绘图窗口
  sprite.fillScreen(TFT_BLACK);

  sprite.setTextColor(TFT_YELLOW, TFT_BLACK);  // Note: the new fonts do not draw the background colour
  updateTime();//更新一次
  targetTime = millis() + 1000;
}

void loop() {
  if (targetTime < millis()) {
    targetTime = millis() + 1000;
    updateTime();
    byte Sec_Point = 82;
    if (ss != currentSec) {
      ss = currentSec;  // Advance second
      sprite.setTextColor(TFT_GREEN, TFT_BLACK);
      //    sprite.setCursor (8, 110);
      //sprite.println(timeClient.getFormattedTime());
      char buffer2[11];
      //  sprite.printf("%04d-%02d-%02d", currentYear, currentMonth, currentMonthDay);//显示日期
      sprintf_P(buffer2, "%04d-%02d-%02d", currentYear, currentMonth, currentMonthDay);
      sprite.drawString(buffer2, 16, 105, 4);     //显示日期
      sprite.setTextColor(TFT_BLUE, TFT_BLACK);  //橙色
      //sprite.setTextColor(0xF81F, TFT_BLACK); // Pink
      //   sprite.drawCentreString("",120,48,2); // (居中)Next size up font 2
      sprite.drawString(weekdays_en[currentWeekDay], 8, 64, 4);  //绘制字符串, 打印 星期几
      sprite.pushSprite(0, 0);
      //  sprite.setTextColor(0xFBE0);     // Orange
      sprite.setTextColor(TFT_GREEN, TFT_BLACK);     
      if (currentSec < 10) {//显示秒
        Sec_Point +=sprite.drawChar('0', Sec_Point, 50, 7);
      }
      sprite.drawNumber(currentSec, Sec_Point, 50, 7);  //显示秒
      sprite.pushSprite(0, 0);
    }

    // Update digital time
    byte xpos = 6;
    byte ypos = 0;
    if (omm != currentMin) {  // Only redraw every minute to minimise flicker
      sprite.setTextColor(0x39C4, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!
      // Font 7 is to show a pseudo 7 segment display.
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .
      sprite.drawString("88:88", xpos, ypos, 7);  // Overwrite the text to clear it
      sprite.setTextColor(0xFBE0);                // Orange
      omm = currentMin;

      if (currentHour < 10) xpos += sprite.drawChar('0', xpos, ypos, 7);
      xpos += sprite.drawNumber(currentHour, xpos, ypos, 7);  //显示时
      sprite.pushSprite(0, 0);
      xcolon = xpos;
      xpos += sprite.drawChar(':', xpos, ypos, 7);
      if (currentMin < 10) xpos += sprite.drawChar('0', xpos, ypos, 7);
      sprite.drawNumber(currentMin, xpos, ypos, 7);  //显示分
      sprite.pushSprite(0, 0);
    }

    if (ss % 2) {  // Flash the colon
      sprite.setTextColor(0x39C4, TFT_BLACK);  //字体颜色
      xpos += sprite.drawChar(':', xcolon, ypos, 7);
      sprite.pushSprite(0, 0);

    } else {
      sprite.drawChar(':', xcolon, ypos, 7);
      sprite.pushSprite(0, 0);
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker
      sprite.fillRect(0, 64, 160, 20, TFT_BLACK);//区域清除
    }
  }
}

void updateTime() {
  timeClient.update();                                  // 更新时间信息
  unsigned long epochTime = timeClient.getEpochTime();  // 获取当前时间的时间戳
#ifdef ESP32
  struct tm *ptm = gmtime((time_t *)&epochTime);  // 将时间戳转换为tm结构体
#else
  time_t ntpTime = (time_t)epochTime;
  struct tm *ptm = localtime(&ntpTime);  // 将时间戳转换为tm结构体
#endif
  // 将epochTime换算成年月日
  currentYear = ptm->tm_year + 1900;  // 获取年份
  currentMonth = ptm->tm_mon + 1;     // 获取月份
  currentMonthDay = ptm->tm_mday;     // 获取月份中的日期
#ifdef ESP32
  currentWeekDay = ptm->tm_wday;  // 获取星期几
  if (currentWeekDay < 0) {
    currentWeekDay += 7;  // 将负数转换为正数
  }
  currentHour = ptm->tm_hour;  // 获取时
  currentMin = ptm->tm_min;    // 获取分
  currentSec = ptm->tm_sec;    // 获取秒
#else
  currentHour = timeClient.getHours();   // 获取时
  currentMin = timeClient.getMinutes();  // 获取分
  currentSec = timeClient.getSeconds();  // 获取秒
  currentWeekDay = timeClient.getDay();  // 获取星期几
#endif
#ifdef SERIAL_DEBUG
  // 打印时间
  Serial.println("Epoch Time: " + String(epochTime));  // 打印时间戳
  Serial.println(timeClient.getFormattedTime());       // 打印时间格式
  Serial.printf("NTP Time: %04d-%02d-%02d\n", currentYear, currentMonth, currentMonthDay);
#endif
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/145612.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SQLite】的使用及指令| 编程操作(增删改查)

一、SQLite 使用和指令集 SQLite 的基本使用SQL 命令 二、常见的 SQL 数据类型 三、SQLite的命令用法 四、SQLite的编程操作 五、sqlite3_open函数 六、sqlite3_close函数 七、sqlite3_errcode函数 八、SQLite C Interface 九、sqlite3_exec函数 十、callback回调函数 十一、…

vue:如何把后端传过来的数组的其中一个对象加入新的属性

加入我们是更改数组中的第一个对象&#xff0c;在vue中可以使用$set方法将属性插入到第一个对象中作为属性。 Script部分&#xff1a; <script>export default {data() {return {boxes: [//模拟后端传过来的数组{id:1,name:张三},{id:2,name:李四},{id:3,name:王五},{i…

香港科技大学广州|智能制造学域机器人与自主系统学域博士招生宣讲会—中国科学技术大学专场

&#x1f3e0;地点&#xff1a;中国科学技术大学西区学生活动中心&#xff08;一楼&#xff09;报告厅 【宣讲会专场1】让制造更高效、更智能、更可持续—智能制造学域 &#x1f559;时间&#xff1a;2023年11月16日&#xff08;星期四&#xff09;18:00 报名链接&#xff1a…

【SpringBoot篇】使用Spring Cache高效处理缓存数据

文章目录 &#x1f339;简述Spring Cache&#x1f3f3;️‍&#x1f308;常用注解&#x1f33a;使用SpringCache&#x1f6f8;Cacheable注解⭐测试 &#x1f6f8;CacheEvict&#x1f38d;一次清理一条数据&#x1f38d;一次删除多条数据 Spring Cache是一个框架,只要简单加一个…

【Mysql】MySQL基于成本的优化

什么是成本 我们之前说 过MySQL 执行一个查询可以有不同的执行方案&#xff0c;它会选择其中成本最低&#xff0c;或者说代价最低的那种方案去真正的执行查询。那么成本是怎么计算的呢&#xff0c;其实在 MySQL 中一条查询语句的执行成本是由下边这两个方面组成的: I/O 成本 …

数据结构:反射

基本概念 反射中的四个类 Class类 Java文件在被编译之后&#xff0c;生成了.class文件&#xff0c;JVM此时解读.class文件&#xff0c;将其解析为java.lang.Class 对象&#xff0c;在程序运行时每个java文件就最终变成了Class类对象的一个实例。通过反射机制应用这个 实例就…

如何在Qemu上跑Milk-duo开发板

前言 &#xff08;1&#xff09;PLCT实验室实习生长期招聘&#xff1a;招聘信息链接 &#xff08;2&#xff09;学习本文之前&#xff0c;要求先看一下Milk-V Duo快速上手的环境搭建部分&#xff0c;创建好镜像文件。 正文 编译milk-duo qemu &#xff08;1&#xff09;下面步…

No203.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

YOLOv8全网独家优化:IoU系列篇 | Inner-IoU融合MPDIoU,创新十足,2023年11月最新IoU改进

🚀🚀🚀本文改进: Inner-IoU(基于辅助边框的IoU损失)结合MPDIoU进行创新,创新十足,全网首发 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1.Inner-IoU介绍 论文:https://arxiv.org/abs/2311.02…

Python---集合中的交集 、并集 | 与差集 - 特性

用 & 来求两个集合的交集&#xff1a;-----键盘上的7上的符号&#xff0c;shift 7 同时按 用 | 来求两个集合的并集&#xff1a; -----键盘上的7上的符号&#xff0c;shift 同时按&#xff08;就是enter键上面那个|\ &#xff09; 用 - 来求两个集合的差集&#xff…

Vue3-TypeScript-Threejs:导入外部的glb格式3D模型

一、直接上代码&#xff0c;在vue3-typescript-threejs 项目 导入外部的glb格式3D模型 极简代码&#xff0c;快速理解 <template><div ref"container"></div></template><script lang"ts" setup>import { onMounted, ref …

Linux应用层点亮硬件的LED灯

一 应用层操作硬件的两种方法 应用层想要对底层硬件进行操控&#xff0c;通常可以通过两种方式&#xff1a; /dev/目录下的设备文件&#xff08;设备节点&#xff09;&#xff1b;/sys/目录下设备的属性文件。 具体使用哪种方式需要根据不同功能类型设备进行选择&#xff0c;通…

人工智能与充电技术:携手共创智能充电新时代

人工智能与充电技术&#xff1a;携手共创智能充电新时代 摘要&#xff1a;本文探讨了人工智能与充电技术的结合及其在未来充电设施领域的应用。通过分析智能充电系统的技术原理、优势以及挑战&#xff0c;本文展望了由人工智能驱动的充电技术为未来电动交通带来的巨大变革与机…

No202.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

Leetcode—4.寻找两个正序数组的中位数【困难】

2023每日刷题&#xff08;二十九&#xff09; Leetcode—4.寻找两个正序数组的中位数 直接法实现代码 int mid, mid1, mid2; bool findmid(int n, int k, int x) {if(n % 2 1) {if(k n / 2) {mid x;return true;}} else {if(k n / 2 - 1) {mid1 x;} else if(k n / 2) {…

3DMAX渲染AO图的三种方法

3DMAX渲染AO图的三种方法 使用Mental Ray渲染AO 1. 我为这个演示制作了一个非常简单的场景。该场景包含一个茶壶、一个盒子和一个球体。我还应用了一些材质&#xff0c;并将渲染引擎设置为Mental Ray。 2. 我还在场景中添加并定位了几个泛光灯。 3. 我选择了Mental Ra…

主题讲座:全球增材制造现状与未来(暨香港科技大学广州|智能制造学域2024博士学位全额奖学金项目)

时间&#xff1a;2023 年11月16日&#xff08;星期四&#xff09;14:30 地点&#xff1a;合肥工业大学 学术会议中心三楼报告厅 主讲嘉宾&#xff1a;陈模军 助理教授 https://facultyprofiles.hkust-gz.edu.cn/faculty-personal-page/CHEN-Mojun/mjchen 报名表直达&#xff1…

数字化时代,企业如何增加产品销售额

2023作为提振消费年&#xff0c;国民宏观经济环境正在复苏&#xff0c;而数字化技术的进步也使消费者的购买方式发生了翻天覆地的变化&#xff0c;对于企业而言&#xff0c;应该如何顺势而上增加产品销售额&#xff0c;成为其成功的关键。 今天媒介盒子就来和大家聊聊企业如何…

DVWA - 3

文章目录 XSS&#xff08;Dom&#xff09;lowmediumhighimpossible XSS&#xff08;Dom&#xff09; XSS 主要基于JavaScript语言进行恶意攻击&#xff0c;常用于窃取 cookie&#xff0c;越权操作&#xff0c;传播病毒等。DOM全称为Document Object Model&#xff0c;即文档对…

笔试题之指针和数组的精讲

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…