* 项目介绍:
非常高兴能幸运地进入第三轮比赛,本轮比赛我收到的盲盒器材是气象仪,自己手头有行空板,没有SCI采集模块,所以赶紧又购买了一块SCI采集模块。根据以上器材情况,经过许多天的冥思苦想,以下是本项目设计之初的一些设想(脑洞)
1.充分利用和挖掘MIND+1.8版本中新增的可视化面板的功能。设计一个充满现代科技感的可视化物联网大屏,并在上面实时显示各种数据和图像。
2. 使用语音合成模块,为可视化的气象数据提供语音播报功能,可方便视力有障碍的同学。
3.根据校园气象站的传感器数据进行校园安全预警。比如提供高温预警,提醒老师和同学们不要中暑,在高温时自动或手动打开空调(风扇)。
4.使用超声波传感器或人体热释电传感器,当检测有人靠近时,自动播放一些介绍性的语音。
5.使用摄像头进行人脸检测,如果检测为已录入的人脸数据,则播放相应的欢迎语句并自动打开门禁(通过舵机转动模拟)。
6.使用心率传感器为用户检测心率的数据。
7. 跨领域的融合:将气象站的数据与校园其他设施的数据进行整合和分析,例如食堂的菜品供应、体育场馆的运动强度等等。这样做可以帮助校方更好地了解校园内的天气情况和影响,并且为学生提供更具针对性的建议和服务。
8.考虑到校园微型气象站的目标受众主要是学生,尝试添加一些趣味性的元素,例如将气象站的数据转换成一段音乐或者一幅画作,让学生可以通过艺术形式来感知当天的天气情况。
项目背景:
随着物联网技术和人工智能的快速发展,越来越多的学校开始引入智能化的设备来改善校园环境和学习体验。校园微型气象站作为其中之一,不仅可以提供实时的气象数据,而且可以帮助学生更好地了解天气变化,提高安全意识。但是,由于传统的气象站数据显示不够直观,难以吸引学生的兴趣。因此,我利用MIND+新版的可视化面板设计了一个可视化校园微型气象站的物联网应用,通过图表、动态图像等形式呈现气象数据,使得学生更容易理解和接受。此外,我还尝试在应用中增加互动元素,如利用语音合成模块对气象数据进行播报,根据光线亮度自动开启灯光(路灯),手动打开风扇,利用摄像头进行人脸识别打开门禁等,进一步增强学生的学习兴趣。
遇到的问题:
1.经过实地测试以后发现,我的想法很美好,但实现起来并不容易。我发现SCI采集模块不支持超声波传感器和心率传感器,或者是由于我的SCI采集模块固件的原因,总之没有测试成功。
2.语音合成模块经过使用发现,有时候会有突然不能播放语音的情况,感觉不够稳定,也可能是程序的问题。
3.摄像头人脸识别的功能由于时间限制和技术水平不够,也未能实现。
4.跨领域融合方面的应用仅有想法,但也未能实现。
* 制作过程:创意实现的过程、步骤,以及在此过程中发现的问题 ;
1.连接行空板等相关硬件,如图所示。
在连接过程中发现行空板I2C的接口数量不够用,我又购买了一块Gravity: I2C分线模块经过测试以后,完美解决了这一问题。
2.在行空板SIot2.0服务中添加相关的主题。
3.编写程序并进行调试。
作品演示:
1.可视化面板效果展示
2.效果演示视频。
* 总结:
在本项目的制作过程中,我有了许多新的收获,在脑洞大开的过程中,体验了一回把脑洞变为现实的艰难过程,但同时也是获得感和成就感满满,非常感谢主办方提供的这次物联网比赛活动。通过三轮比赛,使我熟悉了SCI采集模块和气象仪的用法,也掌握了新版MIND+中的可视化面板的神奇功能。配合SIOT,使我们很轻松的就可以制作一个具有实用价值的充满科技感的可视化物联网屏幕并能实现互动。
通过本项目的制作,我也再次发现了自己的一些技术方面的短板,前期尽顾着挖空心思想脑洞了,临近比赛截止时间了,可是工作又开始忙碌了起来,制作项目的时间上不能充分的保证了。另外,由于这次我没有购买空气质量传感器和PM2.5等传感器。所以可视化面板上可以展示的项目数量相对于第二轮比赛来说有些简单。另外,许多脑洞和想法仅仅还停留在设想的阶段,一方面是器材所限,另一方面也是技术水平所限。比如通过摄像头对人脸进行识别来控制门禁,虽然手头有二哈,但我想尝试用人工智能的算法和模型来实现,但仅此一项就又是一项崭新的课题,直到比赛时间快截止了,也还是没有个完整的头绪。行空板上的许多功能还没有充分的利用和挖掘出来,我的python的编程还处于菜鸟阶段,需要在以后多加以学习。
* 资源:代码+源文件。
附件
# -*- coding: UTF-8 -*-
# MindPlus
# Python
from pinpong.libs.dfrobot_speech_synthesis import DFRobot_SpeechSynthesis_I2C
import base64
from io import BytesIO
from PIL import Image
from pinpong.extension.unihiker import *
from pinpong.board import Board,Pin
from DFRobot_Atmospherlum import *
from pinpong.board import Board
import siot
import cv2
# 自定义函数
def BoBaoTianQi():
p_gravitysynthesis.speak((str("当前风速") + str((str((yunque_i2c.get_value("speed"))) + str((yunque_i2c.get_unit("speed")))))))
p_gravitysynthesis.speak((str("当前风向是") + str((str(({ 'N': '北', 'NE': '东北', 'E': '东', 'SE': '东南','S': '南', 'SW': '西南','NW': '西南', 'W': '西', 'NW': '西北', }[(yunque_i2c.get_value("dir"))])) + str("风")))))
p_gravitysynthesis.speak((str("当前温度") + str((str((yunque_i2c.get_value("Temp"))) + str((yunque_i2c.get_unit("Temp")))))))
p_gravitysynthesis.speak((str("当前湿度") + str((str((yunque_i2c.get_value("Humi"))) + str((yunque_i2c.get_unit("Humi")))))))
p_gravitysynthesis.speak((str("当前气压") + str((str((yunque_i2c.get_value("Pressure"))) + str((yunque_i2c.get_unit("Pressure")))))))
# 事件回调函数
def on_message_callback(client, userdata, msg):
if (msg.payload.decode() == "5"):
BoBaoTianQi()
if (msg.payload.decode() == "1"):
p_p21_out=Pin(Pin.P21, Pin.OUT)
p_p21_out.write_digital(1)
if (msg.payload.decode() == "2"):
p_p21_out=Pin(Pin.P21, Pin.OUT)
p_p21_out.write_digital(0)
if (msg.payload.decode() == "3"):
p_p23_out=Pin(Pin.P23, Pin.OUT)
p_p23_out.write_digital(1)
if (msg.payload.decode() == "4"):
p_p23_out=Pin(Pin.P23, Pin.OUT)
p_p23_out.write_digital(0)
Board().begin()
siot.init(client_id="6524173421102182",server="10.1.2.3",port=1883,user="siot",password="dfrobot")
siot.connect()
siot.loop()
siot.set_callback(on_message_callback)
def frame2base64(frame):
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame) #将每一帧转为Image
output_buffer = BytesIO() #创建一个BytesIO
img.save(output_buffer, format='JPEG') #写入output_buffer
byte_data = output_buffer.getvalue() #在内存中读取
base64_data = base64.b64encode(byte_data) #转为BASE64
return base64_data #转码成功 返回base64编码
def base642base64(frame):
data=str('data:image/png;base64,')
base64data = str(frame2base64(frame))
framedata = base64data[2:(len(base64data)-1)]
base642base64_data = data + str(framedata)
return base642base64_data
vd = cv2.VideoCapture()
vd.open(0)
while not (vd.isOpened()):
print("摄像头初始化成功!")
yunque_i2c = DFRobot_Atmospherlum_I2C(0x42)
while (yunque_i2c.begin() != 0):
print("yunque_i2c initialize failed!!")
time.sleep(1)
print("Sensor initialize success!!")
yunque_i2c.set_local_time()
time.sleep(1)
p_gravitysynthesis = DFRobot_SpeechSynthesis_I2C()
p_gravitysynthesis.begin(p_gravitysynthesis.V2)
siot.getsubscribe(topic="siot/风速")
siot.getsubscribe(topic="siot/风速")
siot.getsubscribe(topic="siot/风向")
siot.getsubscribe(topic="siot/温度")
siot.getsubscribe(topic="siot/湿度")
siot.getsubscribe(topic="siot/气压")
siot.getsubscribe(topic="siot/摄像头")
siot.getsubscribe(topic="siot/音量")
siot.getsubscribe(topic="siot/光线")
siot.getsubscribe(topic="siot/灯光")
siot.getsubscribe(topic="siot/语音")
while True:
if vd.grab():
ret, grab = vd.read()
siot.publish(topic="siot/摄像头", data=base642base64(grab))
else:
print("没有下一帧")
siot.publish_save(topic="siot/风速", data=(str((yunque_i2c.get_value("speed"))) + str((yunque_i2c.get_unit("speed")))))
siot.publish_save(topic="siot/风向", data=({ 'N': '北', 'NE': '东北', 'E': '东', 'SE': '东南','S': '南', 'SW': '西南','NW': '西南', 'W': '西', 'NW': '西北', }[(yunque_i2c.get_value("dir"))]))
siot.publish_save(topic="siot/温度", data=(yunque_i2c.get_value("Temp")))
siot.publish_save(topic="siot/湿度", data=(yunque_i2c.get_value("Humi")))
siot.publish_save(topic="siot/气压", data=(yunque_i2c.get_value("Pressure")))
hacker_2023.08.28
666