EC800M作为从机接收数据,并解析到结构体中,最终调用socket库发送至Web端。
硬件准备:
EC800M固件烧录
本文主要写IOT板如何在串口中接收数据并发送至Web端,解析部分不是本文讲述内容;
EC800M:USB供电;
如果是第一次给IOT板烧录脚本,则需要参考官网中的教程烧录固件:
教程:固件烧录 - QuecPython (quectel.com)
固件下载地址:固件下载
软件流程:
初始化UART引脚、回调
配置串口初始化。定义UART2_RX/TX收发RF报文,波特率115200,数据位数8,无奇偶校验,停止位数1,无硬件控制流。
EC800M-UART2:(这里用的uart2)
TX:引脚号18
RX:引脚号17
(注意:EC800MCNGA 、CNGD/ EG810MCNGA 模块的 uart1 不可用)
设置串口数据回调,回调返回一个list:
huart2 = UART(UART.UART2, 115200, 8, 0, 1, 0)
uart2_data=[]
#list[0]:是否接收数据成功(成功返回0)
#list[1]:接收端口
#list[2]:返回多少数据(返回字节数)
def UART2_Read_Callback(para):
global RF_Read_Flag
global uart2_data
if para[0] == 0:
if para[1]==2:
uart2_data=huart2.read(para[2])
RF_Read_Flag=1
# 串口初始化,调用串口回调接收数据
def UART2_Init():
huart2.set_callback(UART2_Read_Callback)
本工程的发送命令:
(这里写你自己要发送的信息)
检测网络连接(检测电话卡状态)
stage, state = checkNet.wait_network_connected(30)
这里是最长等待30s检测是否有网络连接,如果stage和state分别返回的是3和1就是连接成功了,如果返回的是别的数字就说明没有连上网
这个时候要么检查是不是卡不支持(比如物联卡,物联卡需开启特定的IP),亦或者是电话卡没有流量了。
创建socket对象,发送TCP_Client请求
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM, usocket.IPPROTO_TCP) # usocket.socket(IPv6 地址,socket流,TCP协议类型)
Tcp_Client(address, port)#请求相应的IP以及端口
向RF发送指令
huart2.write(指令)# byte类型
RF数据上报
uart2_data=huart2.read(para[2])
利用回调读取RF传回来的数据,然后丢到解析函数中进行解析。
IOT板接收数据并解析
定义结构体变量并读取串口数据放进变量中,data_buf的长度根据读取到的self.data_buf定义,先转成int类型再调用len函数并%4。
定时给他发数据;如果不主动发数据,就没有回复;建立一个字典,把数据解析好了塞到字典里面。
返回的数据中——èż™äş›ĉ˜Żĉ•°ĉ�ä½ïĵ›42ĉ˜ŻfuncodeïĵŒċˆ¤ĉ–一下ċ°ħèĦŒäş†ïĵŒĉˆ–è€
ä¸ç�Ħäğ–
ĉ˜Ż41ïĵŒċŽğĉŽ‰funcodeäıŸċ°ħĉ˜Ż40
MAX_OBJ ĉ˜Ż8ïĵŒĉœ€ċ¤§ç›�ĉ ‡ĉ•°
ĉœ€ċŽĉ•°ĉ�ĉ€ğé•żċşĤ为ïĵš4+4*8+4 = 40ċ—节
转为字典类型后,转回str类型,方便调用send函数传到web
以上划线句子不重要,我相信读者有自己的串口命令收发数据格式。
解析后数据发送至Web
sock.send(Tx2tcp.encode()) #不断在while中发送数据,类型为byte,最大1024字节
发送完成后自动断开tcp连接(可以不断,但是容易引发错误(但这个错误可以忽略,因为为了省事,我已经把初始化tcp连接这块直接放到while循环里面了,还没试过没断开tcp又重新连接tcp而出现代码跑死的情况))。
然后就是tcp的初始化函数和tcp作为客户端通信的这部分函数代码了,这里的代码片在官网上都有详细解释。
address = '36.152.44.95'
port = 80
def Tcp_Client(address, port):
global TCP_Handle
global Tx2tcp
global uart2_data
# Create a socket object
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM, usocket.IPPROTO_TCP) # usocket.socket(IPv6 地址,socket流,TCP协议类型)
print('socket object created.')
# Connect to the TCP server
sock.connect((address, port))
print('tcp link established: %s, %s' % (address, port))
TCP_Handle = 1
while True:
try:
# Send the data
sock.send(Tx2tcp.encode())
print('<-- send data:')
print(Tx2tcp.encode())
Tx2tcp=None
# time.sleep(0.5)
# print('--> recv data:')
# data = sock.recv(1024)
# print(data.encode())
break
except:
# Connection ends until the data is fully received
print('tcp disconnected.')
sock.close()
break
def Tcp_Init():
global address
global port
stage, state = checkNet.wait_network_connected(30)
if stage == 3 and state == 1: # Network connection is normal
print('[Network connection successful.]')
Tcp_Client(address, port) # Start the client
else:
print('Network connection failed, stage={}, state={}'.format(stage, state))
串口初始化好了,tcp初始化也好了,然后就是读数据了
def RF_Read():
global TCP_Handle
global uart2_data
global Flag
global Tx2tcp
global sock
if Flag:
Tx2tcp = uart2_data #串口读到的数据放到缓存
uart2_data = None
Flag = 0
RX_GUI_Stu.Bytes_Buf=Tx2tcp #解析部分
if(RX_GUI_Stu.Trans_to_Struct()):
if RX_GUI_Stu.ADDR==GUI.GUI_ADDR:
print("Data True")
RF_Stu.data_buf=RX_GUI_Stu.DATA
if RF_Stu.Trans_to_Struct():
print("Trans True")
try:
msg_dir = {"obj1":obj,
"obj2":obj2
}
print('msg_dir:',msg_dir)
Tx2tcp = str(msg_dir)
except:
pass
return 0
uart2_data=0
Flag=0
return 0
这里测试用的地址和端口是百度和80,也用过必应和b站的,都可以成功发送我乱七八糟的东西上去,就是会返回错误,告诉你发的这些东西不合规矩什么的… …
给必应发我的自定义数据:
会返回http error 400,说明数据能够通过tcp发送至web。
然后需要注意的一个点是这里只支持公网数据传输,局域网传输是不支持的,这部分内容官网也是有提及的。
完