上一帖介绍FireBeetle 2ESP32-S3开发板的开箱情况和搭建Arduino开发环境,然后测试了各个硬件,确认都是好用的。这一贴介绍搭建MicroPython开发环境,并在此基础上设计一个天气时钟。本次作品要实现的功能: a、使用固定网站获取公网IP地址,使用高德接口通过IP地址定位城市。
b、利用获得的城市信息通过高德API查询天气信息并显示在OLED屏幕上。
c、通过网络NTP服务校准时钟,并在OLED屏幕上显示实时时钟。
OLED屏幕选用的是以前做实验存货,规格为I2C接口128*64点阵单色屏。我做了一根转接线,将屏幕连接到开发板,实物图如下。
图1、连线实物 程序是在以前做过的实验基础上修改的。在此简单介绍一下。
首先是获取天气。连接http://ip.42.pl/raw可以获取公网IP地址,然后利用高德IP定位服务获取城市代码,接下来再使用城市代码通过高德天气预报接口获取天气信息。高德API相关服务需要申请密钥,都是免费的,只是每天有连接次数限制,足够测试用。高德接口链接如下:
天气查询
https://lbs.amap.com/api/webservice/guide/api/weatherinfo
IP定位服务
https://lbs.amap.com/api/webservice/guide/api/ipconfig
在程序中,我主要获取了城市名称,天气信息,温度和湿度这四个参数,最终显示在OLED屏幕上。
接下来介绍获取UTC8时间,即北京时间。我发现使用官方库文件ntptime.py不管怎么设置,获取到的时间都是UTC0时间,不能设置成UTC8的时间,为了解决此问题,我修改了ntptime.py这个文件,在最后返回的数值基础上加了8小时,如下代码,另存为ntptime8.py,再放到开发板根目录,这样调用ntptime8.settime()校准时间,就是UTC8了。
为了能在OLED屏幕上显示汉字和符号,我这里又添加一个ufont的字库,实现汉字和特殊字符显示,比如温度单位“℃”这个字符,MicroPython的framebuf默认ascii库中就不包含,只会显示乱码。Ufont库链接如下。
https://github.com/AntonVanke/MicroPython-uFont
程序调试好后,Thonny的截图如下,设备窗口是我添加的库文件。RPEL窗口显示的是从网络获取的地点、天气、时间信息。
图2、Thonny调试结果 程序运行后OLED显示效果如下图。
图3、OLED显示效果 整体代码如下。
- import network
- import socket
- import machine
- import ubinascii
- import urequests
- import ujson
- import time
- import ntptime8
- import random
- from ssd1306 import SSD1306_I2C
- import ufont
- from machine import Pin,I2C
- from machine import RTC
- TEMP = "25"
- HUMI = "55"
- CITY = "天街"
- WEATH = "晴"
- ssid = 'ssid '
- password = 'password'
- led = machine.Pin(21,machine.Pin.OUT)
- i2c = I2C(0, scl=Pin(2), sda=Pin(1), freq=400000)
- display = SSD1306_I2C(128, 64, i2c)
- display.fill(0)
- font = ufont.BMFont("unifont-14-12917-16.v3.bmf")
- font.text(display, "天气时钟", 32, 15, show=True)
- font.text(display, "Loading...", 24, 35, show=True)
- wlan = network.WLAN(network.STA_IF)
- wlan.active(True)
- if not wlan.isconnected():
- print('connecting to network...')
- wlan.connect(ssid, password)
- while not wlan.isconnected():
- pass
- print('network config:', wlan.ifconfig())
- status = wlan.ifconfig()
- print( 'ip = ' + status[0] )
- ntptime8.host = 'ntp1.aliyun.com' # 可选,ntp服务器,默认是"pool.ntp.org"
- ntptime8.settime() # 修改设备时间,到这就已经设置好了
- print('NTP OK')
-
- def open_socket():
- ip = urequests.get('http://ip.42.pl/raw')
-
- ip_str = ip.content.decode('ascii')
- print(ip_str)
- ip.close()
-
- str_data = 'https://restapi.amap.com/v3/ip?ip='+ip_str+'&output=JSON&key=xxxxxxxxxxxxxxx-you-key-xxxxxxxxxxxxxxxx'
- city = urequests.get(str_data)
-
- city_str = city.content.decode('ascii')
- #print(city_str)
- parsed_city = ujson.loads(city_str)
-
- adcode = parsed_city["adcode"]
- city.close()
- r = urequests.get('https://restapi.amap.com/v3/weather/weatherInfo?key=xxxxxxxxxxxxxxx-you-key-xxxxxxxxxxxxxxxx&city='+adcode)
- w_str = r.content.decode('ascii')
- # print(r.text)
- #print('111:'+ w_str)
- parsed_w = ujson.loads(w_str)
- # print (parsed_w)
- #w_f = parsed_w["temperature"]
- temp_str = parsed_w["lives"][0]["temperature_float"]
- humi_str = parsed_w["lives"][0]["humidity_float"]
- str_city = parsed_w["lives"][0]["city"]
- str_weather = parsed_w["lives"][0]["weather"]
-
- global TEMP
- TEMP = temp_str
- global HUMI
- HUMI = humi_str
- global CITY
- CITY = str_city
- global WEATH
- WEATH = str_weather
- print (str_city)
- print (str_weather)
- print (temp_str)
- print (humi_str)
- r.close()
- try:
- open_socket()
- time.sleep(0.1)
- display.fill(0)
- TEMP_disp = "城市:"+CITY
- font.text(display, TEMP_disp, 0, 0*16, show=True)
- TEMP_disp = "天气:"+WEATH
- font.text(display, TEMP_disp, 0, 1*16, show=True)
- TEMP_disp = "T:"+TEMP+"℃"+"H:"+HUMI+"%"
- font.text(display, TEMP_disp, 0, 2*16, show=True)
- # TEMP_disp = "21:22:33"
- # font.text(display, TEMP_disp, 0, 3*16, show=True)
- except KeyboardInterrupt:
- machine.reset()
- while True:
- time.sleep(1)
- rtc = RTC()
- # print(rtc.datetime())
- display.rect(0,3*16,8*8,16,0,True)
- TEMP_disp = "%02d:%02d:%02d" % (rtc.datetime()[4],rtc.datetime()[5],rtc.datetime()[6])
- font.text(display, TEMP_disp, 0, 3*16, show=True)
复制代码
展示视频如下。
004
|