步骤1 项目背景
项目名称:高考倒计时
项目用途:TM1650 显示倒计时天数,TM1637 显示当前时间,OLED显示气象信息、励志鸡汤、室内外温度。备战高考,实时了解天气及室内外温度情况,用倒计时督促自己珍惜时间,励志鸡汤鼓励自己!
项目背景:外甥女马上中考了,但是我觉得这只是一个小考,再过三年的高考才是你真正的挑战。高考倒计时三年,珍惜时间,加油。舅舅相信你是最棒的!
步骤2 制作过程
1、外观制作:用1mm厚卡纸制作外观,就叫“高考倒计时树”吧。自己画的,水彩笔涂色,美工刀开孔。
二、整体结构:用虚谷号作为中继站,虚谷号爬取网络信息,通过siot发送至esp8266,由esp8266作为终端进行相关信息显示。
三、电路连接:主控使用esp8266,使用两种型号的四位数码管,还有OLED屏。用面包板、杜邦线将主控与其它设备连接。
温湿度:P0;
OLED和TM1650四位数码管和:IIC;
四位数码管TM1637 :CLK-P14,DIO-12;
四、程序编写:终端esp8266使用图形化mixly进行程序编写,虚谷号使用python进行程序编写,程序如下:
import siot
import time
import json
import requests
from threading import Timer #threading 模块中的 Timer 是一个非阻塞函数
import sched
from lxml import etree
import datetime
SERVER = "127.0.0.1" #MQTT服务器IP
CLIENT_ID = "" #在SIoT上,CLIENT_ID可以留空
IOT_pubTopic_time = 'qyj/time' #“topic”为“项目名称/设备名称”
IOT_pubTopic_day_weather = 'qyj/day_weather'
IOT_pubTopic_day_temperature = 'qyj/day_temperature'
IOT_pubTopic_day_wind = 'qyj/day_wind'
IOT_pubTopic_count_down = 'qyj/count_down'
IOT_pubTopic_jitang = 'qyj/jitang'
IOT_pubTopic_translation = 'qyj/translation'
IOT_UserName ='scope' #用户名
IOT_PassWord ='scope' #密码
siot.init(CLIENT_ID, SERVER, user=IOT_UserName, password=IOT_PassWord)
siot.connect()
siot.loop()
# 初始化sched模块的 scheduler 类
# 第一个参数是一个可以返回时间戳的函数,第二个参数可以在定时未到达之前阻塞。
schedule = sched.scheduler(time.time, time.sleep)
# 被周期性调度触发的函数
def netSiot(inc):
time, count_down, day_weather, day_temperature, day_wind, jitang, translation = new_bata()
# siot写入外网数据,写入前刷新数据
siot.publish(IOT_pubTopic_day_weather, day_weather)
siot.publish(IOT_pubTopic_day_temperature, day_temperature)
siot.publish(IOT_pubTopic_day_wind, day_wind)
siot.publish(IOT_pubTopic_time, time)
siot.publish(IOT_pubTopic_count_down, count_down)
siot.publish(IOT_pubTopic_jitang, jitang)
siot.publish(IOT_pubTopic_translation, translation)
schedule.enter(inc, 0, netSiot, (inc,))
#
def mainTime(inc):
# enter四个参数分别为:间隔事件、优先级(用于同时间到达的两个事件同时执行时定序)、被调用触发的函数,
# 给该触发函数的参数(tuple形式)
schedule.enter(0, 0, netSiot, (inc,))
schedule.run()
# 获取日期和倒计时
def get_time():
a = datetime.datetime.now() # 实施时间
y = str(a.year)
m = str(a.month)
d = str(a.day) # 转换为字符串,便于打印
time = m + '月' + d + '日 '
b = datetime.datetime(2022, 6, 7) # 自己设置的高考时间
count_down = (b - a).days # 高考倒计时
return time, count_down
# 获取白银当日天气情况
def get_weather():
url = 'http://www.weather.com.cn/weather/101161301.shtml'
response = requests.get(url)
response.encoding = 'utf-8'
response = response.text # 获取页面
html = etree.HTML(response)
day_weather = html.xpath('//*[@id="7d"]/ul/li[1]/p[1]/text()')[0] + ' '# 获取天气,白天的天气
high = html.xpath('//*[@id="7d"]/ul/li[1]/p[2]/span/text()')
low = html.xpath('//*[@id="7d"]/ul/li[1]/p[2]/i/text()') # 获取对应的两个温度
# 因为页面在晚上会有小变化,所以使用条件语句,来排除因变化引起的bug
if high == []:
day_temperature = low[0] + ' '
else:
day_temperature = low[0].replace('℃', '') + '~' + high[0] + ' ' # 获取温度
# 获取两个风向
wind_1 = html.xpath('//*[@id="7d"]/ul/li[1]/p[3]/em/span[1]/@title')
wind_2 = html.xpath('//*[@id="7d"]/ul/li[1]/p[3]/em/span[2]/@title')
# 因为有时候,会出现两个风向是同一个风向的情况,所以使用条件语句排除
if wind_2 == []:
wind = wind_1[0] + ' '
elif wind_1[0] == wind_2[0]:
wind = wind_1[0] + ' '
else:
wind = wind_1[0] + '转' + wind_2[0] + ' '
# 因为风级有时候会出现“<",语音的时候会认为是爱心符号,所以使用替换,改为文字”低于“
wind_3 = html.xpath('//*[@id="7d"]/ul/li[1]/p[3]/i/text()')[0].replace('<', '低于').replace('>', '高于')
day_wind = wind + wind_3 # 获取风向及风级
return day_weather, day_temperature, day_wind
# 获取每日鸡汤
def get_content():
url = 'http://open.iciba.com/dsapi/' # 网上找的API
response = requests.get(url=url)
json_s = json.loads(response.text)
jitang = json_s.get("content") # 每日鸡汤
translation = json_s.get("note")# 中文翻译
return jitang, translation
# 数据更新
def new_bata():
time, count_down = get_time()
day_weather, day_temperature, day_wind = get_weather()
jitang, translation = get_content()
print(time, count_down, day_weather, day_temperature, day_wind, jitang, translation)
return time, count_down, day_weather, day_temperature, day_wind, jitang, translation
def main():
# 600s 输出一次(获取最新天气信息)
mainTime(600)
if __name__ == "__main__":
main()
五、作品组装:使用胶枪将画好的硬卡纸进行连接,并固定在面包板上。
步骤3 作品演示
步骤4 总结
“高考倒计时”可能是很多人会想到的一个项目,本作品外形简单,只使用卡纸、面板版、杜邦线,但是最终效果也很漂亮(个人觉得,哈哈哈),所以复制性很强。
当然,该项目如果不使用虚谷号,只使用esp8266也可以实现同样的功能(之前使用esp8266的一个项目https://makelog.dfrobot.com.cn/article-309897.html)。使用虚谷号的目的是拓展一种思路,并不是所有你想要的功能esp8266都可以完成,所以这种使用虚谷号作为中继的思路个人觉得还是挺好,虚谷号的算力还是很强大的。
该作品实现了最初计划的所有功能,可复制、可拓展。
步骤5 附件源码
附件
虾虾^0^2021.08.11
好
虾虾^0^2021.08.11
好