在前一篇測試中我們已經掌握如何利用 MicroPython 內建的 framebuf 模組將圖片的 bytearray 資料存入顯示緩衝器後顯示於 SSD1306 OLED 螢幕上, 本篇則是要從 OpenWeatherMap 每 60 秒抓取一次氣象資料, 然後以圖片方式顯示於 SSD1306 上. 氣象爬蟲做法參考 :
本系列之前的文章參考 :
4. 以圖片方式顯示 OpenWeatherMap 氣象資訊 :
在 "MicroPython 學習筆記 : 用 SSD1306 顯示氣象資訊 (一)" 這篇測試中我們已將 OpenWeatherMap 氣象資料爬蟲寫成如下之 get_weather() 函式 :
def get_weather(country, city, api_key):
url=f'https://api.openweathermap.org/data/2.5/weather?q={city},{country}&units=metric&lang=zh_tw&appid={api_key}'
try:
res=urequests.get(url)
data=ujson.loads(res.text)
if data['cod']==200: # 注意是數值
ret={'geocode': data['id'],
'icon': data['weather'][0]['icon'],
'temperature': data['main']['temp'],
'pressure': data['main']['pressure'],
'humidity': data['main']['humidity']}
return ret
else:
return None
except Exception as e:
return None
首先將 SSID 與密碼以及 OpenWeatherMap API key 寫在 config.py 中, 匯入要用到的模組 :
>>> import config
>>> import xtools
>>> import urequests
>>> import ujson
>>> import ssd1306
>>> import big_symbol
連上網路 :
>>> ip=xtools.connect_wifi(config.SSID, config.PASSWORD)
Connecting to network...
network config: ('192.168.192.189', '255.255.255.0', '192.168.192.92', '192.168.192.92')
設定 get_weather() 需要的參數後呼叫它就會傳回現在的溫濕度與氣壓等資料 :
>>> weather_api_key=config.WEATHER_API_KEY
>>> city='Kaohsiung'
>>> country='TW'
>>> data=get_weather(country, city, weather_api_key)
>>> data
{'icon': '03d', 'temperature': 27.88, 'geocode': 1673820, 'pressure': 1014, 'humidity': 88}
接下來就可以用 big_symbol 模組的 Symbol 物件將這些氣象資料以較大尺寸的圖片顯示至 SSD1306 上. 先建立 SSD1306_I2C 物件 oled :
>>> i2c=I2C(0, scl=Pin(22), sda=Pin(21)) # 建立 I2C 物件 (ESP32)
>>> oled=ssd1306.SSD1306_I2C(128, 64, i2c) # 建立 SSD1306_I2C 物件
>>> sb=big_symbol.Symbol(oled) # 建立 Symbol 物件
先清除螢幕 :
>>> sb.clear()
呼叫 Symbol 物件的 temp() 方法顯示溫度像素圖 :
>>> sb.temp(0, 0)
>>> oled.show()
顯示 get_weather() 傳回的溫度於溫度像素圖後面 :
>>> sb.text(f"{data['temperature']}c", 32, 0)
>>> oled.show()
接下來呼叫 Symbol 物件的 temp() 方法顯示濕度像素圖 :
>>> sb.humid(0, 16)
>>> oled.show()
顯示 get_weather() 傳回的溼度於濕度像素圖後面 :
>>> sb.text(f"{data['humidity']}%", 32, 16)
>>> oled.show()
然後是顯示氣壓 :
>>> sb.press(0, 32)
>>> sb.text(f"{data['pressure']}hPa", 32, 32)
>>> oled.show()
最後可用 ASCII 文字在座標 (0, 48) 位置顯示目前時間以及在座標 (0, 56) 顯示地點 :
>>> now=xtools.tw_now()
Querying NTP server and set RTC time ... OK.
>>> now
'2024-10-14 22:15:09'
>>> oled.text(now, 0, 48, 1)
>>> oled.text(city, 0, 56, 1)
>>> oled.show()
這樣就會在 OLED 上顯示氣象資料了 :
完整程式碼如下 :
import config
import xtools
import urequests
import ujson
from machine import I2C, Pin
import ssd1306
import big_symbol
def get_weather(country, city, api_key):
url=f'https://api.openweathermap.org/data/2.5/weather?q={city},{country}&units=metric&lang=zh_tw&appid={api_key}'
try:
res=urequests.get(url)
data=ujson.loads(res.text)
if data['cod']==200: # 注意是數值
ret={'geocode': data['id'],
'icon': data['weather'][0]['icon'],
'temperature': data['main']['temp'],
'pressure': data['main']['pressure'],
'humidity': data['main']['humidity']}
return ret
else:
return None
except Exception as e:
return None
ip=xtools.connect_wifi(config.SSID, config.PASSWORD)
weather_api_key=config.WEATHER_API_KEY
city='Kaohsiung'
country='TW'
data=get_weather(country, city, weather_api_key)
i2c=I2C(0, scl=Pin(22), sda=Pin(21))
oled=ssd1306.SSD1306_I2C(128, 64, i2c)
sb=big_symbol.Symbol(oled)
sb.clear()
sb.temp(0, 0)
sb.text(f"{data['temperature']}c", 32, 0)
sb.humid(0, 16)
sb.text(f"{data['humidity']}%", 32, 16)
sb.press(0, 32)
sb.text(f"{data['pressure']}hPa", 32, 32)
oled.text(city, 0, 56, 1)
now=xtools.tw_now()
oled.text(now, 0, 48, 1)
oled.show()
但上面的測試只是取得並顯示一筆資料而已, 我們的目標是要每分鐘更新最新氣象資料, 所以要用無窮迴圈來做, 程式碼如下 :
import config
import xtools
import urequests
import ujson
from machine import I2C, Pin
import ssd1306
import big_symbol
import time
def get_weather(country, city, api_key):
url=f'https://api.openweathermap.org/data/2.5/weather?q={city},{country}&units=metric&lang=zh_tw&appid={api_key}'
try:
res=urequests.get(url)
data=ujson.loads(res.text)
if data['cod']==200: # 注意是數值
ret={'geocode': data['id'],
'icon': data['weather'][0]['icon'],
'temperature': data['main']['temp'],
'pressure': data['main']['pressure'],
'humidity': data['main']['humidity']}
return ret
else:
return None
except Exception as e:
return None
ip=xtools.connect_wifi(config.SSID, config.PASSWORD)
if ip:
# 設定氣象爬蟲參數
weather_api_key=config.WEATHER_API_KEY
city='Kaohsiung'
country='TW'
# 建立 I2C 與 SSD1306_I2C 物件
i2c=I2C(0, scl=Pin(22), sda=Pin(21)) # ESP32 I2C
oled=ssd1306.SSD1306_I2C(128, 64, i2c)
sb=big_symbol.Symbol(oled)
while True: # 每分鐘抓一次更新 OLED 顯示器
data=get_weather(country, city, weather_api_key)
sb.clear()
sb.temp(0, 0)
sb.text(f"{data['temperature']}c", 32, 0)
sb.humid(0, 16)
sb.text(f"{data['humidity']}%", 32, 16)
sb.press(0, 32)
sb.text(f"{data['pressure']}hPa", 32, 32)
oled.text(xtools.tw_now(), 0, 48, 1)
oled.text(city, 0, 56, 1)
oled.show()
time.sleep(60)
else:
print('無法連線 WiFi')
這樣每分鐘就會刷新螢幕顯示最新的氣象資料了.
沒有留言:
張貼留言