创作

完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>

3天内不再提示

「行空板Python入门教程」第十课:多节点智慧农业系统

创客生活 来源:创客生活 作者:创客生活 2022-06-23 11:26 次阅读

在蘑菇云「行空板Python入门教程」第九节课上,我们设计了一个智慧农业物联网系统,通过一块行空板来检测植物生长时的土壤湿度情况,将湿度数据上传到SIoT物联网平台进行远程查看并在湿度较低时从平台远程控制浇水。

然而,在真实的农业场景中,常常需要检测不同场所内的多样数据,并汇总到一个平台总站以便远程访问。

那么,在这节课上,让我们借助DFRobot的3块行空板,一起来设计一个多节点的智慧农业系统,模拟一下真实的农业场景吧。

poYBAGKz3WyAUOtXAABF0zn8WDU418.jpg行空板模拟智慧农业系统

任务目标

准备多块行空板(以3块为例),将所有行空板与电脑连接到同一个局域网段内。之后单独在第三块行空板上开启SIoT应用作为服务器,将通过第一块行空板检测到的土壤湿度数据和第二块行空板检测到的光线值数据,各自显示在屏幕上的同时,也发送到板3的SIoT物联网平台上;最后,使第三块行空板订阅物联网平台接收到的消息,将板1的土壤湿度情况和板2的光线强度情况一起显示在屏幕上,并且,当检测到的两个环境数据不佳时,自动给我们的邮箱发送一封警报邮件,以此来提醒我们及时浇水和补光。

pYYBAGKz3WyAC2FOAAB8BuG8-s8541.pngpoYBAGKz3W2AbcMeAAB1PpSkcLc251.pngpYYBAGKz3W2ANloJAAB2aaxYzmg074.pngpoYBAGKz3W2ASDNmAABk_YsYw_s702.pngpYYBAGKz3W2AWrp-AABkM_aagt4894.pngpoYBAGKz3W2ANgPBAABjCmlBDaA013.pngpYYBAGKz3W2ADtjLAABld5nJ7VY237.pngpoYBAGKz3W2AHdIPAABkEzpVImg409.pngpYYBAGKz3W2APFTuAAAanbvJOwg490.jpgpoYBAGKz3W6AaHdHAABGrAAtiAc355.jpgpYYBAGKz3W6AdjcbAABGXVwUVIs967.jpg

知识点

1、学习使用3块行空板搭建多节点物联网系统的方法

2、掌握给行空板供电的多种不同的方式

3、掌握远程连接行空板并运行程序的不同方法

4、学习使用smtplib库发送邮件的流程

5、学习使用smtplib库发送邮件的具体方法

材料清单

硬件清单:

poYBAGKz3W6AGGMiAACh9OZU6ps041.jpg

多节点智慧农业系统需要的硬件材料

软件使用:Mind+编程软件x1

其他: 1、带植物的花盆 x1

2、盛有水的烧杯 x1

3、十字/一字两用螺丝刀 x1

4、TypeC或USB-A口的电源适配器或充电宝 x3

知识储备

1、smtplib库与email库

使用Python编程来发送邮件需要两个关键步骤,一步是构造邮件信息内容,另一步是发送邮件。前者,我们可以借助email库来实现,后者,我们可以使用smtplib库来进行。

pYYBAGKz3W6AJcLCAAAWGSUUU4Y996.jpg

2、email.mime.text包MIMEText模块创建邮件文本

email.mime.text包的MIMEText模块可在构造邮件时创建文本内容,使用时,需要先导入该模块,之后以实例化MIMEText()类的形式来创建文本对象。

from email.mime.text import MIMEText # 导入email.mime.text包中的MIMEText模块

msg=MIMEText('Hello World','plain','utf-8') # 创建邮件文本对象,‘Hello World’对应文本内容,'plain'指设置的文本格式,'utf-8'指设置的编码

其中,“Hello World”指要发送的文本内容,“plain”指文本的格式,“utf-8”指的是编码。

3、email.utils包formataddr模块格式化内容

email.utils包的 formataddr模块可在构造邮件时将输入的内容进行格式化操作,以便邮件服务器能够识别。使用时,需要先导入该模块。

from email.utils import formataddr # 导入formataddr模块,负责将输入的内容格式化

'''三个头部信息:发件人,收件人,主题'''

msg['From']=formataddr([my_name,my_sender]) # 定义发件人信息:括号里的对应发件人邮箱昵称、发件人邮箱账号

msg['To']=formataddr([my_user_name,my_user]) # 定义收件人信息:括号里的对应收件人邮箱昵称、收件人邮箱账号

msg['Subject']= '邮件测试' # 定义邮件的主题,也可以说是标题

其中,“msg['From']”表示邮件信息中发件人信息,包括邮箱、昵称;“msg['To']”表示邮件信息中收件人的信息,包括邮箱、昵称;“msg['Subject']”表示邮件的主题,文本内容“邮件测试”是它的具体内容。

这里,我们通过“formataddr()”函数将邮件的发件人信息和收件人信息文本进行了格式化操作。

4、smtplib库各功能函数

smtplib库可实现发送邮件功能,使用时,首先需要先导入该库,其次,通过其中的“SMTP_SSL()”函数来创建一个SMTP服务对象以连接邮箱,接着通过“login()”函数登录邮箱,之后使用“sendmail()”函数即可发送邮件,最后通过“quit()”函数退出与邮箱服务器的连接。

(1)smtplib库SMTP_SSL()函数创建SMTP服务对象

smtplib库中的SMTP_SSL()函数可创建SMTP服务对象以连接邮箱。使用时,首先需要先导入该库。 import smtplib # 导入smtplib库

server=smtplib.SMTP_SSL("smtp.qq.com", 465) # 创建SMTP服务,连接qq邮箱服务器,发件人邮箱中的SMTP服务器,SMTP协议加密端口是465

其中,“smtp.qq.com”指的是QQ邮箱服务器,“465”表示 SMTP协议加密端口。

(2)smtplib库login()函数登录邮箱

smtplib库中的login()函数可实现对发件人邮箱的登录。使用时,需设定好所要登录邮箱的账号和第三方登录授权码。

my_sender='10******69@qq.com' # 设置发件人邮箱账号,输入自己的邮箱

my_pass = 'sq******ga' # 设置发件人邮箱授权码

server.login(my_sender, my_pass) # 登录邮箱,括号中对应的是发件人邮箱账号、邮箱密码

其中,“my_sender”指的是发件人邮箱账号,“my_pass”指的是发件人邮箱授权码。

(3)smtplib库sendmail()函数发送邮件

smtplib库中的sendmail()函数可实现邮件的发送。使用时,需设定好发件人邮箱账号、收件人邮箱账号和所要发送邮件信息内容。

msg=MIMEText(content,'plain','utf-8') # 创建邮件文本对象,Title对应文本内容,'plain'指设置的文本格式,'utf-8'指设置的编码

my_sender='10******69@qq.com' # 设置发件人邮箱账号,输入自己的邮箱

my_user='10******69@qq.com' # 设置收件人邮箱账号,我这边发送给自己

server.sendmail(my_sender,my_user,msg.as_string()) # 发送邮件,括号中对应的是发件人邮箱账号、收件人邮箱账号、邮件信息的字符串格式

其中,“my_sender”指的是发件人邮箱账号,“my_user”指的是收件人邮箱账号,“msg.as_string()”指的是将邮件定义为字符串格式。

(4)smtplib库quit()函数关闭连接

smtplib库中的quit()函数可关闭与邮箱服务器之间的连接。

server.quit() # 关闭连接

动手实践

任务描述1:前期准备

1、分析设计

在这个项目中,我们将完成多节点智慧农业系统的设计。首先,我们需要将3块行空板与电脑都连接在同一个局域网内(借助路由器/手机热点);之后,我们要将每一块板子轮流使用USB线连接电脑进行网络配置;最后,我们再单独开启其中一块板子的SIoT应用使其作为服务器,而其他板子作为客户端,通过编程将数据发送到SIoT物联网平台上。

poYBAGKz3W6AZuj-AAA5kUEUYlc147.jpg

2、配置网络

STEP1:将电脑连入路由器的Wi-Fi

pYYBAGKz3W6AY0i_AAAPXiVGO-k007.jpg

Tips :没有路由器也可通过手机开热点的方式实现联网。

STEP2:取一块板子,将其通过USB连接线连接到电脑。

STEP3:打开浏览器,登录“10.1.2.3”行空板网页菜单,配置网络,使其连在同一Wi-Fi中。

poYBAGKz3W6AVg4HAABAw6lrDJw501.jpg

STEP4:完成后,拔下USB线,用同样的方式给其他两块行空板配置好网络。

STEP5:给3块板子上电,使其都保持开机状态

这里,给板子上电有以下三种方式,任选其一即可:

1、使用USB或type-c口输出的电源适配器

2、使用USB或type-c口输出的充电宝

3、通过电脑的USB端口

STEP6:检查各板子无线连接的IP地址。

依次查看并记录下3块板子的无线连接的IP地址,如下图,前三组数字应该是一样的,这说明我们成功将3块板子都连接在了同一局域网段内。

Tips:这里,三块板子的无线连接IP地址分别为“192.168.43.199”、“192.168.43.200”、“192.168.43.201”。

pYYBAGKz3W-ANu9LAABeW3vbYNA746.jpg

3、开启SIoT

STEP1:单独启动一块板子的SIoT服务

找到其中一块板子,按下HOME键进入菜单,单击“应用开关”,找到SIoT应用后点击启用,如下图所示。同时,确认其余两块板子SIoT应用关闭。

Tip1:这里,我们将SIoT服务启动在了IP为“192.168.43.201”的板子上。

Tip2:关闭其他板子的SIoT是为了避免如果输入地址错误导致数据不在同一个地方。

poYBAGKz3W-ABzl6AABkKA1Zmg8204.jpg

STEP2:检查电脑联网

打开浏览器,输入IP地址“192.168.43.201”并回车,进入行空板的网页菜单,找到应用开关下的SIoT服务,点击“打开页面”。

pYYBAGKz3W-AHVaIAABEuG3Z7b0073.jpg

Tips:这里,需将“192.168.43.201”改为个人实际的IP地址。

如出现下列界面(物联网平台网页端),说明电脑和板子都连在了同一局域网内,且SIoT应用启动成功。

poYBAGKz3W-AD34MAAAr9bz7k0c641.jpg

任务描述2:行空板1检测土壤湿度

这里,为了便于区分,我们将开启SIoT应用的板子记作行空板3,其余两块板子分别为行空板1和行空板2 。

这个任务中,我们将在行空板1的屏幕上显示一张智慧农业的背景图,使外接土壤湿度传感器检测到的湿度数据一边显示在屏幕上,一边发送到板3的SIoT平台上,这里的整体功能同上节课。

同时,对板1设定设置自动和手动两个模式,在自动模式下,当检测到的土壤湿度值过低时,通过外接继电器和水泵来自动浇水;在手动模式下,可通过点击屏幕上按钮的方式进行浇水;模式之间也可通过按钮手动切换。

此外,也可在SIoT物联网平台网页端发送“relay on”、“relay off”、“auto”和“manual”四个指令,远程控制浇水、关水、切换自动模式以及切换手动模式。

1、硬件搭建

STEP1:将土壤湿度传感器接入行空板1的P21引脚,继电器接入P23引脚

pYYBAGKz3W-AD88pAAAk4o0GMxo340.jpg

STEP2:利用螺丝刀将水泵正负线与转接头连接起来

poYBAGKz3W-AB1X0AAAaHpddjSw878.jpg

STEP3:利用继电器将12V电源开关与水泵的转接头连接起来

pYYBAGKz3W-ANZQmAAAsmk0O7Xk169.jpg

STEP4:将继电器开关拨至NC端

poYBAGKz3W-AcYALAAAxKj_zTs4700.png

STEP5:将水管和土壤湿度传感器插入花盆中,水泵固定在满水的烧杯中

pYYBAGKz3W-ARqtgAAAdIPMyAvc500.jpg

STEP6:将12V电源开关插上220V电源插座

Tips :上述具体步骤皆可参考第8课。

2、程序编写

STEP1:创建与保存项目文件

启动Mind+,另存项目并命名为“010、多节点智慧农业系统01”。

STEP2:远程连接行空板

对不同的板子编程,我们可以同时打开多个Mind+,在各个Mind+中手动输入不同的IP地址,这样就可以连接访问不同板子了。

(1)选择“手动输入”

poYBAGKz3W-ABALUAAAZEJBXsuM400.jpg

(2)输入行空板1 的无线连接IP地址“192.168.43.199”

Tips:需改为个人实际的行空板1的IP地址,同时这里的板子须为正常开机状态且板子与电脑在同一个Wi-Fi下方可连接成功。

pYYBAGKz3XCASmdQAAA-Iv6EM04527.jpg

STEP3:在行空板1中创建一个新的文件夹,并命名为“多节点智慧农业系统”

Tips:这里,我们将程序直接建在板子中,这样可以便于直接通过行空板的Home菜单来运行程序而不需要启动MInd+运行,操作方法后续会介绍。

poYBAGKz3XCAc7VzAAA7Gp36dj4137.jpg

STEP4:创建与保存Python文件

在“多节点智慧农业系统”文件夹中创建一个Python程序文件“main1.py”,双击打开。

pYYBAGKz3XCAIy-YAAA8hnKkUbc589.jpg

STEP5:导入素材文件夹

在“多节点智慧农业系统”文件夹中导入素材文件夹。(下载链接见附录1)

poYBAGKz3XCABzaqAABTTwIo71M223.jpgpYYBAGKz3XCALHxNAAA13YuHA6Y239.jpg

STEP6:程序编写

(1) 导入所需功能库

from unihiker import GUI # 导入unihiker库GUI模块from pinpong.board import Board, Pin # 导入pinpong库下的Board, Pin模块import time # 导入time库import siot # 导入siot库

(2) 初始化板子和引脚

'''初始化板子和硬件'''Board().begin() # 初始化行空板adc0 = Pin(Pin.P21, Pin.ANALOG) # 初始化21引脚为模拟输入模式relay = Pin(Pin.P23, Pin.OUT) # 初始化23引脚为数字输出模式

(3) 连接SIoT物联网平台并设置发送和订阅消息数据功能

Tips:这里的IP地址写入的是之前记录的行空板3的无线热点IP。

'''设置物联网平台连接参数'''SERVER = "192.168.43.201" # MQTT服务器IP,输入个人实际IPCLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic1 = '多节点智慧农业系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称” # 定义回调函数def sub_relay(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() '''定义接收到指令时的操作''' print("\nTopic:" + topic + " Message:" + payload) # 打印接收到的信息 if payload == 'relay on': # 如果接收到“relay on” img.config(w=240, h=320, image='img/浇水1.png') relay.write_digital(1) # 继电器输出高电平 elif payload == 'relay off': # 如果接收到“relay off” img.config(w=240, h=320, image='img/关水1.png') relay.write_digital(0) # 继电器输出低电平 elif payload == 'auto': # 如果接收到“auto” print("auto") click_C() # 切换模式--自动模式 elif payload == 'manual': # 如果接收到“manual” print("manual") click_C() # 切换模式--手动模式 siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接siot物联网平台siot.subscribe(IOT_pubTopic1, sub_relay) # 订阅物联网平台消息siot.loop() # 循环

(4) 显示屏幕界面

'''显示屏幕界面'''gui = GUI() # 实例化gui对象img = gui.draw_image(w=240, h=320, image='img/关水1.png') # 显示背景图片 # 定义三个按钮的回调函数def click_A(): '''定义点击按钮A时的操作--切换显示浇水图片''' img.config(w=240, h=320, image='img/浇水1.png') relay.write_digital(1) # 继电器输出高电平 def click_B(): '''定义点击按钮B时的操作--切换显示关水图片''' img.config(w=240, h=320, image='img/关水1.png') relay.write_digital(0) # 继电器输出低电平 is_auto_mode = 1 # 定义一个标志位--自动模式,1为开,0为关 def click_C(): # 定义点击按钮C时的操作--切换模式 global is_auto_mode if is_auto_mode == 0: # 如果自动模式标志位为0, 即原来为手动模式,那么点击后 text_mode.config(text="自动") button_A.config(state='disabled') # 设置按钮状态为disabled,表示无法点击 button_B.config(state='disabled') is_auto_mode = 1 # 设置自动模式标志位为1 ,即打开自动模式 elif is_auto_mode == 1: # 如果自动模式标准位为1, 即原来为自动模式,那么点击后 text_mode.config(text="手动") button_A.config(state='normal') # 设置按钮状态为normal,表示可以被点击 button_B.config(state='normal') is_auto_mode = 0 # 设置自动模式标志位为0 ,即打开手动模式 # 绘制填充矩形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") # 绘制矩形以显示湿度值数据gui.fill_rect(x=100, y=160, w=70, h=30, color="white") # 绘制矩形以显示“当前模式”gui.fill_rect(x=180, y=160, w=50, h=30, color="white") # 绘制矩形以显示模式类型 # 在矩形框内显示文字gui.draw_text(x=68, y=36, color="red", text='湿度值:') # 显示文字“湿度值:”text_value = gui.draw_text(x=155, y=36, color="red", text="") # 显示湿度值数据gui.draw_text(x=105, y=163, color="red", text='当前模式:', font_size=11) # 显示文字“当前模式:”text_mode = gui.draw_text(x=190, y=163, color="red", text="自动", font_size=11) # 显示模式类型 # 显示按钮'''显示按钮并设置按钮点击后触发的功能,以及按钮初始时处于不可被点击状态'''button_A = gui.add_button(x=50, y=260, w=70, h=40,text="浇水", onclick=click_A, state='disabled')button_B = gui.add_button(x=140, y=260, w=70, h=40,text="关水", onclick=click_B, state='disabled')button_C = gui.add_button(x=10, y=160, w=70, h=30,text="切换模式", onclick=click_C)

(5) 定义自动补水功能

# 定义湿度值较低时自动补水3秒def auto_watering(): '''定义湿度值较低时自动补水3秒''' if Soil_moisture_value < 2120: click_A() time.sleep(3) click_B() else: click_B()

(6) 循环检测湿度值并发送数据至物联网平台

while True: # 循环 Soil_moisture_value = adc0.read_analog() # 读取模拟值 print(Soil_moisture_value) # 打印显示湿度值 siot.publish(IOT_pubTopic1, Soil_moisture_value) # 发布信息至物联网平台 if is_auto_mode == 1: auto_watering() # 自动补水 text_value.config(text=Soil_moisture_value) # 更新湿度值 time.sleep(1) # delay1秒

Tips:完整示例程序如下:

# 板1检测土壤湿度数据,发送到板3开启的SIoT物联网平台上。from unihiker import GUI # 导入unihiker库GUI模块from pinpong.board import Board, Pin # 导入pinpong库下的Board, Pin模块import time # 导入time库import siot # 导入siot库 '''初始化板子和硬件'''Board().begin() # 初始化行空板adc0 = Pin(Pin.P21, Pin.ANALOG) # 初始化21引脚为模拟输入模式relay = Pin(Pin.P23, Pin.OUT) # 初始化23引脚为数字输出模式 '''设置物联网平台连接参数'''SERVER = "192.168.43.201" # MQTT服务器IP,输入个人实际IP CLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic1 = '多节点智慧农业系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称” # 定义回调函数def sub_relay(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() '''定义接收到指令时的操作''' print("\nTopic:" + topic + " Message:" + payload) # 打印接收到的信息 if payload == 'relay on': # 如果接收到“relay on” img.config(w=240, h=320, image='img/浇水1.png') relay.write_digital(1) # 继电器输出高电平 elif payload == 'relay off': # 如果接收到“relay off” img.config(w=240, h=320, image='img/关水1.png') relay.write_digital(0) # 继电器输出低电平 elif payload == 'auto': # 如果接收到“auto” print("auto") click_C() # 切换模式--自动模式 elif payload == 'manual': # 如果接收到“manual” print("manual") click_C() # 切换模式--手动模式 siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接siot物联网平台siot.subscribe(IOT_pubTopic1, sub_relay) # 订阅物联网平台消息siot.loop() # 循环 '''显示屏幕界面'''gui = GUI() # 实例化gui对象img = gui.draw_image(w=240, h=320, image='img/关水1.png') # 显示背景图片 # 定义三个按钮的回调函数def click_A(): '''定义点击按钮A时的操作--切换显示浇水图片''' img.config(w=240, h=320, image='img/浇水1.png') relay.write_digital(1) # 继电器输出高电平 def click_B(): '''定义点击按钮B时的操作--切换显示关水图片''' img.config(w=240, h=320, image='img/关水1.png') relay.write_digital(0) # 继电器输出低电平 is_auto_mode = 1 # 定义一个标志位--自动模式,1为开,0为关 def click_C(): # 定义点击按钮C时的操作--切换模式 global is_auto_mode if is_auto_mode == 0: # 如果自动模式标志位为0, 即原来为手动模式,那么点击后 text_mode.config(text="自动") button_A.config(state='disabled') # 设置按钮状态为disabled,表示无法点击 button_B.config(state='disabled') is_auto_mode = 1 # 设置自动模式标志位为1 ,即打开自动模式 elif is_auto_mode == 1: # 如果自动模式标准位为1, 即原来为自动模式,那么点击后 text_mode.config(text="手动") button_A.config(state='normal') # 设置按钮状态为normal,表示可以被点击 button_B.config(state='normal') is_auto_mode = 0 # 设置自动模式标志位为0 ,即打开手动模式 # 绘制填充矩形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") # 绘制矩形以显示湿度值数据gui.fill_rect(x=100, y=160, w=70, h=30, color="white") # 绘制矩形以显示“当前模式”gui.fill_rect(x=180, y=160, w=50, h=30, color="white") # 绘制矩形以显示模式类型 # 在矩形框内显示文字gui.draw_text(x=68, y=36, color="red", text='湿度值:') # 显示文字“湿度值:”text_value = gui.draw_text(x=155, y=36, color="red", text="") # 显示湿度值数据gui.draw_text(x=105, y=163, color="red", text='当前模式:', font_size=11) # 显示文字“当前模式:”text_mode = gui.draw_text(x=190, y=163, color="red", text="自动", font_size=11) # 显示模式类型 # 显示按钮'''显示按钮并设置按钮点击后触发的功能,以及按钮初始时处于不可被点击状态'''button_A = gui.add_button(x=50, y=260, w=70, h=40,text="浇水", onclick=click_A, state='disabled')button_B = gui.add_button(x=140, y=260, w=70, h=40,text="关水", onclick=click_B, state='disabled')button_C = gui.add_button(x=10, y=160, w=70, h=30,text="切换模式", onclick=click_C) # 定义湿度值较低时自动补水3秒def auto_watering(): '''定义湿度值较低时自动补水3秒''' if Soil_moisture_value < 2120: click_A() time.sleep(3) click_B() else: click_B() while True: # 循环 Soil_moisture_value = adc0.read_analog() # 读取模拟值 print(Soil_moisture_value) # 打印显示湿度值 siot.publish(IOT_pubTopic1, Soil_moisture_value) # 发布信息至物联网平台 if is_auto_mode == 1: auto_watering() # 自动补水 text_value.config(text=Soil_moisture_value) # 更新湿度值 time.sleep(1) # delay1秒

3、程序运行

STEP1:运行观察效果

点击Mind+软件上的运行按钮,观察行空板1,可以看到板1界面如下,能在手动和自动两个模式下控制浇水,也可以在浏览器中输入SIoT服务器所在的行空板的IP地址(此处为“192.168.43.201”),打开网页菜单应用开关中的SIoT,从物联网平台远程查看湿度数据并且进行浇水等操作。

poYBAGKz3XCAbBGHAAB47N0wTLs838.pngpoYBAGKz3W2AbcMeAAB1PpSkcLc251.pngpYYBAGKz3WyAC2FOAAB8BuG8-s8541.pngpYYBAGKz3XGAPVHOAAB4Bh9jPFU362.pngpoYBAGKz3XGANt8bAAA_AapIef8318.jpg

Tips:只有手动模式下发送消息才有效

任务描述3:行空板2检测光线

这里,我们将在行空板2的屏幕上显示一张小灯背景图,将板载光线传感器检测到的光线值数据一边显示在屏幕上,一边发送到板3的SIoT平台上。

同时,对板2设定设置自动和手动两个模式,在自动模式下,当检测到的光线值过低时,通过外接LED来自动补光;在手动模式下,可通过点击屏幕上按钮的方式来补光;模式之间也可通过按钮手动切换。

此外,也可在SIoT物联网平台网页端发送“led on”、“led off”、“auto”和“manual”四个指令,远程控制LED灯打开、LED灯熄灭、切换自动模式以及切换手动模式。

1、硬件搭建

将LED接入行空板2的P23引脚

pYYBAGKz3XGAfDltAAAbZCEA9jo303.jpg

2、程序编写

STEP1:创建与保存项目文件

再启动一个Mind+软件,另存项目并命名为“010、多节点智慧农业系统02”。

STEP2:远程连接行空板

(1)选择“手动输入”

(2)输入行空板2 的无线连接IP地址“192.168.43.200”

poYBAGKz3XGAV_3gAAA46-k3lfQ503.jpg

STEP3:和板1一样,直接在行空板2中创建一个新的文件夹,并命名为“多节点智慧农业系统”

STEP4:创建与保存Python文件

在“多节点智慧农业系统”文件夹中创建一个Python程序文件“main2.py”,双击打开。

STEP5:在“多节点智慧农业系统”文件夹中导入素材文件夹。

pYYBAGKz3XGAcRebAAA35is1L5s791.jpg

STEP6:程序编写

整体上,这里的编程逻辑同上述板1,因此我们不做过多赘述,注意写入实际行空板3的IP地址。

Tips:完整示例程序如下:

# 板2检测光线数据,发送到板3开启的SIoT物联网平台上。from unihiker import GUI # 导入unihiker库from pinpong.board import Board, Pin # 导入pinpong库下的Board, Pin模块from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块import time # 导入time库import siot # 导入siot库 '''初始化板子和硬件'''Board().begin() # 初始化行空板led = Pin(Pin.P23, Pin.OUT) # 初始化23引脚为数字输出模式 '''设置物联网平台连接参数'''SERVER = "192.168.43.201" # MQTT服务器IP,输入个人实际IP CLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic2 = '多节点智慧农业系统/light' # 湿度topic,“项目名称/设备名称” # 定义回调函数def sub_led(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() '''定义接收到指令时的操作''' print("\nTopic:" + topic + " Message:" + payload) # 打印接收到的信息 if payload == 'led on': # 如果接收到“led on” img.config(w=240, h=320, image='img/开灯1.png') led.write_digital(1) # led输出高电平 elif payload == 'led off': # 如果接收到“led off” img.config(w=240, h=320, image='img/关灯1.png') led.write_digital(0) # led输出低电平 elif payload == 'auto': # 如果接收到“auto” print("auto") click_C() # 切换模式--自动模式 elif payload == 'manual': # 如果接收到“manual” print("manual") click_C() # 切换模式--手动模式 siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接siot物联网平台siot.subscribe(IOT_pubTopic2, sub_led) # 订阅物联网平台消息siot.loop() # 循环 '''显示屏幕界面'''gui = GUI() # 实例化gui对象img = gui.draw_image(w=240, h=320, image='img/关灯1.png') # 显示背景图片 # 定义回调函数def click_A(): '''定义点击按钮A时的操作--切换显示开灯图片''' img.config(w=240, h=320, image='img/开灯1.png') led.write_digital(1) # 继电器输出高电平 def click_B(): '''定义点击按钮B时的操作--切换显示关灯图片''' img.config(w=240, h=320, image='img/关灯1.png') led.write_digital(0) # 继电器输出低电平 is_auto_mode = 1 # 定义一个标志位--自动模式,1为开,0为关 def click_C(): # 定义点击按钮C时的操作--切换模式 global is_auto_mode if is_auto_mode == 0: # 如果自动模式标志位为0, 即原来为手动模式,那么点击后 text_mode.config(text="自动") button_A.config(state='disabled') # 设置按钮状态为disabled,表示无法点击 button_B.config(state='disabled') is_auto_mode = 1 # 设置自动模式标志位为1 ,即打开自动模式 elif is_auto_mode == 1: # 如果自动模式标准位为1, 即原来为自动模式,那么点击后 text_mode.config(text="手动") button_A.config(state='normal') # 设置按钮状态为normal,表示可以被点击 button_B.config(state='normal') is_auto_mode = 0 # 设置自动模式标志位为0 ,即打开手动模式 # 绘制填充矩形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") # 绘制矩形以显示光线值数据gui.fill_rect(x=100, y=160, w=70, h=30, color="white") # 绘制矩形显示“当前模式”gui.fill_rect(x=180, y=160, w=50, h=30, color="white") # 绘制矩形显示模式类型 # 在矩形框内显示文字gui.draw_text(x=68, y=36, color="red", text='光线值') # 显示文字“光线值”text_value = gui.draw_text(x=155, y=36, color="red", text="") # 显示光线值数据gui.draw_text(x=105, y=163, color="red", text='当前模式:', font_size=11) # 显示文字“当前模式:”text_mode = gui.draw_text(x=190, y=163, color="red", text="自动", font_size=11) # 显示模式类型 # 显示按钮'''显示按钮并设置按钮点击后触发的功能,以及按钮初始时处于不可被点击状态'''button_A = gui.add_button(x=50, y=260, w=70, h=40,text="开灯", onclick=click_A, state='disabled')button_B = gui.add_button(x=140, y=260, w=70, h=40,text="关灯", onclick=click_B, state='disabled')button_C = gui.add_button(x=10, y=160, w=70, h=30,text="切换模式", onclick=click_C) # 定义光线值较低时自动开灯def auto_light(): '''定义光线值较低时自动开灯''' if Light< 666: click_A() else: click_B() while True: # 循环 Light = light.read() # 读取光线值 print(Light) # 打印显示光线值 siot.publish(IOT_pubTopic2, Light) # 发布信息至物联网平台 if is_auto_mode == 1: auto_light() # 自动补水 text_value.config(text=Light) # 更新光线值 time.sleep(1) # delay1秒

3、程序运行

STEP1:运行观察效果

点击Mind+软件上的运行按钮,观察行空板2,可以看到板2界面如下,能在手动和自动两个模式下控制补光(打开LED),也可以在浏览器中输入SIoT服务器所在的行空板的IP地址(此处为“192.168.43.201”),打开网页应用中的SIoT,从物联网平台远程查看光线值数据并进行补光等操作。

注意板2的Topic与板1的Topic不同,需要返回设备列表操作名称为“light”的项目。

poYBAGKz3XGAAt6TAAB0Ace28Yk297.pngpYYBAGKz3XKALuiqAABhHy6O-7g568.pngpoYBAGKz3XKAMgHjAAB4j1sN6S0885.pngpYYBAGKz3XKAPHg4AABkltXlWbA971.pngpoYBAGKz3XKAXIsTAAAz-w5Ru48313.jpg

Tips:只有手动模式下发送消息才有效

任务描述4:行空板3远程监控

这里,我们将行空板3作为总站,接收行空板1和行空板2发送到SIoT物联网平台上的土壤湿度和光线值数据,然后汇总显示在板3的屏幕上,并通过板3上的按钮来对板1 和板2进行控制,实现各自的浇水、关水、开灯、关灯功能。

同时,在板3上设定自动和手动两个模式开关按钮,分别用来控制板1和板2两个模式的切换,初始时默认为自动模式。

此外,最重要的,板3的总站也可以对接收到的数据进行实时判别,当某一环境数据不佳时,远程发送一封邮件至邮箱作为警报提示,以便我们能及时获取信息并进行浇水补光。

1、邮箱设置

STEP1:记录qq邮箱授权码

(1)打开qq邮箱,点击页面上方的“设置”

pYYBAGKz3XKAbKZqAAAlDQR3ijQ542.jpg

(2)开启SMTP服务,生成授权码并记录

Tips:需要通过手机发送验证短信,生成授权码

poYBAGKz3XKAO4I5AABVCSLJHYM838.jpgpYYBAGKz3XOAHfZ6AABD6MrtkMw097.jpg

(3)微信开启QQ邮箱提醒

这里,为了方便查看邮件,我们也可在微信上开启QQ邮箱提醒功能。

poYBAGKz3XOACfO9AABA1wau91I035.png

Tips:具体操作方法可参考一下链接:https://kf.qq.com/touch/faq/1506 ... Uz.html?platform=14

2、程序编写

STEP1:创建与保存项目文件

再启动一个Mind+软件,另存项目并命名为“010、多节点智慧农业系统03”。

STEP2:远程连接行空板

(1)选择“手动输入”

(2)输入行空板3 的无线连接IP地址“192.168.43.201”

STEP3:直接在行空板3中创建一个新的文件夹,并命名为“多节点智慧农业系统”

STEP4:创建与保存Python文件

在“多节点智慧农业系统”文件夹中创建一个Python程序文件“main3.py”,双击打开。

pYYBAGKz3XOAJsA2AAA8b318ue8209.jpg

Step5:程序编写

(1)导入功能库

这里,为了能成功发送邮件,我们首先需要导入smtplib库,同时,在构造邮件时,我们需要处理文本,以及将输入的内容格式化,那么我们还需导入MIMEText模块和formataddr模块。

from unihiker import GUI # 导入unihiker库GUI模块import time # 导入time库import siot # 导入siot库import smtplib # 导入smtplib库from email.mime.text import MIMEText # 导入email.mime.text库MIMEText模块,负责处理文本from email.utils import formataddr # 导入email.utils库formataddr模块,负责将输入的内容格式化

(2)设置物联网平台连接参数

接着,由于我们将接收板1和板2发送到物联网平台的数据,因此我们需要先设置好物联网平台的连接参数,以便后续订阅。

'''设置物联网平台连接参数'''SERVER = "192.168.43.201" # MQTT服务器IP地址,输入个人实际IPCLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic1 = '多节点智慧农业系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称”IOT_pubTopic2 = '多节点智慧农业系统/light' # 光强topic,“项目名称/设备名称”

(3)显示屏幕页面

之后,我们在行空板3的屏幕上显示四部分内容,首先是板1和板2 的湿度值和光线值数据;其次是对数据进行判别后的情况分析,比如在屏幕上显示“当前土壤湿度适当”、“当前光线强度适当”;接着是模式切换按钮和当前模式的显示;最后是手动模式下的四个按钮控件。而在按钮中,我们通过定义回调函数的方式,来设定其功能。

'''显示屏幕页面''' # 定义五个按钮的回调函数def click_A(): # 定义点击按钮A时的操作--切换图片 siot.publish(IOT_pubTopic1, 'relay on') # 发布信息'relay on'至物联网平台 def click_B(): # 定义点击按钮B时的操作--切换图片 siot.publish(IOT_pubTopic1, 'relay off') # 发布信息'relay off'至物联网平台 def click_C(): # 定义点击按钮C时的操作--切换图片 siot.publish(IOT_pubTopic2, 'led on') # 发布信息'led on'至物联网平台 def click_D(): # 定义点击按钮D时的操作--切换图片 siot.publish(IOT_pubTopic2, 'led off') # 发布信息'led off'至物联网平台 is_auto_mode = 1 # 定义一个标志位--自动模式,1为开,0为关 def click_E(): # 定义点击按钮E时的操作--切换模式 global is_auto_mode if is_auto_mode == 0: text_mode.config(text="自动") button_A.config(state='disabled') button_B.config(state='disabled') button_C.config(state='disabled') button_D.config(state='disabled') siot.publish(IOT_pubTopic1, 'auto') # 发布信息'auto'至物联网平台 siot.publish(IOT_pubTopic2, 'auto') # 发布信息'auto'至物联网平台 is_auto_mode = 1 elif is_auto_mode == 1: text_mode.config(text="手动") button_A.config(state='normal') button_B.config(state='normal') button_C.config(state='normal') button_D.config(state='normal') siot.publish(IOT_pubTopic1, 'manual') # 发布信息'manual'至物联网平台 siot.publish(IOT_pubTopic2, 'manual') # 发布信息'manual'至物联网平台 is_auto_mode = 0 gui=GUI() # 实例化gui对象 # 显示填充矩形gui.fill_rect(x=0, y=0, w=240, h=320, color="#99CCFF") # 绘制填充矩形显示为背景# 显示标题title = gui.draw_text(x=30, y=5, text='多节点智慧农业系统', font_size=14, color='blue') # 显示part1数据(圆角矩形、文字)gui.draw_round_rect(x=20, y=33, w=200, h=42, r=8, width=1) # 显示圆角矩形,(起点坐标(20,33),宽200,高42,圆角半径8,线宽1)gui.draw_text(x=35, y=32, text='湿度值:', font_size=11) # 显示文字“湿度值:”text_value = gui.draw_text(x=110, y=32, color="red", text="", font_size=12) # 显示光线值数据gui.draw_text(x=35, y=52, text='光线值:', font_size=11) # 显示文字“光线值”text_value_2 = gui.draw_text(x=110, y=52, color="red", text="", font_size=12) # 显示光线值数据 # 显示part2数据情况(圆角矩形、文字)gui.draw_round_rect(x=20, y=80, w=200, h=80, r=8,width=1)text1 = gui.draw_text(x=30, y=80, text='土壤湿度情况:', font_size=11, color='black') # 在(30,60)坐标位显示“土壤湿度情况:”,字体大小为11,颜色为黑text2 = gui.draw_text(x=30, y=98, text='当前土壤湿度适当', font_size=12, color='red')text3 = gui.draw_text(x=30, y=120, text='光线强度情况:', font_size=11, color='black')text4 = gui.draw_text(x=30, y=138, text='当前光线强度适当', font_size=12, color='red') # 显示part3切换模式功能(圆角矩形、按钮、文字)gui.draw_round_rect(x=20, y=165, w=200, h=40, r=8,width=1)button_E = gui.add_button(x=30, y=170, w=70, h=30, text="切换模式", onclick=click_E)gui.draw_text(x=110, y=173, text='当前模式:', font_size=11) # 显示文字“当前模式:”text_mode = gui.draw_text(x=178, y=173, color="red", text="自动", font_size=12) # 显示模式类型 # 显示part4手动控制模式(圆角矩形、按钮、文字)gui.draw_round_rect(x=20, y=210, w=200, h=105, r=8,width=1)gui.draw_text(x=33, y=213, text='手动控制:',font_size=11) # 显示文字“手动控制:”button_A = gui.add_button(x=30, y=240, w=70, h=30, text="浇水", onclick=click_A,state='disabled')button_B = gui.add_button(x=140, y=240, w=70, h=30, text="关水", onclick=click_B,state='disabled')button_C = gui.add_button(x=30, y=280, w=70, h=30, text="开灯", onclick=click_C,state='disabled')button_D = gui.add_button(x=140, y=280, w=70, h=30, text="关灯", onclick=click_D,state='disabled')

(4)邮件设置

接下来,我们将定义邮件发送功能,首先设置好发送邮件所需的参数,包括发件人邮箱账号,发件人邮箱授权码,发件人邮箱昵称,收件人邮箱账号,收件人邮箱昵称总计五个参数。之后,定义一个发送邮件的函数,在其中将邮件内容和标题作为参数传入,以便能多次调用以发送邮件。

Tips:须填入实际的发件人账号、授权码信息,昵称可随意编写,但不可为空。

'''邮件设置'''my_sender='10******69@qq.com' # 设置发件人邮箱账号,输入自己的邮箱my_pass = '******' # 设置发件人邮箱授权码,不可为空my_name = 'IvanD.Mido' # 设置发件人邮箱昵称my_user='10******69@qq.com' # 设置收件人邮箱账号,我这边发送给自己my_user_name = 'IvanD.Mido' # 设置收件人邮箱昵称 # 定义警报发邮件函数def mail(content,title): ret=True # 定义一个标记ret,记录发送邮件事件,初始值为True try: msg=MIMEText(content,'plain','utf-8') # 创建邮件文本对象,Title对应文本内容,'plain'指设置的文本格式,'utf-8'指设置的编码 '''三个头部信息:发件人,收件人,主题''' msg['From']=formataddr([my_name,my_sender]) # 定义发件人信息:括号里的对应发件人邮箱昵称、发件人邮箱账号 msg['To']=formataddr([my_user_name,my_user]) # 定义收件人信息:括号里的对应收件人邮箱昵称、收件人邮箱账号 msg['Subject']=title # 定义邮件的主题,也可以说是标题 server=smtplib.SMTP_SSL("http://smtp.qq.com", 465) # 创建SMTP服务,连接qq邮箱服务器,发件人邮箱中的SMTP服务器,SMTP协议加密端口是465 server.login(my_sender, my_pass) # 登录邮箱,括号中对应的是发件人邮箱账号、邮箱密码 server.sendmail(my_sender,my_user,msg.as_string()) # 发送邮件,括号中对应的是发件人邮箱账号、收件人邮箱账号、邮件信息的字符串格式 server.quit() # 关闭连接 except Exception: # 如果 try 中的语句没有执行,则会执行下面的 ret=False ret=False # 将ret标记记为False return ret # 返回ret标记

(6)定义回调函数

由于发送邮件是在检测到板1和板2 的数据不佳的情况下进行,因此,我们需要先设定接收到SIoT物联网平台的数据时的功能操作。

当接收到Topic1下的土壤湿度的数据后,我们做三步处理,首先是将数据呈现在屏幕上,其次是对数据进行判别,于屏幕更新显示判别分析后的情况,最后是依据判别结果,当结果数据不佳时设定发送一封警报邮件,并且每封主题邮件之间的间隔不少于10s。

而当接收到Topic2下的光线值数据后,我们做同样的处理。

Tips:这里的邮件发送频率可自行修改。

soil_mail_enable = True # 定义发送土壤警报邮件使能的标志light_mail_enable = True # 定义发送光线警报邮件使能的标志 soil_mail_time = time.time() # 定时邮件发送时间记录标志light_mail_time = time.time() # 定时邮件发送时间记录标志 # 定义回调函数def sub_cb(client, userdata, msg): global soil_mail_enable,light_mail_enable,soil_mail_time,light_mail_time topic = msg.topic # topic数据存入变量 payload = msg.payload.decode() # payload消息数据转换为字符串后存入变量 print("\nTopic:" + topic + " Message:" + payload) # 终端打印数据 if topic == IOT_pubTopic1: # 定义接收到Soil_moisture_value时的操作 if payload.isdigit(): # 接收的消息是数字类型的则说明是湿度值而不是控制命令 Soil_moisture_value = int(payload) # 转换为数字类型方便后面做判断 text_value.config(text = str(Soil_moisture_value)) # 更新屏幕显示数据 if Soil_moisture_value < 2120: # 阈值设置为2120,可根据实际情况调整 text2.config(text="当前土壤湿度过低") # 更新文字警告 if soil_mail_enable == True and (time.time()-soil_mail_time) > 10: # 如果允许且距离上次发送邮件时间间隔10秒以上才进行发送的操作 ret1=mail("土壤湿度报警","当前土壤湿度值为 " + str(Soil_moisture_value) + ",请及时补水!") if ret1: # 如果有发送邮件事件 print("邮件发送成功1") soil_mail_enable = False # 已经发送过邮件,改变标记避免重复发送 soil_mail_time = time.time() # 记录本次邮件发送的时间 else: # 否则 print("邮件发送失败1") else: text2.config(text="当前土壤湿度适当") # 更新文字 soil_mail_enable = True # 如果警报解除了就允许后续发邮件 elif topic == IOT_pubTopic2: # 定义接收到Light时的操作 if payload.isdigit(): # 接收的消息是数字类型的则说明是光线值而不是控制命令 light_value = int(payload) # 转换为数字类型方便后面做判断 text_value_2.config(text = str(light_value)) # 屏幕更新光线值 if light_value < 666: # 阈值设置为666,可根据实际情况调整 text4.config(text="当前光线强度过低") # 更新文字警告 if light_mail_enable == True and (time.time()-light_mail_time) > 10: # 如果允许发送邮件才进行发送的操作 ret2=mail("光线强度报警","当前光线值为 " + str(light_value) + ",请及时补光!") if ret2: # 如果有发送邮件事件 print("邮件发送成功2") light_mail_enable = False # 已经发送过邮件,改变标记避免重复发送 light_mail_time = time.time() # 记录本次邮件发送的时间 else: # 否则 print("邮件发送失败2") else: text4.config(text="当前光线强度适当") # 更新文字警告 light_mail_enable = True # 如果警报解除了就允许后续发邮件

(7)订阅物联网平台消息

在定义好回调函数后,我们设定板3订阅物联网平台的消息,并在开始时发送“auto”至两个Topic下,以便设定起始默认模式为自动。

siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接siot物联网平台siot.subscribe(IOT_pubTopic1, sub_cb) # 订阅Topic1 土壤湿度数据siot.subscribe(IOT_pubTopic2, sub_cb) # 订阅Topic2 光线强度数据siot.publish(IOT_pubTopic1,'auto') #发布信息'auto'至物联网平台
siot.publish(IOT_pubTopic2,'auto') #发布信息'auto'至物联网平台siot.loop() # 循环

(8)循环保持程序运行

while True: # 循环 time.sleep(0.5) # delay0.5秒

Tips:完整示例程序如下:

'''板3订阅板1&板2发送到物联网平台的消息,显示在板3上,数值不佳时警报发邮件'''from unihiker import GUI # 导入unihiker库GUI模块import time # 导入time库import siot # 导入siot库import smtplib # 导入smtplib库from email.mime.text import MIMEText # 导入email.mime.text包中的MIMEText模块,负责处理文本from email.utils import formataddr # 导入email.utils包中的formataddr模块,负责将输入的内容格式化 '''设置物联网平台连接参数'''SERVER = "192.168.43.201" # MQTT服务器IP地址,输入个人实际IPCLIENT_ID = "" # 在SIoT上,CLIENT_ID可以留空IOT_UserName = 'siot' # 用户名IOT_PassWord = 'dfrobot' # 密码IOT_pubTopic1 = '多节点智慧农业系统/Soil_moisture_value' # 湿度topic,“项目名称/设备名称”IOT_pubTopic2 = '多节点智慧农业系统/light' # 光强topic,“项目名称/设备名称” # 定义五个按钮的回调函数def click_A(): # 定义点击按钮A时的操作--切换图片 siot.publish(IOT_pubTopic1, 'relay on') # 发布信息'relay on'至物联网平台 def click_B(): # 定义点击按钮B时的操作--切换图片 siot.publish(IOT_pubTopic1, 'relay off') # 发布信息'relay off'至物联网平台 def click_C(): # 定义点击按钮C时的操作--切换图片 siot.publish(IOT_pubTopic2, 'led on') # 发布信息'led on'至物联网平台 def click_D(): # 定义点击按钮D时的操作--切换图片 siot.publish(IOT_pubTopic2, 'led off') # 发布信息'led off'至物联网平台 is_auto_mode = 1 # 定义一个标志位--自动模式,1为开,0为关 def click_E(): # 定义点击按钮E时的操作--切换模式 global is_auto_mode if is_auto_mode == 0: text_mode.config(text="自动") button_A.config(state='disabled') button_B.config(state='disabled') button_C.config(state='disabled') button_D.config(state='disabled') siot.publish(IOT_pubTopic1, 'auto') # 发布信息'auto'至物联网平台 siot.publish(IOT_pubTopic2, 'auto') # 发布信息'auto'至物联网平台 is_auto_mode = 1 elif is_auto_mode == 1: text_mode.config(text="手动") button_A.config(state='normal') button_B.config(state='normal') button_C.config(state='normal') button_D.config(state='normal') siot.publish(IOT_pubTopic1, 'manual') # 发布信息'manual'至物联网平台 siot.publish(IOT_pubTopic2, 'manual') # 发布信息'manual'至物联网平台 is_auto_mode = 0 '''显示屏幕页面'''gui=GUI() # 实例化gui对象 # 显示填充矩形gui.fill_rect(x=0, y=0, w=240, h=320, color="#99CCFF") # 绘制填充矩形显示为背景# 显示标题title = gui.draw_text(x=30, y=5, text='多节点智慧农业系统', font_size=14, color='blue') # 显示part1数据(圆角矩形、文字)gui.draw_round_rect(x=20, y=33, w=200, h=42, r=8, width=1) # 显示圆角矩形,(起点坐标(20,33),宽200,高42,圆角半径8,线宽1)gui.draw_text(x=35, y=32, text='湿度值:', font_size=11) # 显示文字“湿度值:”text_value = gui.draw_text(x=110, y=32, color="red", text="", font_size=12) # 显示光线值数据gui.draw_text(x=35, y=52, text='光线值:', font_size=11) # 显示文字“光线值”text_value_2 = gui.draw_text(x=110, y=52, color="red", text="", font_size=12) # 显示光线值数据 # 显示part2数据情况(圆角矩形、文字)gui.draw_round_rect(x=20, y=80, w=200, h=80, r=8,width=1)text1 = gui.draw_text(x=30, y=80, text='土壤湿度情况:', font_size=11, color='black') # 在(30,60)坐标位显示“土壤湿度情况:”,字体大小为11,颜色为黑text2 = gui.draw_text(x=30, y=98, text='当前土壤湿度适当', font_size=12, color='red')text3 = gui.draw_text(x=30, y=120, text='光线强度情况:', font_size=11, color='black')text4 = gui.draw_text(x=30, y=138, text='当前光线强度适当', font_size=12, color='red') # 显示part3切换模式功能(圆角矩形、按钮、文字)gui.draw_round_rect(x=20, y=165, w=200, h=40, r=8,width=1)button_E = gui.add_button(x=30, y=170, w=70, h=30, text="切换模式", onclick=click_E)gui.draw_text(x=110, y=173, text='当前模式:', font_size=11) # 显示文字“当前模式:”text_mode = gui.draw_text(x=178, y=173, color="red", text="自动", font_size=12) # 显示模式类型 # 显示part4手动控制模式(圆角矩形、按钮、文字)gui.draw_round_rect(x=20, y=210, w=200, h=105, r=8,width=1)gui.draw_text(x=33, y=213, text='手动控制:',font_size=11) # 显示文字“手动控制:”button_A = gui.add_button(x=30, y=240, w=70, h=30, text="浇水", onclick=click_A,state='disabled')button_B = gui.add_button(x=140, y=240, w=70, h=30, text="关水", onclick=click_B,state='disabled')button_C = gui.add_button(x=30, y=280, w=70, h=30, text="开灯", onclick=click_C,state='disabled')button_D = gui.add_button(x=140, y=280, w=70, h=30, text="关灯", onclick=click_D,state='disabled') '''邮件设置'''my_sender='10******69@qq.com' # 设置发件人邮箱账号,输入自己的邮箱my_pass = '' # 设置发件人邮箱授权码,不可为空my_name = 'IvanD.Mido' # 设置发件人邮箱昵称my_user='10******69@qq.com' # 设置收件人邮箱账号,我这边发送给自己my_user_name = 'IvanD.Mido' # 设置收件人邮箱昵称 # 定义警报发邮件函数def mail(content,title): ret=True # 定义一个标记ret,记录发送邮件事件,初始值为True try: msg=MIMEText(content,'plain','utf-8') # 创建邮件文本对象,Title对应文本内容,'plain'指设置的文本格式,'utf-8'指设置的编码 '''三个头部信息:发件人,收件人,主题''' msg['From']=formataddr([my_name,my_sender]) # 定义发件人信息:括号里的对应发件人邮箱昵称、发件人邮箱账号 msg['To']=formataddr([my_user_name,my_user]) # 定义收件人信息:括号里的对应收件人邮箱昵称、收件人邮箱账号 msg['Subject']=title # 定义邮件的主题,也可以说是标题 server=smtplib.SMTP_SSL("http://smtp.qq.com", 465) # 创建SMTP服务,连接qq邮箱服务器,发件人邮箱中的SMTP服务器,SMTP协议加密端口是465 server.login(my_sender, my_pass) # 登录邮箱,括号中对应的是发件人邮箱账号、邮箱密码 server.sendmail(my_sender,my_user,msg.as_string()) # 发送邮件,括号中对应的是发件人邮箱账号、收件人邮箱账号、邮件信息的字符串格式 server.quit() # 关闭连接 except Exception: # 如果 try 中的语句没有执行,则会执行下面的 ret=False ret=False # 将ret标记记为False return ret # 返回ret标记 soil_mail_enable = True # 定义发送土壤警报邮件使能的标志light_mail_enable = True # 定义发送光线警报邮件使能的标志 soil_mail_time = time.time() # 定时邮件发送时间记录标志light_mail_time = time.time() # 定时邮件发送时间记录标志 # 定义回调函数def sub_cb(client, userdata, msg): global soil_mail_enable,light_mail_enable,soil_mail_time,light_mail_time topic = msg.topic # topic数据存入变量 payload = msg.payload.decode() # payload消息数据转换为字符串后存入变量 print("\nTopic:" + topic + " Message:" + payload) # 终端打印数据 if topic == IOT_pubTopic1: # 定义接收到Soil_moisture_value时的操作 if payload.isdigit(): # 接收的消息是数字类型的则说明是湿度值而不是控制命令 Soil_moisture_value = int(payload) # 转换为数字类型方便后面做判断 text_value.config(text = str(Soil_moisture_value)) # 更新屏幕显示数据 if Soil_moisture_value < 2120: # 阈值设置为2120,可根据实际情况调整 text2.config(text="当前土壤湿度过低") # 更新文字警告 if soil_mail_enable == True and (time.time()-soil_mail_time) > 10: # 如果允许且距离上次发送邮件时间间隔10秒以上才进行发送的操作 ret1=mail("土壤湿度报警","当前土壤湿度值为 " + str(Soil_moisture_value) + ",请及时补水!") if ret1: # 如果有发送邮件事件 print("邮件发送成功1") soil_mail_enable = False # 已经发送过邮件,改变标记避免重复发送 soil_mail_time = time.time() # 记录本次邮件发送的时间 else: # 否则 print("邮件发送失败1") else: text2.config(text="当前土壤湿度适当") # 更新文字 soil_mail_enable = True # 如果警报解除了就允许后续发邮件 elif topic == IOT_pubTopic2: # 定义接收到Light时的操作 if payload.isdigit(): # 接收的消息是数字类型的则说明是光线值而不是控制命令 light_value = int(payload) # 转换为数字类型方便后面做判断 text_value_2.config(text = str(light_value)) # 屏幕更新光线值 if light_value < 666: # 阈值设置为666,可根据实际情况调整 text4.config(text="当前光线强度过低") # 更新文字警告 if light_mail_enable == True and (time.time()-light_mail_time) > 10: # 如果允许发送邮件才进行发送的操作 ret2=mail("光线强度报警","当前光线值为 " + str(light_value) + ",请及时补光!") if ret2: # 如果有发送邮件事件 print("邮件发送成功2") light_mail_enable = False # 已经发送过邮件,改变标记避免重复发送 light_mail_time = time.time() # 记录本次邮件发送的时间 else: # 否则 print("邮件发送失败2") else: text4.config(text="当前光线强度适当") # 更新文字警告 light_mail_enable = True # 如果警报解除了就允许后续发邮件 siot.init(CLIENT_ID, SERVER, user=IOT_UserName,password=IOT_PassWord) # 初始化,确定输入的用户名和密码正确siot.connect() # 连接siot物联网平台siot.subscribe(IOT_pubTopic1, sub_cb) # 订阅Topic1 土壤湿度数据siot.subscribe(IOT_pubTopic2, sub_cb) # 订阅Topic2 光线强度数据siot.publish(IOT_pubTopic1,'auto') #发布信息'auto'至物联网平台
siot.publish(IOT_pubTopic2,'auto') #发布信息'auto'至物联网平台siot.loop() # 循环 while True: # 循环 time.sleep(0.5) # delay0.5秒

Tips:须填入实际的发件人账号、授权码等信息,不可为空。

3、程序运行

STEP1:运行程序观察效果

点击Mind+软件上的运行按钮,观察行空板3,可以看到初始时模式为自动,此时浇水、关水、开灯、关灯四个按钮为灰色,不可被点击,点击切换模式后,按钮恢复正常状态,同时检测到的土壤湿度值和光线值数据也显示在了屏幕上。此时,在板3上点击“浇水”和“开灯”后,板1上的水泵开始工作,板2上的LED亮起。当点击“关水”和“关灯”后,水泵和LED则停止了工作。

pYYBAGKz3W2AWrp-AABkM_aagt4894.pngpoYBAGKz3W2ANgPBAABjCmlBDaA013.pngpYYBAGKz3W2ADtjLAABld5nJ7VY237.pngpoYBAGKz3W2AHdIPAABkEzpVImg409.png

观察物联网平台,可以看到在两个不同的Topic下,皆有数据传入。

pYYBAGKz3W2APFTuAAAanbvJOwg490.jpgpoYBAGKz3XOABQ8SAAAy4bQDe8M822.jpgpYYBAGKz3XOAWtsjAAArO0uTILU417.jpg

同时,观察QQ邮箱,当土壤湿度或光线值数据不佳时,我们会接收到一封邮件。

poYBAGKz3W6AaHdHAABGrAAtiAc355.jpgpYYBAGKz3W6AdjcbAABGXVwUVIs967.jpg

Tip1:这里,由于我们直接将Python程序文件建在了行空板的内存中,因此,我们也可以直接在板子上运行程序,以板3为例,操作方法如下:

poYBAGKz3XOAD3YiAABWFDLegdM906.jpg

Tip2:这里的路由器或手机热点须能正常上网,方可发送邮件。

挑战自我

想一想,在本节课介绍的三种给行空板供电的方式中(电源适配器、充电宝、电脑USB口),对于需要长期运行程序的场景,该选择哪种方式更适合呢,而对于需要在户外使用的场景,又适合哪种方式呢?

除了发邮件警报作为一种手段之外,还可以有哪些可行的远程提醒的方法呢?

在既没有路由器,也没有手机热点的场景下,我们还能搭建多节点的物联网系统吗?

Tips:答案见附录2。

附录

附录2:

在既没有路由器和手机也无法开热点的情况下,我们也可以通过开启其中一块行空板自身的热点功能创建一个Wi-Fi无线热点,其他行空板都连接这个Wi-Fi热点,来使各块板子连在同一局域网内。开启方法如下。

pYYBAGKz3XOAPjeIAABm0DDTkRg060.jpg
  • 物联网
    +关注

    关注

    2816

    文章

    31941

    浏览量

    331770
  • 温湿度传感器

    关注

    3

    文章

    440

    浏览量

    31107
  • python
    +关注

    关注

    47

    文章

    2715

    浏览量

    74816
  • IOT
    IOT
    +关注

    关注

    87

    文章

    2954

    浏览量

    162329
  • 智慧农业
    +关注

    关注

    4

    文章

    510

    浏览量

    17603
收藏 人收藏

    评论

    相关推荐

    NETWORKX Python编程语言软件包概述及用途

    NetworkX 是一个 Python 编程语言软件包,可用于创建、操作和学习复杂图形网络的结构、动....
    的头像 NVIDIA英伟达 发表于 07-01 11:30 20次 阅读

    智能工厂数采方案

    两化融合物联网系统是智能工厂的核心,透过信息收集、分析及可视化进行实时管理,物通博联提供完整的物联网....
    发表于 07-01 10:56 8次 阅读

    Python2.7和Python3.2有什么区别

    Python2.7中input函数的参数是合法的Python表达式,所以参数是字符串时,要输入双/....
    发表于 07-01 10:53 6次 阅读

    工业PDA的应用行业及解决方案

    近年来,全球市场环境风云变幻,继互联网技术后的新兴物联网技术迎来迅猛发展,赋予了千行百业新的内涵与动....
    的头像 1655199132.853000 发表于 07-01 10:23 18次 阅读

    用于嵌入式系统的Java的优点和缺点

      在嵌入式系统上使用 Java 的优点多于缺点,特别是因为代码的质量和大量已经能够使用 Java ....
    的头像 星星科技指导员 发表于 07-01 10:00 20次 阅读

    简化嵌入式物联网应用程序的软件开发

    这是通过在硬件和软件堆栈中主动和无缝集成嵌入式和连接设备来实现的。MCU 和无线设备的这种集成是紧凑....
    的头像 星星科技指导员 发表于 07-01 09:53 28次 阅读
    简化嵌入式物联网应用程序的软件开发

    用于物联网开发的方便且免费使用的IDE

      RT-Thread Studio 内部集成了丰富的优质可复用代码资源。经过简单的配置,开发者就可....
    的头像 星星科技指导员 发表于 07-01 09:13 59次 阅读

    互联网时代下的STEAM教育创新之路

    前段时间印发的《全民科学素质行动规划纲要(2021-2035年)》也提到了科学素质是国民素质的重要组....
    的头像 格物斯坦机器人 发表于 06-30 18:20 2次 阅读

    市数字政府服务中心领导一行莅临诚迈科技参观考察

    6月28日,山西省大同市副市长孟维君,市政府副秘书长、市数字政府服务中心主任韩杰,市政府副秘书长高旭....
    的头像 科技绿洲 发表于 06-30 16:10 210次 阅读

    水肥一体化自动控制机的物联网应用

    现场的水肥一体化自动控制机的控制器PLC通过网口或串口与WG585工业智能网关连接,分布在农田各地的....
    发表于 06-30 14:45 4次 阅读

    如何让IoT产品更好便于企业运营管理

    物联网(IoT)产品的快速更新迭代,使得很多研发出来的产品越来越频繁地进行技术升级。尤其在当下,一个....
    发表于 06-30 14:44 66次 阅读

    TPM 2.0如何在坚固的边缘计算机中实现基础安全

      最后,当嵌入式系统设计人员转向操作系统层时,Microsoft Windows 10 IoT具有....
    的头像 星星科技指导员 发表于 06-30 14:39 120次 阅读

    企业如何在移动应用开发中利用人工智能

      一些专家坚持认为,人工智能和区块链的实施应该主要进行,同时考虑到用户的安全。但是,这些技术可以解....
    发表于 06-30 11:31 73次 阅读

    基于Python对微信好友进行数据分析

    同平时登录网页版微信一样,我们使用手机扫描二维码就可以登录,这里返回的friends对象是一个集合,....
    的头像 马哥Linux运维 发表于 06-30 11:17 112次 阅读

    满足日益增长的硬件安全需求

      下一个级别,TrustFLEXv,提供了使用客户选择的证书颁发机构的灵活性,同时仍然受益于预配置....
    的头像 星星科技指导员 发表于 06-30 10:57 104次 阅读

    能源物联网平台方案详解

    Acrel-EIoT能源物联网开放平台是一套基于物联网数据中台,建立统一的上下行数据标准,为互联网用....
    的头像 h1654156073.1491 发表于 06-30 10:48 39次 阅读
    能源物联网平台方案详解

    超越实时嵌入式调试的范围

      因为数据很容易以易于使用、人类可读的数据格式导出到 PC 终端,从而帮助工程师快速捕获波形并分析....
    的头像 星星科技指导员 发表于 06-30 10:47 109次 阅读
    超越实时嵌入式调试的范围

    EIoT能源物联网开放平台的主要功能介绍

    Acrel-EIoT 能源物联网开放平台是一套基于物联网数据中台,建立了上下行数据标准,为互联网用户....
    的头像 h1654156073.1491 发表于 06-30 10:44 36次 阅读
    EIoT能源物联网开放平台的主要功能介绍

    实时操作系统RTOS的介绍

      RTOS 是确保嵌入式设备(例如用于物联网、机器人和移动设备)的可预测和及时执行的关键组件。因此....
    的头像 星星科技指导员 发表于 06-30 10:43 104次 阅读

    物联网数据库管理注意事项

      在物联网边缘设备上收集和管理的数据量不断增长,这对物联网工程师和数据库管理系统供应商必须不断研究....
    发表于 06-30 10:18 90次 阅读
    物联网数据库管理注意事项

    机智云AIoT开发及云服务平台助力数字化转型升级

    物联网(IoT)产品的快速更新迭代,使得很多研发出来的产品越来越频繁地进行技术升级。尤其在当下,一个....
    的头像 机智云物联网 发表于 06-30 10:15 51次 阅读

    如何合规性为嵌入式市场中平衡敏捷过渡

    在一个敏捷性需要与合规性共存的世界中,很高兴知道这是绝对可能的,只要通过正确的文化、工具和流程来解决....
    的头像 星星科技指导员 发表于 06-30 09:36 42次 阅读

    国内物联网专利授权再进击!华为全球授权量超11万,oppo国内排名第三

    电子发烧友网报道(文/莫婷婷、章鹰)近年来,关于产品核心知识产权的竞争不在少数,专利已经成为同行竞争....
    的头像 Monika观察 发表于 06-30 08:40 712次 阅读
    国内物联网专利授权再进击!华为全球授权量超11万,oppo国内排名第三

    物联网初创企业会遇到的四个坑儿

    大部分初创企业缺少有能力的技术人员,以至于软件或硬件选型错误,结果就是走了很多弯路,产品迟迟不能落地....
    的头像 张杰一 发表于 06-30 08:11 227次 阅读

    基于RT-Thread设备运行数据分析预警系统

    本项目采用到硬件方案是:通过ART-Pi STM32H750主板上的I2C引脚和UART以及一个普通....
    的头像 极速紫韵 发表于 06-30 06:22 1252次 阅读
    基于RT-Thread设备运行数据分析预警系统

    智能玻璃温室助力打造现代化设施农业

    温室大棚,作为反季节作物种植的必备建筑物,广泛应用于经济附加值高的作物种植中。如今随着物联网技术的应....
    的头像 王工 发表于 06-29 17:19 168次 阅读

    大华股份智慧物联网产业园赋能数字经济建设

    数字工厂建设是浙江省以数字化改革为引领,深入实施数字经济“一号工程”2.0版,是引领数字产业化发展的....
    的头像 科技绿洲 发表于 06-29 17:15 352次 阅读

    python抓取公司信息

    现在正好是毕业且需要找工作的季节,在找工作的时候很多小伙伴都会一家一家的公司去看,这得多浪费时间啊。今天用Python教大家怎...
    发表于 06-29 16:54 502次 阅读

    高级流程节点使仿真必不可少

      就晶体管数量和复杂性而言,先进工艺节点的设计尺寸正在迅速增加。因此,Veloce Strato ....
    的头像 星星科技指导员 发表于 06-29 15:23 136次 阅读

    克服物联网用户体验设计的六大挑战

      要使物联网系统发挥其极限,用户需要完全信任底层数据。对于在高度敏感的环境中工作的用户,例如核电站....
    的头像 星星科技指导员 发表于 06-29 14:40 134次 阅读
    克服物联网用户体验设计的六大挑战

    使用SPARK和Ada进行代码清理

      Ada 和 SPARK 方法的独特之处在于它集成了软件规范、实现和验证,提供了一种以现代系统所需....
    的头像 星星科技指导员 发表于 06-29 14:33 127次 阅读
    使用SPARK和Ada进行代码清理

    如何为物联网项目选择合适的微控制器

    开源ISA允许不付许可费便能设计自己的处理器,而基于RISC-V ISA的设计可以像任何其它类型的I....
    发表于 06-29 14:27 269次 阅读

    物联网通信复习提纲

    物联网专业通信应用技术复习提纲
    发表于 06-29 14:23 7次 阅读

    定制HMI解决方案可解决工业自动化中复杂多样的需求

      通过访问有助于工业组织进行知情分析的数据,可以提高成本效益和持续改进流程。提供更全面的生产过程视....
    的头像 星星科技指导员 发表于 06-29 14:15 95次 阅读

    应用层提供互操作性的标准和开源计划

      Zigbee 已开始展示 Dotdot 跨不同连接堆栈的互操作性(如图 14 所示),在 CES....
    的头像 星星科技指导员 发表于 06-29 14:09 101次 阅读
    应用层提供互操作性的标准和开源计划

    嵌入式通信管理机的核心优势和作用

    摘要:随着物联网技术的发展,各种应用及系统推陈出新,不断更新换代,而通信管理机是系统的数据枢纽,在整....
    的头像 panqin888 发表于 06-29 12:33 54次 阅读

    应用系统应该使用哪种物联网协议

      这些协议中的每一个的高层定位都是相似的。除了 HTTP,所有提到的协议都被定位为支持数百万设备的....
    的头像 星星科技指导员 发表于 06-29 11:42 158次 阅读
    应用系统应该使用哪种物联网协议

    物联网设备的无线固件升级

      在为物联网应用选择组件时,研究芯片和开发工具支持的 OTA 固件升级方法非常重要。在评估具有内部....
    的头像 星星科技指导员 发表于 06-29 10:58 80次 阅读
    物联网设备的无线固件升级

    偿还安全关键型汽车软件的技术债务

      基线测试可以帮助减少现有代码库中的技术债务,让开发人员有信心重构和增强这些代码库,并最终让这些遗....
    发表于 06-29 10:50 87次 阅读

    物联网对数据中心基础设施构成严峻挑战

      这里的关键点是物联网设备需要正确的数据中心基础设施才能按预期工作。海量数据和不断下降的可接受延迟....
    发表于 06-29 10:16 83次 阅读

    系统模拟是一种对IoT应用程序进行压力测试的方法

      基于物联网的设计的另一个有趣方面是,尽管有数百或数千个节点,但占空比可能相当低。传感器不会不断地....
    的头像 星星科技指导员 发表于 06-29 10:09 126次 阅读
    系统模拟是一种对IoT应用程序进行压力测试的方法

    用于嵌入式设备的JavaScript

      这些开发系统中的每一个都是在嵌入式设备上开始 JavaScript 开发的好工具。尽管 Java....
    的头像 星星科技指导员 发表于 06-29 09:39 71次 阅读
    用于嵌入式设备的JavaScript

    装机1700万部!中移物联网OneOS在智能制造撕开口子 助力中国企业数字化转型

    在过去三年中,由于5G、AI技术快速发展,极大推动物联网的技术的进步,物联网操作系统取得了显着进步。....
    的头像 章鹰观察 发表于 06-29 08:24 1159次 阅读
    装机1700万部!中移物联网OneOS在智能制造撕开口子 助力中国企业数字化转型

    对物联网应用有用的继电器屏蔽PCB设计方案

    描述 对物联网应用有用的继电器屏蔽 PCB 设计 每个家庭都有电子设备,这些电子设备是我们日常生活的重要组成部分,如洗碗...
    发表于 06-29 06:59 38次 阅读

    涂鸦智能物联网设备解决方案合辑(一)

    全球510,000+开发者基于涂鸦开发各类IoT应用。涂鸦智能王学集要做的是揭中国制造业的根,打造最接地气的智能平台,实现智能产...
    发表于 06-28 16:54 551次 阅读
    涂鸦智能物联网设备解决方案合辑(一)

    机智云AIoT云平台推动各行业智能化升级

    机智云将超过10年时间、上万方案、千万级设备接入的物联网云平台建设经验,沉淀为工业级稳定、安全的AI....
    的头像 机智云物联网 发表于 06-28 16:27 218次 阅读

    如何在外包生产过程中保护软件

    根据经济合作与发展组织(OECD)的数据,假冒消费品占世界总体贸易的3%以上。调查结果显示,电子产品....
    的头像 科技绿洲 发表于 06-28 15:47 231次 阅读

    BOE(京东方)智慧楼宇解决方案助力华英证券实现智慧化办公

    近日,由BOE(京东方)打造的智慧楼宇解决方案在华英证券无锡总部、北京、上海、深圳、成都、武汉等地分....
    发表于 06-28 15:29 207次 阅读

    物联网的高效无线软件和固件更新

      SCOMO 仅限于管理和通信协议,将实际操作(如应用程序更新和设备刷新)的实现留给设备制造商。因....
    的头像 星星科技指导员 发表于 06-28 14:58 127次 阅读

    中软国际携手深开鸿等企业共同深耕开源鸿蒙“黑土地”

    数字化变革正在全球范围展开,一方面,中国政企的数字化转型进入了深水区,新一代信息技术与各垂直领域融合....
    发表于 06-28 11:22 147次 阅读

    为什么物联网在多种技术的支持下效果最好

      在医院、物流和供应链之外,还有大量利用 LoRa 和支持 BLE 的物联网技术的垂直领域,这些技....
    发表于 06-28 11:10 113次 阅读

    Python pacp模块——自动识别文字中的省市区并绘图

    一个用于提取简体中文字符串中省,市和区并能够进行映射,检验和简单绘图的python模块。 举个例子: [code]["徐汇区虹漕路...
    发表于 06-27 17:20 1185次 阅读

    让 python 循环语句具有C语言级别的性能

    Python 的 for 和 while 循环是灵活并且高级的,语法自然、读起来像伪代码。而 Cython 也支持 for 和 while,无需修改。但由于...
    发表于 06-24 16:02 2594次 阅读

    Python 一个超快的公共情报搜集爬虫——Photon

    Photon是一个由s0md3v开源的情报搜集爬虫,其主要功能有: 1.爬取链接(内链、外链)。 2.爬取带参数的链接,如(pythondict.com...
    发表于 06-23 16:35 172次 阅读

    Loguru — 一个强大的 Python 日志工具

    Loguru 安装方式很简单,打开终端输入: [code]pip install loguru[/code]1、即开即用 在Loguru中,如果你需要输出 debug 日...
    发表于 06-22 15:27 678次 阅读

    【物联网开发】正点原子STM32战舰v3+机智云AIoT+APP控制

    第一步:进入到机智云开发者中心,注册开发者账号,然后开始创建新产品。 图1创建新产品 图2创建新产品以及产品分类 设置好后...
    发表于 06-21 17:44 4389次 阅读

    简单分析爬虫中需要登陆的网站

    在爬虫工作过程中经常会遇到需要登录的问题,面对这样的问题就需要用到模拟登录的相关方法。python提供了强大的url库,想做到这...
    发表于 06-21 16:45 751次 阅读

    Addict 一个写起来令人极其舒适的字典模块

    Addit 是一个Python模块,除了提供标准的字典语法外,Addit 生成的字典的值既可以使用属性来获取,也可以使用属性进行设置。 ...
    发表于 06-21 16:13 1284次 阅读