本文主要是介绍MicroPython_ESP8266_IoT——第四回 初入联网(接入了贝壳物联),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第四回 初入联网(接入了贝壳物联)
本来计划先把所有的硬件介绍完,再介绍如何介入贝壳物联的。但是那样就比较枯燥,还是先尝试接入贝壳物联,来增加ESP8266模块的可玩性。
需要了解[贝壳物联平台通信协议](贝壳物联平台通讯协议-贝壳物联,让你与智能设备沟通更方便的物联网云平台 (bigiot.net)) ,如果不想了解,可以跳过通讯协议这小节,不影响后面学习,等到后面有疑问再来这小节里面寻找。
忘记说了,可以先去贝壳物联官网熟悉熟悉,最好自己注册账号,在后续试验中使用自己的设备;
通信协议
这里使用TCP(websocket)长连接协议,先主要介绍通讯地址,通讯数据格式和命令列表。
通讯地址
通讯方式:TCP或websocket
地址:www.bigiot.net
TCP端口:8181,还有其他的8282,8585
Websocket端口:8383,8484
若选用8181端口则,服务器不主动发送心跳包,靠客户端主动发送心跳包保持在线,心跳间隔以40~50s为佳;
说人话,就是设备需要间隔40~50s向服务器发过去一个指令,用于通知服务器端,自己还活着,因为时间间隔非常有规律,所以拟称为心跳包。
其他情况,自行了解;
通讯数据格式
Json
字符串 + 换行符,比如:
{"M":"beat"}\n
这种形式也叫做Json New Line
。
命令列表
常用的命令有10种,分别是:
- 设备登录(加密);
- 发送实时数据;
- 用户和设备上线通知数据;
- 用户或设备下线通知数据;
- 用户与设备、设备与设备、用户与用户间沟通指令数据;
- 查询设备或用户是否在线;
- 查询当前设备状态;
- 发送报警信息;
- 查询服务器时间;
- 强制目标设备下线;
命令,都是一句Json New Line
的数据格式(有点类似于Python的字典),以包的形式,向服务器发出。
详细介绍设备登录和发送实时数据,熟悉了这两个就可以完成基本的想服务器发送指令的操作了。
设备登录(加密)
格式:
{"M":"checkin","ID":"xx1","K":"xx2"}\n
说明:
M —— 固定(Method)
checkin —— 固定,登录指令
ID —— 固定
xx1 —— 可变,设备ID,在会员中心查看
K —— 固定(apiKey)
xx2 —— 可变,设备apikey,在会员中心查看
设备登录后,如果在1分钟内无数据传送,连接将被自动关闭。
若保持设备长期在线,可每隔50秒向服务器发送一次信息,任何信息均可。
返回结果(登录信息正确时返回,错误无任何返回,如果设备已登录,也将无任何返回信息,且不会登录成功):
{"M":"checkinok","ID":"xx1","NAME":"xx2","T":"xx3"}\n
说明:
M —— 固定(Method)
checkinok —— 固定,设备登录成功指令
ID —— 固定
xx1 —— 可变,设备登录成功后,用于通讯的唯一ID,其组成为字符“D"+设备ID,如D24
NAME —— 固定
xx2 —— 可变,该设备的名称
T —— 固定(time)
xx3 —— 可变,服务器发送信息时的时间戳,自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数。发送实时数据
发送实时数据
格式:
{"M":"update","ID":"xx1","V":{"id1":"value1",...}}\n
说明:此命令无返回信息,两次发送间隔不得小于5s,发送数据前应确保该设备已登录在线。
M —— 固定(Method)
update —— 固定,实时更新数据指令(可用 u 代替 update,减小命令长度)
ID —— 固定
xx1 —— 可变,设备ID,在会员中心查看
V —— 固定(Value)
id1 —— 可变,数据接口ID,在会员中心查看,
value1 —— 可变(数值型),本地数据(譬如:传感器测量数据)
… —— 可以更新该设备下多个数据接口的数据
示例
一次上传单个接口数据示例:
{"M":"update","ID":"2","V":{"2":"120"}}\n
同时上传多个接口数据示例:
{"M":"update","ID":"112","V":{"6":"1","36":"116"}}\n
实时上传定位接口数据示例:
{"M":"update","ID":"112","V":{"36":"116,40"}}\n
其中116为经度值,40是为维度值,详见:定位数据上传说明。
贝壳物联的官方指导手册中也提供的了PC端的模拟测试 ,可以通过软件,先对自己创建的设备进行便捷的联网访问。
PC模拟测试TCP长连接教程见:《贝壳物联通讯协议TCP连接测试教程》
Windows测试工具见:https://www.bigiot.net/talk/1140.html
设备联网
接下来可就是真操实练了,那么就从ESP8266的内部文件目录搞起。
内部文件目录
通过MicroUSB连接ESP8266模块到PC,确保COM端口已经被识别。PC端打开MicroPython File Uploader.exe
工具,再来个该工具的使用界面,唤醒一下第一回的记忆:
选择COM口
,Open
。
在命令行中键入:import os
, os.listdir()
:
>>> import os
>>> os.listdir()
['boot.py', 'main.py']
可以看到在ESP8266模块中,有两个特殊启动文件:
- boot.py
- main.py
文件操作的方式为:当设备启动,一旦文件系统被挂载上,boot.py将会首先执行,而后执行main.py。
可以在main.py中创建用户代码,也可以创建自己的用户脚本,并且在main.py中建立关联,如在main.py中写入如下code:
import my_appmy_app.main()
并创建my_app.py进行用户代码编写,其中包含main()函数,也可以创建其他用户模块。
先在PC端创建,main.py和my_app.py,并按照上述编辑main.py,并且在my_app.py中进行如下编辑:
from machine import Pin
import time# 定义引脚2为输出
ledPin = Pin(2, Pin.OUT)def main():while True:# 延时1000ms使ledPin进行数值反转ledPin.value(not ledPin.value())time.sleep_ms(1000)
通过文件传输工具,传输到ESP8266模块,在MicroPython File Uploader
工具中,选择main.py和my_app.py文件(需要逐个上传),之后点击send
,REPL提示如下:
>>> os.listdir()
['boot.py']
Sending main.py...
SUCCESS: 52 bytes written
>>>
MPY: soft reboot
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
Sending my_app.py...
SUCCESS: 223 bytes written
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
>>> import os
>>> os.listdir()
['boot.py', 'main.py', 'my_app.py']
上述操作,先查看了内部只有boot.py文件,而后送入main.py和my_app.py,再次查询文件存在,上传成功;
此时,ESP8266模块会按照my_app.py的设计,进行每隔1s闪烁一次;
这说明,模块按照预期的那样,依次执行了boot.py,main.py和my_app.py。
连接WIFI
接入贝壳物联之前,需要是的ESP8266模块通过WIFI的STA模式连接入网络,可以在my_app.py编辑(一定要修改成自己的热点账号和密码啊):
import networkSSID = "MEIZU 17" # 这里为WIFI名称
PASSWORD = "123456.789" # 这里为WIFI密码def connect_wifi():wlan = network.WLAN(network.STA_IF)wlan.active(True)if not wlan.isconnected():print('Connecting to network...')wlan.connect(SSID, PASSWORD)while not wlan.isconnected():passprint('Network config:', wlan.ifconfig())def main():connect_wifi()
将该文件上传至ESP8266模块,RST
之后,便可以接入WIFI,这里为手机开的移动热点,REPL会通过print
打印出wifi的接口配置信息:
>>>
MPY: soft reboot
network config: ('192.168.43.70', '255.255.255.0', '192.168.43.127', '192.168.43.127')
手机端热点列表里,也可以看到有名称为ESP_XXXX
的设备已经连接。
连接至贝壳物联
在贝壳物联个人中心
,添加智能设备,输入设备名称为LED灯(还有一些详细介绍可以根据需求添加),如果不公开设备可以设定为加密等。
返回到智能设备列表,可以获得此设备重要信息,如ID,APIKEY,(这俩非常重要,一定要记住自己的设备ID和APIKEY,也支持重置APIKEY)在线状态以及控制模式等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2oFc1sIt-1608449167465)(https://i.loli.net/2020/12/20/oJ2R9HsEgiOm1Kc.png)]
比较重要的信息为ID
和APIKEY
(再次强调,要用自己的哈),在my_app.py脚本中,将会被定义为常量。
DEVICEID = "10471"
APIKEY = "2530067a3"
host = "www.bigiot.net"
port = 8181
而后,使用socket连接:
import socketdef connect_bigiot():s = socket.socket()# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)addr = socket.getaddrinfo(host, port)[0][-1]try:s.connect(addr)except:print('Waiting for connect bigiot.net')print('Connect bigiot success!')# 获取会话返回信息ans = s.recv(50)print(ans)# 连接至贝壳物联后,需要通过发送命令,使得设备上线checkinBytes=bytes('{\"M\":\"checkin\",\"ID\":\"'+DEVICEID+'\",\"K\":\"'+APIKEY+'\"}\n', 'utf8')s.sendall(checkinBytes)print('Check in OK!')ans = s.recv(50)print(ans)def main():# 先连接WIFIconnect_wifi()# 再连接贝壳物联connect_bigiot()
将my_app.py上传至ESP8266模块后,对应REPL显示为:
>>>
MPY: soft reboot
Network config: ('192.168.43.70', '255.255.255.0', '192.168.43.127', '192.168.43.127')
Connect bigiot success!
b'{"M":"WELCOME TO BIGIOT"}\n'
Check in OK!
b'{"M":"checkinok","ID":"D10471","NAME":"LED\\u706f",'
通过上一节的内容可以了解到,返回的Json New Line
信息为服务端返回的数据,通过上述ID
和NAME
,可以看到ESP8266设备已经登录成功,再贝壳物联智能设备列表中也能够观察到设备在线:
一张设备在线的图片.jpg
这样,就完成了这个名称为LED灯的ESP8266模块,通过
- 先连接网络;
- 再连接贝壳物联,进行设备登陆
两步骤,完成了设备联网,接入服务器。
通过Web/手机控制设备
根据设备入网需求,再8181端口需要设备每隔40~50s向服务器发送依次心跳包,这里先设定每隔40秒(也可以用中断的方式),发送一次check status
:
def keepOnline(s, t):if utime.time()-t > 40:sayBytes = bytes('{\"M\":\"status\"}\n', 'utf8')s.sendall(sayBytes)ans = s.recv(100)print('Check status : {}\n'.format(json.loads(str(ans, 'utf-8'))["M"]))return utime.time()else:return t
LED的状态有两种,设定最简单的开关方式:
def toggle(pin):pin.value(not pin.value())
接下来的交给main()
函数,使用轮询的方式,判断是否收到web端/或手机端的消息,来判断是否需要对本地的LED灯状态进行改变:
def main():# 定义引脚2为输出ledPin = Pin(2, Pin.OUT)# 定义引脚的初始状态为关闭, 此ESP8266模块中on()为LED熄灭;ledPin.off()# 先连接WIFIconnect_wifi()# 再连接贝壳物联s = socket.socket()# 设置超时s.settimeout(10)connect_bigiot(s)recvData = b''t = utime.time()print("The start time is :{}\n".format(t))while True:try: # 在超时时间内是否接收到数据recvData = s.recv(100)except: # 如果接收不到,维持上线状态t = keepOnline(s, t)print("Keep online operate, The time now is {}\n".format(t))if recvData : # 接收到数据msg = json.loads(str(recvData, 'utf-8'))print("Received Data is : {}\n".format(msg))if "C" in msg.keys(): # 接收到offOn的命令,执行操作if msg["C"] == "offOn":toggle(ledPin)else:print("The other C in msg : {}\n".format(msg["C"]))else:print("NO keys C in the msg!\n")recvData = b''
主函数中,先定义LED引脚为输出,再连接WIFI,后连接贝壳物联;通过接受贝壳物联返回的信息, 根据信息offOn
,控制LED反转;
通过贝壳物联Web端,或者是微信小程序,就可以控制这个名称为LED灯的设备开关了。演示效果如下:
仔细观察开关按钮和ESP8266模块上蓝色的LED灯,向模块发送offOn
指令,对LED的亮灭进行了控制。
登录贝壳物联微信小程序 ,也可以看到名称为LED灯的设备在线,也同样支持相同的方式进行控制,界面效果与上述Web端一致,下图为小程序操作界面:
想必,细心的你已经发现控制面板上还有很多控制按钮(其实也可以自定义控件),那么就可以根据控件进行其他的控制了,emm后面的内容就更加丰富了。
至此,使用Micropython,配合ESP8266模块,接入贝壳物联这一路也就畅通了。
结束语
表面上看,是结束了可实际上后面需要做的事情还有很多,比如:
- 使用中断进行间隔状态查询;
- 通过AP对wifi的SSID和PASSWORD进行设置;
- 丰富接收信息处理内容;
- 丰富ESP8266模块连接硬件的功能;
- OTA远程软件升级?
- 模块系统化,精致化等等;
捣鼓了两个星期的周末,四篇博文也算是有点像模像样了。打算此系列后面的内容就是根据功能需求,根据小制作的功能来将此系列继续下去。
道阻且长,其修远兮。
2020-12-20;
这篇关于MicroPython_ESP8266_IoT——第四回 初入联网(接入了贝壳物联)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!