在本文中我尝试在esp32(micropython)上通过网络同步时间(东八区北京时间)后将时间显示至0.96寸的oled屏幕(ssd1315)上,但是尝试文档中的示例代码(ntptime.settime(timezone=8, server='ntp.ntsc.ac.cn'))发现所传的两个参数不存在,因此在网上寻找其他资料,这里感谢博主zld_555的博文对我提供的帮助,原文链接:
micropython实现ntp获取网络时间(UTC+8)_ntptime.ntp_delta-优快云博客
下面我将直接提供我的代码,相关内容我都写到注释中
import network
import ntptime
import time
from ssd1315 import SSD1315_I2C
from machine import Pin,I2C
# 冒号的字模
pic_m = [0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00]
# 数字0~9的字模
pic = [[0x00, 0x07, 0x08, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0xF0, 0x08, 0x04, 0x04, 0x08, 0xF0, 0x00],
[0x00, 0x00, 0x08, 0x08, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFC, 0x04, 0x04, 0x00],
[0x00, 0x0E, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x00, 0x00, 0x0C, 0x14, 0x24, 0x44, 0x84, 0x0C, 0x00],
[0x00, 0x0C, 0x10, 0x10, 0x10, 0x11, 0x0E, 0x00, 0x00, 0x18, 0x04, 0x84, 0x84, 0x44, 0x38, 0x00],
[0x00, 0x00, 0x01, 0x02, 0x0C, 0x1F, 0x00, 0x00, 0x00, 0x60, 0xA0, 0x24, 0x24, 0xFC, 0x24, 0x24],
[0x00, 0x1F, 0x11, 0x11, 0x11, 0x10, 0x10, 0x00, 0x00, 0x98, 0x04, 0x04, 0x04, 0x88, 0x70, 0x00],
[0x00, 0x07, 0x08, 0x11, 0x11, 0x09, 0x00, 0x00, 0x00, 0xF0, 0x88, 0x04, 0x04, 0x04, 0xF8, 0x00],
[0x00, 0x18, 0x10, 0x10, 0x11, 0x16, 0x18, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x80, 0x00, 0x00, 0x00],
[0x00, 0x0E, 0x11, 0x10, 0x10, 0x11, 0x0E, 0x00, 0x00, 0x38, 0x44, 0x84, 0x84, 0x44, 0x38, 0x00],
[0x00, 0x0F, 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x80, 0x48, 0x44, 0x44, 0x88, 0xF0, 0x00]
]
def sync_ntp():
ntptime.NTP_DELTA = 3155644800 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
ntptime.host = 'ntp1.aliyun.com' # 可选,ntp服务器,默认是"pool.ntp.org"
ntptime.settime() # 修改设备时间,到这就已经设置好了
def re_place(n): # 返回数字的个位数和十位数
n2 = 0
n1 = 0
n2 = int(n/10)
n1 = int(n%10) # 取余取个位
return [n1,n2]
# 连接wifi,不连接wifi同步时间步骤会报错
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
print("连接中",end="")
while not wlan.isconnected(): # 当没有连接wifi时才会执行连接的代码
wlan.connect('腿','12345678ggg')
print(".",end="")
print("\n网络连接成功!")
sync_ntp() # 同步当前网络时间,必须在连接wifi之后
# 屏幕初始化
i2c=I2C(0,scl=Pin(22),sda=Pin(21))
oled=SSD1315_I2C(i2c)
# 显示当前时间和日期
while True:
t = time.localtime() # 将当前时间转换为数组格式,可以通过下标索引年月日时分秒
# print(t)
# print('当前时间是:{}年{}月{}日 {}:{}:{}'.format(t[0], t[1], t[2], t[3], t[4], t[5]))
oled.fill(0) # 清空屏幕内容,否则会出现重影
# 获取小时
n = re_place(t[3])
oled.p8_16(pic[n[1]],0,0) # 小时的十位
oled.p8_16(pic[n[0]],8,0) # 小时的个位
oled.p8_16(pic_m,16,0) # 冒号
# 获取分钟
n = re_place(t[4])
oled.p8_16(pic[n[1]],24,0)
oled.p8_16(pic[n[0]],32,0)
oled.p8_16(pic_m,40,0) # 冒号
# 获取秒数
n = re_place(t[5])
oled.p8_16(pic[n[1]],48,0) #
oled.p8_16(pic[n[0]],56,0)
oled.show() # 刷新屏幕
time.sleep(1)
在代码中我使用了方法p8_16()用于显示8*16规格的数字字符,在驱动文件中的类SSD1315中增加这一方法:
def p8_16(self,page,x,y):
for e in range(16):
byte=bin(page[e]).replace('0b','')
while len(byte)<8:
byte='0'+byte
for i in range(8):
if byte[i] and e<8:
self.pixel(x+e,y+i,int(byte[i])) #有一个关键的问题,显示器左上角为0,0,右下角为127,63,所以这里先画了图像的上半部分
elif byte[i] and e>=8:
self.pixel(x-8+e,y+8+i,int(byte[i])) #再画图像的下半部分
显示效果