【得捷电子Follow me第1期】任务3:同步网络时间
[复制链接]
本帖最后由 你家吃的 于 2023-5-1 14:29 编辑
主题:
学习network模块用法,掌握连接网络、查看网络参数等用法,实现通过网络同步系统时间。
搭配器件:Raspberry Pi Pico w开发板
每日最新的UF2固件文件:https://micropython.org/download/rp2-pico-w/
raspberry pi pico w板子上搭了个无线芯片CYW43439,通过spi接口与板子相接。这颗芯片支持802.11a/b/g/n,蓝牙 v5.2 + EDR。板子还不支持蓝牙1。下图可以看到引脚接线图来看,这个板子是没法支持了,硬件上蓝牙的线没拉上。
------------------------连接网络、查看网络参数
import network
import time
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('---', '---')
while not wlan.isconnected() and wlan.status() >= 0:
print("Waiting to connect:")
time.sleep(1)
print(wlan.ifconfig())
效果如下
------------------------实现一个简单的网络获取时间代码
import machine
import time
import ssd1306
import math
import ufont
import socket
import ujson
import network
led = machine.Pin("LED",machine.Pin.OUT)
i2c1 = machine.I2C(0, sda=machine.Pin("GP8"), scl=machine.Pin("GP9"), freq=400000)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('---','---')
print(wlan.ifconfig())
import urequests
r = urequests.get("https://api.seniverse.com/v3/weather/daily.json?key=SorklM7u-uR7sB3UR&location=dalian&language=zh-Hans&unit=c&start=-1&days=5")
e=r.text.encode('utf-8').decode("unicode_escape")
print(e)
parsed = ujson.loads(e)
res = parsed['results']
print(type(parsed))
print(type(res))
print("11111111 %s" % type(res[0]))
#内层
print(res[0]['location']['name'])
print(res[0]['daily'][0]['date'])
print(res[0]['daily'][0]['text_night'])
posi = res[0]['location']['name']
date = res[0]['daily'][0]['date']
ss = res[0]['daily'][0]['text_night']
display = ssd1306.SSD1306_I2C(128,64,i2c1)
font = ufont.BMFont("unifont-14-12917-16.v3.bmf")
font.text(display, "天气:", 0, 0, show=True)
font.text(display, "日期:", 0, 20, show=True)
font.text(display, "时间:", 0, 40, show=True)
showCl = '{0}.{1}'.format(posi,ss)
font.text(display, showCl, 40, 0, show=True)
font.text(display, date,40, 20, show=True)
#font.text(display,, 40, 40, show=True)
r.close()
#获取时间
while True:
r = urequests.get('http://quan.suning.com/getSysTime.do')
parsed = ujson.loads(r.text)
tm = (parsed['sysTime2']).split()[1]
display.rect(40,40,120,40,0,True)
font.text(display,tm, 40, 40, show=True)
time.sleep(.3)
led.on()
time.sleep(.3)
led.off()
通过知心天气接口得到天气的信息,返回的json数据如下,使用ujson模块解析这个数据结构:
{
"results":[
{
"location":{
"id":"WWYMRT0VRMUG",
"name":"大连",
"country":"CN",
"path":"大连,大连,辽宁,中国",
"timezone":"Asia/Shanghai",
"timezone_offset":"+08:00"
},
"daily":[
{
"date":"2023-05-01",
"text_day":"晴",
"code_day":"0",
"text_night":"多云",
"code_night":"4",
"high":"20",
"low":"10",
"rainfall":"0.00",
"precip":"0.00",
"wind_direction":"南",
"wind_direction_degree":"180",
"wind_speed":"32.8",
"wind_scale":"5",
"humidity":"65"
},
{
"date":"2023-05-02",
"text_day":"多云",
"code_day":"4",
"text_night":"晴",
"code_night":"1",
"high":"21",
"low":"12",
"rainfall":"0.00",
"precip":"0.00",
"wind_direction":"南",
"wind_direction_degree":"180",
"wind_speed":"43.3",
"wind_scale":"6",
"humidity":"65"
},
{
"date":"2023-05-03",
"text_day":"晴",
"code_day":"0",
"text_night":"多云",
"code_night":"4",
"high":"18",
"low":"12",
"rainfall":"0.00",
"precip":"0.00",
"wind_direction":"东南",
"wind_direction_degree":"135",
"wind_speed":"32.8",
"wind_scale":"5",
"humidity":"91"
}
],
"last_update":"2023-05-01T08:00:00+08:00"
}
]
}
通过http://quan.suning.com/getSysTime.do获取到时间
效果:
322_1682922096
语法小讲堂:
- ord() :返回一个字符的unicode码
- chr() :传入编码,返回一个字符
- print : print(' %s' % 'helloworld') print('{0} {1}' .format('hello','world'))
- ss.encode('utf-8').decode("unicode_escape") 把一个unicode编码转换为utf-8编码
- 三元表达式 exp1 if condition else exp2 : 如果condition成立,执行exp1,否则执行exp2
- super().__init__() :此方法是用来调用父类的初始化函数
- 父类调用子类的方法
ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) //实例化
SSD1306类里调用 SSD1306_I2C的write_cmd了等方法,百度一下,没啥结果。个人理解,是SSD1306_I2C类实例化,同时实例化父类SSD1306,再实例化FrameBuffer。结果就是实例化了三个类。最主要的是python语言的逻辑相信程序员,在父类调用子类方法的时候,子类一定定义了此方法,所以脚本解释的时候能够调用到。其实自始至终代码里只有一个实例。如果理解错误,当我乱讲,不过能够帮助理解这个语法。
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
# https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py
from micropython import const
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_IREF_SELECT = const(0xAD)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
self.buffer = bytearray(self.pages * self.width)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def init_display(self):
for cmd in (
SET_DISP, # display off
# address setting
SET_MEM_ADDR,
0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE, # start at line 0
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO,
self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET,
0x00,
SET_COM_PIN_CFG,
0x02 if self.width > 2 * self.height else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV,
0x80,
SET_PRECHARGE,
0x22 if self.external_vcc else 0xF1,
SET_VCOM_DESEL,
0x30, # 0.83*Vcc
# display
SET_CONTRAST,
0xFF, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
SET_IREF_SELECT,
0x30, # enable internal IREF during display on
# charge pump
SET_CHARGE_PUMP,
0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01, # display on
): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP)
def poweron(self):
self.write_cmd(SET_DISP | 0x01)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def rotate(self, rotate):
self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3))
self.write_cmd(SET_SEG_REMAP | (rotate & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width != 128:
# narrow displays use centred columns
col_offset = (128 - self.width) // 2
x0 += col_offset
x1 += col_offset
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
def clear(self):
self.fill(0)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
self.write_list = [b"\x40", None] # Co=0, D/C#=1
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.write_list[1] = buf
self.i2c.writevto(self.addr, self.write_list)
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
import time
self.res(1)
time.sleep_ms(1)
self.res(0)
time.sleep_ms(10)
self.res(1)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(buf)
self.cs(1)
补充内容 (2023-5-1 14:32):
测试
补充内容 (2023-5-1 14:46):
唉,为啥发了帖子,就不允许修改呢
|