上一篇学习笔记讲了如何在Arduino上配置ESP32开发环境,这次分享一下如何让ESP32联网获取时间再通过OLED来显示。此系列文章都是学习笔记,希望能有所帮助。

ps:代码中调用的库如需要可在在文末查找下载

目录

1、OLED显示时间( SSD1306 IIC)

2、OLED显示时间(U8G2 SPI DS1302时钟芯片维持走时)

3、 夹带私货的一期产品——智锺(简陋)

4、调用的库

1、OLED显示时间( SSD1306 IIC)

这里使用的是SSD1306驱动的IIC的OLED屏幕,通过RTC时钟维持联网同步时间后的继续走时,这种走时不准,后面有说加一个时钟芯片维持走时的。并且从这里开始,笔者发现实际同步后的时间还是会比网络时间酌情慢一些(1至2s),应该是由通信延迟导致的,包括ESP32联网获取时间的延迟和ESP32向OLED屏幕传输时间的延迟。

下面的代码注释很详细,可以直接CV烧录,需要自己更改的只有wifi名字和密码(后面会更新不在代码中设置名称和密码的版本,开机后手动输入名称和密码,适合不同环境)。另外需要注意SDA,SCL的接线引脚。

附(ESP32 WROOM引脚图):

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>// 引入驱动OLED所需的库
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>#define SCREEN_WIDTH 128 // 设置OLED宽度,单位:像素
#define SCREEN_HEIGHT 64 // 设置OLED高度,单位:像素// 自定义重置引脚,虽然教程未使用,但却是Adafruit_SSD1306库文件所必需的
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);const char *ssid = "821"; //你的网络名称
const char *password = "54085408"; //你的网络密码
// "pool.ntp.org";
const char *ntpServer = "ntp.neu.edu.cn";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;void printLocalTime()
{struct tm timeinfo;if (!getLocalTime(&timeinfo)){display.println("Failed to obtain time");return;}display.println(&timeinfo, "%F"); // 格式化输出display.println(&timeinfo, "%T"); // 格式化输出display.println(&timeinfo, "%A"); // 格式化输出
}void setup()
{// put your setup code here, to run once://设置I2C的两个引脚SDA和SCL,这里用到的是17作为SDA,作为SCLWire.setPins(/*SDA*/33,/*SCL*/32);//初始化OLED并设置其IIC地址为 0x3Cdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C);//清除屏幕display.clearDisplay();//设置字体颜色,白色可见display.setTextColor(WHITE);//设置字体大小display.setTextSize(1);//设置光标位置display.setCursor(0, 0);WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED){delay(500);display.print(".");}display.println("WiFi connected!");// 从网络时间服务器上获取并设置时间// 获取成功后芯片会使用RTC时钟保持时间的更新configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);printLocalTime();WiFi.disconnect(true);WiFi.mode(WIFI_OFF);display.println("WiFi disconnected!");display.display();
}void loop()
{// put your main code here, to run repeatedly:、delay(1000);//清除屏幕display.clearDisplay();//设置光标位置display.setCursor(0, 0);printLocalTime();display.display();}

2、OLED显示时间(U8G2 SPI DS1302时钟芯片维持走时)

后面笔者和组员就使用了4线SPI的OLED屏继续开发,并且加入了时钟芯片使联网同步时间后的走时更加准确(依然有延迟,暂时不知道怎么优化,有时候就刚好玄学对的上)。

联网获取时间得到的数据用于初始化DS1302时钟芯片,后续是ESP32从时钟芯片获取时间再传到OLED进行显示。

同样的,支持两键CV烧录,只需要更改wifi名称和密码;同样的,也需要注意接线,DS1302时钟芯片和OLED SPI的接线,代码中有设置好的引脚,也可自行依据上面的引脚图自行定义。              注意!笔者的OLED是SH1106驱动的,购买OLED前,询问商家查明驱动芯片,如与我不同只需要更改此处的芯片型号即可。

#include <stdio.h>
#include <Arduino.h>
#include <WiFi.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <DS1302.h>/*-------------------------------WIFI--------------------------------------------------*/
const char* ssid = "123";           //wifi 名字
const char* password = "12345678";  // wifi 密码//-----------网络时间获取-----------//
const char* ntpServer = "pool.ntp.org";  //网络时间服务器
//时区设置函数,东八区(UTC/GMT+8:00)写成8*3600
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;  //夏令时填写3600,否则填0
/*-------------------------------WIFI--------------------------------------------------*//*-------------------------------DS1302-------------------------------------------------*/
//设置适当的数字 I/O 引脚连接
//这些是Arduino以及DS1302芯片的引脚分配。
//参见DS1302数据表:
//http://datasheets.maximintegrated.com/en/ds/DS1302.pdf
const int kCePin = 13;    // RST
const int kIoPin = 23;    // DAT
const int kSclkPin = 19;  // CLKDS1302 rtc(kCePin, kIoPin, kSclkPin);  //创建 DS1302 对象
/*-------------------------------DS1302-------------------------------------------------*//*----------------------------OLED--------------------------------*/
U8G2_SH1106_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18, /* data=*/ 15, /* cs=*/ 5, /* dc=*/ 22, /* reset=*/ 21);
/*----------------------------OLED--------------------------------*/struct tm timeinfo;String dayAsString() {switch (timeinfo.tm_wday) {case 1: return "Monday";case 2: return "Tuesday";case 3: return "Wednesday";case 4: return "Thursday";case 5: return "Friday";case 6: return "Saturday";case 7: return "Sunday";}return "(unknown day)";
}void printTime()  //打印时间数据
{// 从芯片获取时间Time t = rtc.time();// 定义星期几const String day = dayAsString();// 设置时间和日期的格式并插入到临时缓冲区中char buf[50];snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",t.yr, t.mon, t.date,t.hr, t.min, t.sec);u8g2.clearBuffer();                  // 清除内部存储器u8g2.setFont(u8g2_font_ncenB08_tr);  // 选择合适的字体u8g2.setCursor(0, 32);u8g2.print(day);u8g2.drawStr(2, 10, buf);  // 写入内部存储器u8g2.sendBuffer();         // 将内部存储器传输到显示器Serial.println(day);Serial.println(buf);
}void setu8g2() {Serial.begin(115200);u8g2.begin();
}void getTime(void)  //联网获取时间
{WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("WiFi connected!");// 从网络时间服务器上获取并设置时间// 获取成功后芯片会使用RTC时钟保持时间的更新configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);if (!getLocalTime(&timeinfo)) {Serial.println("Failed to obtain time");return;}Serial.println(&timeinfo, "%F %T %A");  // 格式化输出uint16_t year = (uint16_t)timeinfo.tm_year;uint8_t mon = (uint8_t)(timeinfo.tm_mon) + 1;uint8_t day = (uint8_t)timeinfo.tm_mday;uint8_t hour = (uint8_t)timeinfo.tm_hour;uint8_t min = (uint8_t)timeinfo.tm_min;uint8_t sec = (uint8_t)timeinfo.tm_sec;rtc.writeProtect(false);                                                                                       //关闭写保护rtc.halt(false);                                                                                               //清除时钟停止标志Time t((uint16_t)year + 1900, (uint8_t)mon, (uint8_t)day, (uint8_t)hour, (uint8_t)min, sec, Time::kSaturday);  //新建时间对象 最后参数位星期数据,周日为1,周一为2以此类推rtc.halt(false);rtc.time(t);  //向DS1302设置时间数据rtc.writeProtect(true);WiFi.disconnect(true);WiFi.mode(WIFI_OFF);Serial.println("WiFi disconnected!");
}void setup() {setu8g2();getTime();
}void loop() {printTime();delay(1000);
}

3、 夹带私货的一期产品——智锺(简陋)

#include <stdio.h>
#include <DS1302.h>#include <Arduino.h>
#include <U8g2lib.h>#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif#define BUS_CLOCK 400000  // 最大400000
#define DURATION 1000     // 加载条持续时长(ms)#include <WiFi.h>/*-------------------------------WIFI--------------------------------------------------*/
const char* ssid = "821";           //wifi 名字
const char* password = "54085408";  // wifi 密码//-----------网络时间获取-----------//
const char* ntpServer = "pool.ntp.org";  //网络时间服务器
//时区设置函数,东八区(UTC/GMT+8:00)写成8*3600
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;  //夏令时填写3600,否则填0
/*-------------------------------WIFI--------------------------------------------------*//*-------------------------------DS1302-------------------------------------------------*/
//设置适当的数字 I/O 引脚连接
//这些是Arduino以及DS1302芯片的引脚分配。
//参见DS1302数据表:
//http://datasheets.maximintegrated.com/en/ds/DS1302.pdf
const int kCePin = 4;    // RST
const int kIoPin = 23;    // DAT
const int kSclkPin = 19;  // CLKDS1302 rtc(kCePin, kIoPin, kSclkPin);  //创建 DS1302 对象
/*-------------------------------DS1302-------------------------------------------------*//*----------------------------OLED--------------------------------*/
U8G2_SH1106_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18, /* data=*/ 15, /* cs=*/ 5, /* dc=*/ 22, /* reset=*/ 21);
/*----------------------------OLED--------------------------------*/struct tm timeinfo;static const unsigned char logo[] U8X8_PROGMEM = {//logo0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x0F,0x00,0xC0,0x03,0xF4,0x00,0xE0,0x01,0xE2,0x01,0xF0,0x01,0xE2,0x03,0xF0,0x00,0xC1,0x03,0x78,0x80,0x80,0x07,0x78,0x80,0x80,0x07,0x3C,0x00,0x00,0x0F,0x3C,0xE0,0x07,0x0F,0x1E,0xF0,0x07,0x1E,0xFE,0xFB,0xF7,0x1F,0x1E,0xF8,0x03,0x1E,0x3C,0xF8,0x01,0x0F,0x3C,0x00,0x00,0x0F,0x78,0x40,0x80,0x07,0x78,0x40,0x80,0x07,0xF0,0x20,0xC0,0x03,0xF0,0x11,0xE0,0x03,0xE0,0x11,0xE0,0x01,0xC0,0x0B,0xF0,0x00,0x00,0xFC,0x0F,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};String dayAsString() {switch (timeinfo.tm_wday) {case 1: return "Monday";case 2: return "Tuesday";case 3: return "Wednesday";case 4: return "Thursday";case 5: return "Friday";case 6: return "Saturday";case 7: return "Sunday";}return "(unknown day)";
}void printTime()  //打印时间数据
{// 从芯片获取时间Time t = rtc.time();// 定义星期几const String day = dayAsString();// 设置时间和日期的格式并插入到临时缓冲区中char buf[50];snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",t.yr, t.mon, t.date,t.hr, t.min, t.sec);u8g2.clearBuffer();                  // 清除内部存储器u8g2.setFont(u8g2_font_ncenB08_tr);  // 选择合适的字体u8g2.setCursor(0, 32);u8g2.print(day);u8g2.drawStr(2, 10, buf);  // 写入内部存储器u8g2.sendBuffer();         // 将内部存储器传输到显示器Serial.println(day);Serial.println(buf);
}void setu8g2() {Serial.begin(115200);u8g2.setBusClock(BUS_CLOCK);u8g2.begin();u8g2.enableUTF8Print();u8g2.setFont(u8g2_font_wqy12_t_gb2312);u8g2.setPowerSave(0);
}void load_bar(int W) {u8g2.clearBuffer();unsigned long time;time = millis();// for (; W <= 128;) // W:宽度// {for (int mode = 0; mode < 4; mode++) {u8g2.clearBuffer();for (int H = 48; H < 64; H++)  // H:高度{switch (mode) {case 0:for (int j = 0; j < W; j += 4) {u8g2.drawPixel(j, H);u8g2.drawPixel(j + 1, H);}mode = 1;break;case 1:for (int j = 0; j < W; j += 4) {u8g2.drawPixel(j + 1, H);u8g2.drawPixel(j + 2, H);}mode = 2;break;case 2:for (int j = 0; j < W; j += 4) {u8g2.drawPixel(j + 2, H);u8g2.drawPixel(j + 3, H);}mode = 3;break;case 3:for (int j = 0; j < W; j += 4) {u8g2.drawPixel(j, H);u8g2.drawPixel(j + 3, H);}mode = 0;break;}}// u8g2.drawStr(0, 36, "智汇嵌入式");     // 在指定位置显示字符串u8g2.drawXBM(0, 8, 30, 30, logo);u8g2.setCursor(30, 22);u8g2.print("智汇嵌入式");u8g2.setCursor(32, 34);u8g2.print("ZHIHUIEMBEDDED");  // 在指定位置显示字符串u8g2.sendBuffer();delay(10);}// if ((millis() - time) > (DURATION / 4))// {//     time = millis();//     W += 32;// }// }
}void getTime(void)  //联网获取时间
{WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {int W = 0;unsigned long time;time = millis();for (; W < 129;) {if ((millis() - time) > (DURATION / 4)) {time = millis();W += 32;}load_bar(W);}}Serial.println("WiFi connected!");// 从网络时间服务器上获取并设置时间// 获取成功后芯片会使用RTC时钟保持时间的更新configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);if (!getLocalTime(&timeinfo)) {Serial.println("Failed to obtain time");return;}Serial.println(&timeinfo, "%F %T %A");  // 格式化输出uint16_t year = (uint16_t)timeinfo.tm_year;uint8_t mon = (uint8_t)(timeinfo.tm_mon) + 1;uint8_t day = (uint8_t)timeinfo.tm_mday;uint8_t hour = (uint8_t)timeinfo.tm_hour;uint8_t min = (uint8_t)timeinfo.tm_min;uint8_t sec = (uint8_t)timeinfo.tm_sec;rtc.writeProtect(false);                                                                                       //关闭写保护rtc.halt(false);                                                                                               //清除时钟停止标志Time t((uint16_t)year + 1900, (uint8_t)mon, (uint8_t)day, (uint8_t)hour, (uint8_t)min, sec, Time::kSaturday);  //新建时间对象 最后参数位星期数据,周日为1,周一为2以此类推rtc.halt(false);rtc.time(t);  //向DS1302设置时间数据rtc.writeProtect(true);u8g2.clear();WiFi.disconnect(true);WiFi.mode(WIFI_OFF);Serial.println("WiFi disconnected!");
}void setup() {setu8g2();getTime();
}void loop() {printTime();delay(1000);
}

4、调用的库

百度网盘

链接:https://pan.baidu.com/s/1m_N8mJov1IVzlUwhobzSzg?pwd=5408 
提取码:5408

二、ESP32基于Arduino IDE OLED 联网显示时间相关推荐

  1. ESP32基于Arduino框架下U8g2驱动I2C OLED 时间显示

    ESP32基于Arduino框架下U8g2驱动I2C OLED时间显示

  2. 【嵌入式】STM32基于SPI通信协议OLED屏显示

    STM32基于SPI通信协议OLED屏显示 一.SPI协议和OLED介绍 1.SPI协议介绍 物理层 协议层 2.OLED显示屏介绍 二.显示个人学号姓名实验 1.题目要求 2.代码部分 1.完整代码 ...

  3. 基于Arduino IDE开发的ESP8266(ESP-12F)项目4 ——中断及高级输入输出

     本次写这篇文章是自己做一下学习记录,如有错误,还请大家斧正!!! 日后及时修正!感谢支持! 欢迎大家的关注        点赞        收藏        留言 目录 前言 一.新建工程 二. ...

  4. 基于Arduino IDE开发的ESP8266(ESP-12F)项目2 ——按键操作

     本次写这篇文章是自己做一下学习记录,如有错误,还请大家斧正!!! 日后及时修正!感谢支持! 欢迎大家的关注        点赞        收藏        留言 目录 前言 一.新建工程 二. ...

  5. 基于STM32实现OLED滚动显示

    基于STM32实现OLED滚动显示 滚动方式 水平滚动 水平加垂直滚动 一.文字取模 二.代码修改 三.硬件连接加结果 总结 参考文献 滚动方式 水平滚动 OLED_WR_Byte(0x2E,OLED ...

  6. 实验 STM32 基于SPI的OLED屏显示

    STM32 基于SPI的OLED屏显示 一.任务要求 二.显示自己的学号和姓名 1.例子程序的改写 (1)下载资料 (2)解压后找到文件,并用KEIL打开. (3)改写程序 2.连接硬件 3.运行结果 ...

  7. 合宙ESP32C3基于Arduino IDE框架下配置分区表

    合宙ESP32C3基于Arduino IDE框架下配置分区表 关于VSCode PIO配置分区表可以参考示例文章<合宙ESP32C3基于VSCode PIO开发初探教程> 有关Arduin ...

  8. esp32使用MicroPython驱动oled屏显示中文和英文

    文章目录 esp32使用MicroPython驱动oled屏显示中文和英文 介绍 安装 特点 开源 硬件连接 API 示例 显示英文字符 显示汉字 参考链接 esp32使用MicroPython驱动o ...

  9. ESP32基于Arduino框架,SD卡+MAX98357模块+MP3播放器

    ESP32基于Arduino框架,SD卡+MAX98357模块+MP3播放器

最新文章

  1. dram和nand哪个难生产_DRAM与NAND差别这么大,存储之争都争啥
  2. 【计算机网络】网络层 : 网络层简介 ( 功能 | 拥塞控制 )
  3. MySQL 高级 - 存储过程 - 语法 - 游标
  4. python生成1到100的列表_python列表生成式与列表生成器的使用
  5. 网站登录JWT的实现
  6. Spring 类管理机制
  7. 李宏毅《机器学习》完整版笔记发布
  8. java 祖父类_JAVA的XX.put中的put方法,是在哪个父类或祖父类中,详述父类链。
  9. Inception V3 的 tensorflow 实现
  10. 数字信号处理实验(六)—— 心电信号处理 IIR FIR滤波综合题(下篇)
  11. 官方配置要求_《魔兽争霸3》重制版极客装机配置和官方要求配置
  12. 模拟电子技术基础笔记(1)
  13. 邮箱怎么打开smtp服务器端口号,什么是SMTP协议?SMTP端口号是多少?什么是SMTP服务器?免费smtp服务器?...
  14. 黑页网站html源码,仿360网站卫士拦截页面黑页源码
  15. 李嘉诚:没有人愿意贫穷,但出路在哪(转自意林)
  16. 光猫下连接路由器的详细步骤
  17. u3d:200个插件免费分享
  18. 使用tsx开发vue项目入门
  19. isfinite函数_isfinite()函数以及C ++中的示例
  20. 百度浏览器的隐私安全问题分析

热门文章

  1. L2-028 秀恩爱分得快 (25 分)(模拟)
  2. AI实战:2019、2020最新的中文文本检测检测模型
  3. oracle sql查询缺失号,Oracle层次查询和分析函数
  4. js判断输入的是否为数字
  5. mysql截取前几个字符串_mysql 截取字符串 函数
  6. logrotate测试_Linux自带神器logrotate详解
  7. Android TextView的setHint不生效
  8. 批量读取txt文件中的内容进入csv文件
  9. #每日一记#开发微博的 Chrome 插件 快捷键问题
  10. 网站停服、秒杀大促…解析高可用网站架构云化