优化点:
1、_thread线程改成定时器
ESP32支持4个定时器Timer(0 1 2 3)
The ESP32 port has four hardware timers. Use the machine.Timer class with a timer ID from 0 to 3 (inclusive):
from machine import Timer
tim0 = Timer(0)
tim0.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(0))
tim1 = Timer(1)
tim1.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(1))
2、RTC时钟
The RTC is an independent clock that keeps track of the date and time.
Example usage:
rtc = machine.RTC()
rtc.datetime((2020, 1, 21, 2, 10, 32, 36, 0))
print(rtc.datetime())
3、10分钟定时同步NTP时间
def sync_ntp(prt=False):
for i in range(1,11):
try:
"""通过网络校准时间"""
ntptime.NTP_DELTA = 3155644800 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
ntptime.host = 'pool.ntp.org' # 可选,ntp服务器,默认是"pool.ntp.org" 这里使用阿里服务器
ntptime.settime() # 修改设备时间,到这就已经设置好了
print("set ntp time ok!")
if prt:
oled.fill(0) #清空屏幕
oled.text("set ntp time ok!", 10, 10)
oled.show()
time.sleep(1)
break
except OSError as e:
if e.errno == 116: # [Errno 116] ETIMEDOUT
print("Connection timed out. Retrying...")
# Handle the timeout situation, e.g., retry the operation
else:
# Handle other OSError exceptions
print("An error occurred:", e)
oled.fill(0) #清空屏幕
oled.text("set ntp time timed out. Retrying...", 10, 10)
oled.show()
time.sleep(1)
最后直接上mian.py
from lib import urequests
from machine import Pin,I2C
from machine import SoftI2C
from machine import Timer
from machine import RTC
from ssd1306 import SSD1306_I2C #从ssd1306模块中导入SSD1306_I2C子模块
import time,ntptime,network
import ujson
import sys
import _thread
import re
#创建RTC对象
rtc=RTC()
#创建软件I2C对象
i2c = SoftI2C(sda=Pin(23), scl=Pin(18))
#创建OLED对象,OLED分辨率、I2C接口
oled = SSD1306_I2C(128, 64, i2c)
#定义LED控制对象
led1=Pin(15,Pin.OUT)
led1.value(0)
# 心知天气API申请:https://seniverse.yuque.com
# API_KEY = 'S9hoa4Wza9Hcs2uX_'
#接口;https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c
# LOCATION = 'zhuzhou'
# URL = 'https://api.seniverse.com/v3/weather/now.json'
# UNIT = 'c'
# LANGUAGE = 'zh-Hans'
#路由器WIFI账号和密码
ssid="FAST_0DB8"
password="xxxxxxx"
#WIFI连接
def wifi_connect():
wlan=network.WLAN(network.STA_IF) #STA模式
wlan.active(True) #激活
#start_time=time.time() #记录时间做超时判断
cnt = 0
if not wlan.isconnected():
print("conneting to network...")
oled.fill(0) #清空屏幕
oled.text("conneting to wifi...", 10, 10)
oled.show()
time.sleep(1)
wlan.connect(ssid,password) #输入 WIFI 账号密码
while not wlan.isconnected():
cnt += 1
led1.value(1)
time.sleep(0.5)
led1.value(0)
time.sleep(0.5)
print("cnt", cnt)
#超时判断,15 秒没连接成功判定为超时
if cnt > 15:
print("WIFI Connect Timeout!")
oled.fill(0) #清空屏幕
oled.text("WIFI Connect Timeout!", 10, 10)
oled.show()
time.sleep(1)
return False
return True
else:
print("network information:", wlan.ifconfig())
oled.fill(0) #清空屏幕
oled.text("WIFI Connect OK!", 10, 10)
oled.show()
time.sleep(1)
return True
def sync_ntp(prt=False):
for i in range(1,11):
try:
"""通过网络校准时间"""
ntptime.NTP_DELTA = 3155644800 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
ntptime.host = 'pool.ntp.org' # 可选,ntp服务器,默认是"pool.ntp.org" 这里使用阿里服务器
ntptime.settime() # 修改设备时间,到这就已经设置好了
print("set ntp time ok!")
if prt:
oled.fill(0) #清空屏幕
oled.text("set ntp time ok!", 10, 10)
oled.show()
time.sleep(1)
break
except OSError as e:
if e.errno == 116: # [Errno 116] ETIMEDOUT
print("Connection timed out. Retrying...")
# Handle the timeout situation, e.g., retry the operation
else:
# Handle other OSError exceptions
print("An error occurred:", e)
oled.fill(0) #清空屏幕
oled.text("set ntp time timed out. Retrying...", 10, 10)
oled.show()
time.sleep(1)
def fetchWeather():
result = urequests.get("https://api.seniverse.com/v3/weather/now.json?key=S9hoa4Wza9Hcs2uX_&location=shenzhen&language=zh-Hans&unit=c")
return result.text
class CWeather:
def __init__(self, addr="", weather="", temperature=""):
self.addr = addr
self.weather = weather
self.temperature = temperature
g_weather = CWeather()
def threadFetchWeather(tim0):
global g_weather
print("=======================threadFetchWeather=========================")
result = urequests.get("https://api.seniverse.com/v3/weather/now.json?key=S9hoa4Wza9Hcs2uX_&location=shenzhen&language=zh-Hans&unit=c")
text = result.text
result.close()
print("text", text)
j=ujson.loads(text)
print(j['results'][0]['location']['name'])
print(j['results'][0]['now']['text'])
print(j['results'][0]['now']['temperature'])
print(j['results'][0]['last_update'])
print("\r\n\r\n")
g_weather.addr=j['results'][0]['location']['name']
g_weather.weather=j['results'][0]['now']['text']
g_weather.temperature=j['results'][0]['now']['temperature']
sync_ntp(True)
localTime = time.localtime()
# 设置新的本地时间
new_time = (localTime[0], localTime[1], localTime[2], 0, localTime[3], localTime[4], localTime[5], 0)
#设置RTC时间
rtc.datetime(new_time)
print("set rtc ok!!!")
def threadShowOled(tim1):
global oled
global g_weather
#oled.fill(0) #清空屏幕
oled.text("ESP32 Weather Clock", 4, 0)
oled.line(0, 14, 128, 14, 1)#划线
oled.show()
print("show oled:%s %s %s"%(g_weather.addr, g_weather.weather, g_weather.temperature))
if 0 == len(g_weather.addr):
return
oled.fill(0) #清空屏幕
oled.text("ESP32 Weather Clock", 4, 0)
oled.line(0, 14, 128, 14, 1)#划线
oled.text("地点:%s"%g_weather.addr,0,16)
oled.text("天气:%s 温度:%s℃"%(g_weather.weather, g_weather.temperature),0,32)
localtime = rtc.datetime()
print("localtime: ", localtime)
strTime = ("%d-%02d-%02d %02d:%02d:%02d"%(localtime[0], localtime[1], localtime[2], localtime[4], localtime[5], localtime[6]))
print(strTime)
oled.text("%s"%strTime,0,48)
oled.show()
if __name__ == '__main__':
#def test():
oled.font_load("GB2312-12.fon")# 所使用的字体时12号字体
print("begin connect wifi")
if wifi_connect():
print("connect wifi success")
else:
print("connect wifi failed")
sys.exit(0)
sync_ntp()
# 天气10分钟获取一次
tim0 = Timer(0)
threadFetchWeather(tim0)
tim0.init(period=1000*60*10, mode=Timer.PERIODIC, callback=threadFetchWeather)
time.sleep(5)
# 时间1s更新刷屏
tim1 = Timer(1)
tim1.init(period=1000, mode=Timer.PERIODIC, callback=threadShowOled)
while True:
pass
代码目录结构:
完整代码请参考上一篇博客
成果展示:
MicroPython+ESP32+SSD1306 IIC OLED显示天气时钟
参考:
MicroPython开发手册