【得捷电子Follow me第2期】+补充作业:任务4增强版之整点报时像素时钟
[复制链接]
本来所有作业都提交完了,但是最近买的一块16*16的像素屏到货啦,赶上中秋、国庆小长假有时间,就结合一并购买的语音模块DFR0745,在原来任务4-1基础上做了一个整点报时像素时钟,下面 详细介绍制作过程。
首先介绍像素屏。该屏幕分辨率为16*16点阵,采用WS2812B串行连接,蛇形排布,只需一个IO口就能驱动。实际使用中,首先是在控制器内存中开辟一个缓存区,将要显示的内容写入缓存,然后按照灯珠串行顺序将数据取出挨个送入IO口,即可显示对应内容。我买到的像素屏实物如下图片。
然后介绍语音模块DFR0745。此语音模块由DFRobot设计,支持Arduino、AT指令、板载按键和ADC按键四种控制方式。通过板载按键即使在没有微控制器的情况下也能进行录放音。模块支持多段语音录制,并且模块搭载了16MB的存储空间,可以录制大约40分钟的声音。通过USB线您可以很容易的将模块中的录音拷贝到电脑上。实物图如下。
电路连接如下图,语音模块电源接Feather主板USB引入的5V电源。TX、RX交叉相连。像素屏数据口接Feather主板的D5引脚。由于像素屏功率比较大,电源需要单独供电。
像素屏驱动,这个页面提供了非常详细的教程,我在此不再赘述。
https://learn.adafruit.com/easy-neopixel-graphics-with-the-circuitpython-pixel-framebuf-library/overview
关于时钟界面,我设计如下图。
由于像素有限,每行只能放3个字符,共两行。我就将整个屏幕分成4个区,左上2个字符显示小时,左下2个字符显示分钟。中间横线表示秒闪烁。最右侧选取了4*15共60个点用于计数读秒,每秒增加一个点。4个分区用3种颜色区分开,方便观看。
像素屏点亮时比较刺眼,我在上面罩了一层白纸,感觉看起来比较舒服。下图是在几种情况下的显示效果,最终我觉的在灯光且加罩的情况下比较好,后续测试均在此情况进行。
时钟调试完成后的显示效果如下视频。
004-像素钟显示效果
视频1、时钟显示
为了实现语音报时,我从网上找了整点报时语音素材,然后使用GoldWave处理成MP3格式,按照DFR0745模块的文件命名规则改了名称,在程序中就可以直接输入整点时间调用对应声音文件。
为了展示语音报时效果,我设计了一个测试程序,如下代码。
代码1
import time
import board
import busio
uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=0)
uart.write(b"AT+VOL=0\r\n")
print("AT+VOL=0\r\n")
time.sleep(2)
uart.write(b"AT+FUNCTION=1\r\n")
print("AT+FUNCTION=1\r\n")
time.sleep(3)
uart.write(b"AT+VOL=25\r\n")
print("AT+VOL=25\r\n")
time.sleep(2)
def voice_nowtime(v_hour):
uart.write(b"AT+PLAYFILE={:02}\r\n".format(v_hour))
print("AT+PLAYFILE={:02}\r\n".format(v_hour))
###################################################################################
import neopixel
from adafruit_pixel_framebuf import PixelFramebuffer
pixel_pin = board.D5
pixel_width = 16
pixel_height = 16
pixels = neopixel.NeoPixel(
pixel_pin,
pixel_width * pixel_height,
brightness=0.1,
auto_write=False,
)
pixel_framebuf = PixelFramebuffer(
pixels,
pixel_width,
pixel_height,
reverse_x=True,
)
text1 = "08"
text2 = "58"
hour_cunt = 0
def pixel_clock(p_hour,p_min,p_sec):
text1 = "{:02}".format(p_hour)
text2 = "{:02}".format(p_min)
pixel_framebuf.fill(0)
pixel_framebuf.text(text1, 0, 0, 0x00FF00)
pixel_framebuf.text(text2, 0, 8, 0x00FF00)
lie_a = int(p_sec / 15)
lie_b = p_sec % 15
pixel_framebuf.fill_rect(12, 0, lie_a, 15, 0xFF0000)
pixel_framebuf.line(12+lie_a, 0, 12+lie_a, lie_b, 0xFF0000)
pixel_framebuf.line(0, 7, 10, 7, 0x0000FF if p_sec % 2 else 0x000000)
pixel_framebuf.display()
min_cunt = 0
hour_cunt = 15
last_hour = 0
while True:
time.sleep(0.05)
min_cunt += 1
if(min_cunt == 59):
min_cunt = 0
hour_cunt += 1
if(hour_cunt>23):
hour_cunt = 0
if(last_hour != hour_cunt):
last_hour = hour_cunt
voice_nowtime(hour_cunt)
pixel_clock(hour_cunt, min_cunt, min_cunt)
语音报时效果演示视频。
005-报时演示
视频2、语音报时
将显示、语音报时、天气时钟所有代码整合到一起,最终的代码如下。
代码2
import board
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
display = board.DISPLAY
board.DISPLAY.brightness = 0.5
board.DISPLAY.rotation = 0
str_disp = "天气时钟"
font = bitmap_font.load_font("opposans_m_12.pcf")
color = 0xE60000
text_area = label.Label(font, text=str_disp, color=color)
text_area.x = 93
text_area.y = 62
display.show(text_area)
##连接wifi --------------------------------------------------------------------------------------
import wifi
wifi.radio.connect('xxxxxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxx')
print(f"My IP address: {wifi.radio.ipv4_address}")
## END连接wifi --------------------------------------------------------------------------------------
#获取时间
import rtc
import adafruit_ntp
import socketpool
import time
#https://learn.adafruit.com/super-simple-sunrise-lamp/code
print("Fetching time from NTP.")
pool = socketpool.SocketPool(wifi.radio)
ntp = adafruit_ntp.NTP(pool, server="ntp.aliyun.com", tz_offset=8)
rtc.RTC().datetime = ntp.datetime
now = time.localtime()
print("Current time:\n{}-{}-{}\n{:2}:{:02}".format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min))
#-------------------------
str_tm = "{}-{}-{} {:2}:{:02}".format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min)
color = 0xF60000
text_tm = label.Label(font, text=str_tm, color=color)
text_tm.x = 10
text_tm.y = 20
display.show(text_tm)
##############################################
temp_str = "25.0"
humi_str = "88%"
str_city = "天街"
str_weather = "晴"
## 访问网络 --------------------------------------------------------------------------------------
import ssl
import socketpool
import adafruit_requests
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
## END访问网络 --------------------------------------------------------------------------------------
# 请求获取IP
## api http://ip.42.pl/raw
JSON_IP_URL = "http://ip.42.pl/raw"
response = requests.get(JSON_IP_URL)
ip_str = response.text
print(ip_str)
# 获取城市编码
str_data = 'https://restapi.amap.com/v3/ip?ip='+ip_str+'&output=JSON&key=xxxxxxxxxxxxxxxxxxxxxxxx'
city = requests.get(str_data)
print(city.json())
city_str = city.json()
adcode = city_str["adcode"]
print(adcode)
#获取天气
response = requests.get('https://restapi.amap.com/v3/weather/weatherInfo?key=xxxxxxxxxxxxxxxxxxxxxxxx&city='+adcode)
weather = response.json()
print(weather)
temp_str = weather["lives"][0]["temperature_float"]
humi_str = weather["lives"][0]["humidity_float"]
str_city = weather["lives"][0]["city"]
str_weather = weather["lives"][0]["weather"]
print(temp_str + '\n' + humi_str + '\n' + str_city + '\n' + str_weather)
#-------------------------
str_tq = str_tm + '\n' + str_city + ' '+ str_weather + '\n' + '温度:' + temp_str + '`C' + '\n' + '湿度:' + humi_str+ '%'
color = 0xF60000
text_tq = label.Label(font, text=str_tq, color=color)
text_tq.x = 10
text_tq.y = 20
display.show(text_tq)
###################################################################################
import busio
uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=0)
uart.write(b"AT+VOL=0\r\n")
print("AT+VOL=0\r\n")
time.sleep(2)
uart.write(b"AT+FUNCTION=1\r\n")
print("AT+FUNCTION=1\r\n")
time.sleep(3)
uart.write(b"AT+VOL=25\r\n")
print("AT+VOL=25\r\n")
time.sleep(2)
def voice_nowtime(v_hour):
uart.write(b"AT+PLAYFILE={:02}\r\n".format(v_hour))
print("AT+PLAYFILE={:02}\r\n".format(v_hour))
###################################################################################
import neopixel
from adafruit_pixel_framebuf import PixelFramebuffer
pixel_pin = board.D5
pixel_width = 16
pixel_height = 16
pixels = neopixel.NeoPixel(
pixel_pin,
pixel_width * pixel_height,
brightness=0.1,
auto_write=False,
)
pixel_framebuf = PixelFramebuffer(
pixels,
pixel_width,
pixel_height,
reverse_x=True,
)
text1 = "08"
text2 = "58"
# hour_cunt = 0
def pixel_clock(p_hour,p_min,p_sec):
text1 = "{:02}".format(p_hour)
text2 = "{:02}".format(p_min)
pixel_framebuf.fill(0)
pixel_framebuf.text(text1, 0, 0, 0x00FF00)
pixel_framebuf.text(text2, 0, 8, 0x00FF00)
lie_a = int(p_sec / 15)
lie_b = p_sec % 15
pixel_framebuf.fill_rect(12, 0, lie_a, 15, 0xFF0000)
pixel_framebuf.line(12+lie_a, 0, 12+lie_a, lie_b, 0xFF0000)
pixel_framebuf.line(0, 7, 10, 7, 0x0000FF if p_sec % 2 else 0x000000)
pixel_framebuf.display()
last_sec = 0
last_hour = 0
while True:
time.sleep(0.1)
now = time.localtime()
if(last_sec != now.tm_sec):
last_sec = now.tm_sec
str_tm = "{}-{}-{} {:2}:{:02}:{:02}".format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
text_tq.text = str_tm + '\n' + str_city + ' '+ str_weather + '\n' + '温度:' + temp_str + '`C' + '\n' + '湿度:' + humi_str+ '%'
print(str_tm)
pixel_clock(now.tm_hour, now.tm_min, now.tm_sec)
if(last_hour != now.tm_hour):
last_hour = now.tm_hour
voice_nowtime(last_hour)
最终完成作品效果如下。
ok
视频3、整点报时像素时钟
此作业是对本次任务的一个补充,基本上将任务4的分任务1、2、4都涉及到了,虽然不是百分百扣题,但是也有自己的特色,总之开心就好,祝大家节日快乐。
|