「行空板Python入门教程」第九课-智慧农业物联网系统2
5G元年的列车早已驶出,人工智能、大数据的浪潮还在涌动,云办公、云问诊成为防疫期间的热词。
现如今,物联网技术正处于时代发展的风口,相较于传统的硬件设备,物联网技术使得各种硬件设备能够通过信息传输设备与互联网连接起来,继而进行信息的传递,以实现智能化识别与管理,为人们的日常生活带来便捷。
在上节课中,我们利用行空板设计了一个智慧农业可视化系统,模拟了对农业中庄稼生长环境的实时监测和改善,然而,在这其中,监测到的数据只能显示在行空板的屏幕上,我们必须走近行空板方能进行观察,很不方便。那有什么办法能让我们待在家中,远程就能知晓实时的环境数据呢?
这节课,就让我们试着利用强大的物联网技术,用DFRobot的行空板来模拟一个智慧农业物联网系统,解决这个问题吧!
任务目标
将通过土壤湿度传感器检测到的湿度值显示在屏幕上,同时,开启SIoT物联网系统,将数据同步传输到物联网平台以便进行查看,当观察到的土壤湿度值不佳时,通过在物联网平台的网页端输入指定字符“on”和“off”来控制继电器和水泵浇水。
知识点
1、认识物联网、MQTT、SIoT
2、学习使用SIoT库连接物联网平台的方法
3、学习使用SIoT库向物联网平台发送消息的方法
4、学习使用SIoT库接收物联网平台消息的方法
材料清单
硬件清单:
软件使用:Mind+编程软件x1
其他:
1、带植物的花盆 x1
2、盛有水的烧杯 x1
3、十字/一字两用螺丝刀 x1
知识储备
1、物联网
物联网(Internet of Things,简称IoT)是借助互联网、传统电信网等信息承载体,让所有能行使独立功能的普通物体实现互联互通的网络。
物联网是互联网的一个延伸,互联网的终端是计算机(PC、服务器),而物联网的终端是硬件设备(手机、电脑、传感器等等)。通过物联网,我们可以用中心计算机将各种机器、设备连接起来,进行集中管理,实现物物相连。比如,将家中的灯、风扇、空调等电器连入物联网中后可以通过手机来控制它们开关。
2、MQTT
计算机为了联网,就必须规定通信协议,就好比一群不同国家的人在一块儿,只有说同一种语言才能实现互相交流。同样地,要想实现万物互联,也需要一套协议。事实上,物联网系统的搭建可通过很多协议来实现,常用的物联网应用层协议包括MQTT、HTTP、XMPP、CoAP等。这里我们采用的是MQTT,通过该协议,我们可以在物联网上传输消息。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,服务器就是我们要搭建的物联网平台的载体。客户端可以是信息发布者或订阅者。每个客户端都可以连接到服务器。举个例子,邮局大家都不陌生,我们可以到邮局寄信和收信。当我们寄信时,对于邮局而言我们就是信息发布者,当收信时我们就成了订阅者。同时,无论是寄信者还是收信者,我们都是客户。而邮局这个收寄信的平台就是所谓的服务器,为我们提供收信和寄信的服务。
当发布者具有要分发的新数据时,它会将包含数据的控制消息发送到服务器。然后,服务器将信息分发给已订阅该主题的任何客户端。发布者不需要有关于订阅者数量或位置的任何数据,而订阅者又不必配置有关发布者的任何数据。
另外,MQTT传输的消息可分为:Topic和payload两部分
(1)Topic,可以理解为消息的类型,订阅者订阅后,就会收到该主题的消息内容(Payload);
(2)payload,可以理解为消息的内容,是指订阅者具体要接收的内容。
3、SIoT
SIoT是一个为教育定制的跨平台的开源MQTT服务器程序,S指科学(science)、简单(simple)的意思。SIoT支持Win10、Win7、Mac、Linux等操作系统,一键启动,无需用户注册或者系统设置即可使用。
SIoT也是为了帮助中小学生理解物联网原理,并且能够基于物联网技术开发各种创意应用。因为其重点关注物联网数据的收集和导出,是采集科学数据的最好选择之一。
这里,于行空板而言,SIoT应用程序已经被内置在了板子上,因此在使用时,我们可直接在应用开关内通过点击它来开启服务。同时,为了便于它的使用,我们开发了名为“SIoT”的Python库,旨在通过编写Python程序来连接MQTT服务器以及实现消息的传输。
在实际使用时,开启SIoT服务的行空板我们就可以当作一台服务器,连接传感器以检测数据的行空板(设备)我们可以当作客户端。
而如果在同一块板子上既开启SIoT服务,又连接传感器来检测数据,那么它既是客户端又是服务器。
Tips:在这节课上,我们将通过一块板子来实现物联网功能,而下节课中,我们将使用三块板子来模拟多节点的物联网系统。
4、SIoT库常见函数
(1)init()、connect()、loop()函数初始化并连接物联网平台
SIoT库中的init()函数可以用来初始化与物联网平台的连接,使用前,我们首先需要导入库,之后设定好连接物联网平台所需的参数,包括服务器IP地址、物联网平台的账号用户名、账号对应的密码,接着使用init()函数进行连接验证,验证成功后再通过connect()和loop()函数进行与平台的连接。
import siot # 导入SIoT库
SERVER = "10.1.2.3" # MQTT服务器IP,输入个人实际Ip
CLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空
IOT_UserName = 'siot' # 用户名
IOT_PassWord = 'dfrobot' # 密码
siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确
siot.connect() # 连接SIoT物联网平台
siot.loop() # 循环
其中,SERVER指的是开启siot服务用以连接的服务器的IP地址;CLIENT_ID指的是客户端标识符,它是客户端到服务器的唯一标识,这里我们可以不输入内容; user指的是物联网平台账户的用户名;password指账号对应的密码。
(2)publish()函数向物联网平台发送消息
在连接上SIoT物联网平台后,通过SIoT库的publish函数可以实现将消息发送到平台,使用时需要先后指定发送的主题Topic(目的地)和发送的消息内容。
IOT_pubTopic = '智慧农业物联网系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称”
Soil_moisture_value = adc0.read_analog() # 读取模拟值
siot.publish(IOT_pubTopic, Soil_moisture_value) # 发布信息至物联网平台
其中,IOT_pubTopic指主题Topic,包括项目ID和设备名称;Soil_moisture_value指要发送的土壤湿度数据消息。
Tips:SIoT平台上同时用Topic表示了项目ID和设备名称,因此Topic中需要有“/”符号将两者分开,否则物联网平台看不到项目。
(3)subscribe()函数订阅物联网平台消息
在连接上SIoT物联网平台后,通过SIoT库的subscribe()函数可以订阅平台发送来的消息,使用时需要先后指定发送的主题Topic(目的地)以及接收到平台消息后所要执行的操作。
IOT_pubTopic = '智慧农业物联网系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称”
def sub_relay(client, userdata, msg):
topic = msg.topic
payload = msg.payload.decode()
'''定义接收到指令时的操作'''
print("\nTopic:" + topic + " Message:" + payload) # 打印接收到的信息
if payload == 'on': # 如果接收到“on”
img.config(w=240, h=320, image='img/浇水1.png')
relay.write_digital(1) # 继电器输出高电平
elif payload == 'off': # 如果接收到“off”
img.config(w=240, h=320, image='img/关水1.png')
relay.write_digital(0) # 继电器输出低电平
siot.subscribe(IOT_pubTopic, sub_relay) # 订阅消息
其中,IOT_pubTopic指主题Topic,包括项目ID和设备名称;sub_relay是定义的接收到平台消息后所要执行的功能函数;msg.topic指的是消息中的Topic主题;msg.payload指的是消息的内容;decode()是将消息内容转换为字符串方便后续条件判断。
动手实践
任务描述1:发送湿度数据至SIoT物联网平台
启动SIoT物联网系统,通过外接土壤湿度传感器检测湿度值后,将数据显示在屏幕上的同时也发送至SIoT物联网平台并在平台网页端查看。
1、硬件搭建
STEP1:通过USB连接线将行空板连接到计算机
STEP2:将土壤湿度传感器接入行空板的P21引脚
STEP3:将土壤湿度传感器插入花盆中
STEP4:启动SIoT服务
按下HOME键进入菜单,单击“应用开关”,找到SIoT应用后点击启用,如下图所示。
STEP5:查看ip并记录
按下HOME键进入菜单,单击“查看网络信息”,找到SIoT应用后点击启用,如下图所示。
Tips:“10.1.2.3”为板子通过USB线连接电脑后的固定IP地址。这里我们将它记录下来,后续有用。
2、程序编写
STEP1:创建与保存项目文件
启动Mind+,另存项目并命名为“009、智慧农业物联网系统”。
STEP2:创建与保存Python文件
创建一个Python程序文件“main1.py”,双击打开。
STEP3:导入图片文件夹
在项目文件夹中导入背景图文件夹。(图片文件夹与程序文件同在项目文件夹中,下载链接见附录1)
STEP4:程序编写
(1) 导入所需功能库
在这个任务中,我们需要使用Pinpong库来使土壤湿度传感器读取数值并显示在屏幕上,因此,我们需要导入Pinpong库和unihiker库中的GUI模块,同时,为了能将数据实时发送至SIoT物联网平台,我们还需导入SIoT库。
from unihiker import GUI # 导入unihiker库GUI模块from pinpong.board import Board, Pin # 导入pinpong库下的Board, Pin模块import time # 导入time库import siot # 导入SIoT库 |
(2) 实例化GUI类并初始化板子和引脚
之后我们创建gui对象并初始化板子和引脚以便后续能使用屏幕功能和控制传感器工作。
gui = GUI() # 实例化gui对象 Board().begin() # 初始化行空板adc0 = Pin(Pin.P21, Pin.ANALOG) # 初始化21引脚为模拟输入模式 |
(3) 设置参数并连接SIoT平台
接下来,我们将创建与SIoT物联网平台的连接,在这之前,我们先设定好连接时所需要的参数,包括ip地址,CLIENT_ID,用户名,密码以及topic,之后进行连接并保持连接状态。
Tips:这里的IP地址为之前记录的“10.1.2.3”。
SERVER = "10.1.2.3" # MQTT服务器IP,输入个人实际Ip CLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic = '智慧农业物联网系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称” siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接SIoT物联网平台siot.loop() # 循环 |
(4) 显示背景图、填充矩形和初始文字
紧接着,我们在行空板的屏幕上显示一张背景图,并添加填充矩形和初始文字,以便后续直接在此更新数据显示。
# 显示背景图片img = gui.draw_image(w=240, h=320, image='img/关水1.png') # 绘制填充矩形并在矩形框内显示文字gui.fill_rect(x=65, y=35, w=70, h=30, color="white") # 绘制矩形“湿度值”gui.fill_rect(x=148, y=35, w=55, h=30, color="white") # 绘制矩形以显示湿度值数据 text_1 = gui.draw_text(x=68, y=36, color="red", text='湿度值:') # 显示"湿度值:"text_value = gui.draw_text(x=155, y=36, color="red", text="") # 显示湿度值数据 |
(5) 检测土壤湿度并将数据显示在屏幕及发送到SIoT物联网平台
最后,我们设置通过传感器来读取检测数据,将湿度值发送到物联网平台的同时也显示在屏幕上,而为了使得上述操作能每隔一秒不停地执行,这里,我们使用while语句。
while True: # 循环 Soil_moisture_value = adc0.read_analog() # 读取模拟值 print(Soil_moisture_value) # 打印显示湿度值 siot.publish(IOT_pubTopic, Soil_moisture_value) # 发布信息至物联网平台 text_value.config(text=Soil_moisture_value) # 更新湿度值 time.sleep(1) # delay1秒 |
Tips:完整示例程序如下:
from unihiker import GUI # 导入unihiker库GUI模块from pinpong.board import Board, Pin # 导入pinpong库下的Board, Pin模块import time # 导入time库import siot # 导入SIoT库 gui = GUI() # 实例化gui对象 Board().begin() # 初始化行空板adc0 = Pin(Pin.P21, Pin.ANALOG) # 初始化21引脚为模拟输入模式 SERVER = "10.1.2.3" # MQTT服务器IP,输入个人实际Ip CLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic = '智慧农业物联网系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称” siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接SIoT物联网平台siot.loop() # 循环 # 显示背景图片img = gui.draw_image(w=240, h=320, image='img/关水1.png') # 绘制填充矩形并在矩形框内显示文字gui.fill_rect(x=65, y=35, w=70, h=30, color="white") # 绘制矩形“湿度值”gui.fill_rect(x=148, y=35, w=55, h=30, color="white") # 绘制矩形以显示湿度值数据 text_1 = gui.draw_text(x=68, y=36, color="red", text='湿度值:') # 显示"湿度值:"text_value = gui.draw_text(x=155, y=36, color="red", text="") # 显示湿度值数据 while True: # 循环 Soil_moisture_value = adc0.read_analog() # 读取模拟值 print(Soil_moisture_value) # 打印显示湿度值 siot.publish(IOT_pubTopic, Soil_moisture_value) # 发布信息至物联网平台 text_value.config(text=Soil_moisture_value) # 更新湿度值 time.sleep(1) # delay1秒 |
3、程序运行
STEP1:远程连接行空板,运行程序并观察效果
观察行空板,可以看到在智慧农业的背景图上,每隔一秒显示着检测到的土壤湿度值。
STEP2:平台网页端查看消息
(1)打开浏览器,输入“10.1.2.3”后回车,进入行空板的网页菜单,找到应用开关下的SIoT服务,点击“打开页面”。
(2)输入默认的账号“siot”,密码“dfrobot”,点击登录
(3)点击“智慧农业物联网系统”项目下的“查看设备列表”
可以看到“项目ID”、“名称”分别对应为程序中“IOT_pubTopic”的信息
(4)点击“查看消息”
随后我们就可以查看到“智慧农业物联网系统/Soil_moisture_value”这个Topic的MQTT消息记录啦,并伴有具体的消息内容及发送时间,这就是我们检测到的该时刻的土壤湿度值,如下图。
(5)点击“自动刷新消息”
通过刷新消息,我们发现土壤湿度数据每隔一秒进行了更新,如下图,
(6)点击“隐藏/显示图标”
点击后,我们可以发现数据以图表的形式呈现了出来,如下图。
(7)点击“导出查询结果”
这里我们可以将数据以表格的形式下载下来以便后续作进一步分析。
任务描述2:平台网页端控制浇水
在上一任务中,我们实现了将土壤湿度传感器检测到的数据上传到SIoT物联网平台,并从平台的网页端实时查看湿度值,接下来,我们给板子添加订阅平台消息的功能,使得我们能够在土壤较干燥的时候通过SIoT物联网平台的网页端来及时控制浇水。
1、硬件搭建
STEP1:将继电器接入行空板的P23引脚
STEP2:利用螺丝刀将水泵正负线与转接头连接起来,具体步骤同上节课。
STEP3:利用继电器将12V电源开关与水泵的转接头连接起来
STEP4:将继电器开关拨至NC端
STEP5:将水泵固定在满水的烧杯中
STEP6:将水管插入花盆中
2、程序编写
STEP1:创建与保存项目文件
新建一个Python程序文件“main2.py”,双击打开。
Step2:程序编写
(1)初始化引脚
这里,由于我们将使用继电器控制水泵进行浇水,因此我们需要补充对继电器引脚的初始化操作,设置其23号引脚为数字输出模式。
relay = Pin(Pin.P23, Pin.OUT) # 初始化23引脚为数字输出模式 |
(2)定义接收到平台消息后的操作
由于后续我们将接收平台发送的消息,当消息为“on”时,控制继电器输出高电平来浇水,当消息为“off”时,控制继电器输出低电平停止浇水。因此在这里,我们补充定义一个回调函数,来表示接收到平台消息后需执行的操作,以便在后续调用。
def sub_relay(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() '''定义接收到指令时的操作''' print("\nTopic:" + topic + " Message:" + payload) # 打印接收到的信息 if payload == 'on': # 如果接收到“on” img.config(w=240, h=320, image='img/浇水1.png') relay.write_digital(1) # 继电器高电平 elif payload == 'off': # 如果接收到“off” img.config(w=240, h=320, image='img/关水1.png') relay.write_digital(0) # 继电器低电平 |
(3)订阅平台发送的消息
最后,为了能接收到物联网平台发送的消息,这里,我们在连接上平台后补充一下对消息的订阅。
siot.subscribe(IOT_pubTopic, sub_relay) # 订阅消息 |
Tips:完整示例程序如下:
from unihiker import GUI # 导入unihiker库GUI模块from pinpong.board import Board, Pin # 导入pinpong库下的Board, Pin模块import time # 导入time库import siot # 导入SIoT库 gui = GUI() # 实例化gui对象 Board().begin() # 初始化行空板adc0 = Pin(Pin.P21, Pin.ANALOG) # 初始化21引脚为模拟输入模式relay = Pin(Pin.P23, Pin.OUT) # 初始化23引脚为数字输出模式 SERVER = "10.1.2.3" # MQTT服务器IP,输入个人实际IP CLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic = '智慧农业物联网系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称” def sub_relay(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() '''定义接收到指令时的操作''' print("\nTopic:" + topic + " Message:" + payload) # 打印接收到的信息 if payload == 'on': # 如果接收到“on” img.config(w=240, h=320, image='img/浇水1.png') relay.write_digital(1) # 继电器输出高电平 elif payload == 'off': # 如果接收到“off” img.config(w=240, h=320, image='img/关水1.png') relay.write_digital(0) # 继电器输出低电平 siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接SIoT物联网平台siot.subscribe(IOT_pubTopic, sub_relay) # 订阅消息siot.loop() # 循环 # 显示背景图片img = gui.draw_image(w=240, h=320, image='img/关水1.png') # 绘制填充矩形并在矩形框内显示文字gui.fill_rect(x=65, y=35, w=70, h=30, color="white") # 绘制矩形“湿度值”gui.fill_rect(x=148, y=35, w=55, h=30, color="white") # 绘制矩形以显示湿度值数据 text_1 = gui.draw_text(x=68, y=36, color="red", text='湿度值:') # 绘制矩形“湿度值”text_value = gui.draw_text(x=155, y=36, color="red", text="") # 显示湿度值数据 while True: # 循环 Soil_moisture_value = adc0.read_analog() # 读取模拟值 print(Soil_moisture_value) # 打印显示湿度值 siot.publish(IOT_pubTopic, Soil_moisture_value) # 发布信息至物联网平台 text_value.config(text=Soil_moisture_value) # 更新湿度值 time.sleep(1) # delay1秒 |
3、程序运行
STEP1:将12V电源开关插上220V电源插座
STEP2:远程连接行空板,运行程序并观察效果
观察行空板,可以发现湿度值依旧不停得更新显示在屏幕上。
STEP3:平台发送消息
观察检测到的突然湿度数据,当湿度值过低时,我们在网页端指定位置输入“on”,并点击发送,可以发现继电器开始工作,控制水泵不断将烧杯中的水抽入花盆中。
之后,当水量合适后,我们再在消息框中输入“off”,点击发送后,可以发现水泵停了下来。
挑战自我
想一想,在农业系统中,还有哪些因素是会影响庄稼生长的呢,我们有何方法来检测它吗,自己来研究一下吧,并结合物联网平台,试着以远程的方式分析一下它对庄稼的影响规律吧!
更多行空板Python入门教程学习请关注“蘑菇云创造”公众号。