【MaixPY 教程】用mixly玩轉k210——MixNo通過TCP/IP與掌控板進行通訊
前言
【MaixPy系列教程:】
- 【MaixPy教程】用maixHub訓練模型進行開源硬件識別
- 【MaixPy 教程】用mixly玩轉K210——口罩識別
- 【MaixPy教程】用mixly玩轉K210——調用AI_OneNET API實現車牌識別
- 【MaixPy 教程】用mixly玩轉K210——人臉追蹤
- 【MaixPy 教程】用mixly玩轉K210——20類對象檢測
- 【MaixPy 教程】用mixly玩轉K210——一鍵本地模型訓練
在教程開始之前你需要了解套接字、和tcp協議及編程的原理:
什麼是套接字?
Socket
是網絡編程的一個抽象概念。通常我們用一個Socket表示“打開了一個網絡鏈接”,而打開一個Socket需要知道目標計算機的IP地址和端口號,再指定協議類型即可。
TCP協議簡介
TCP協議,傳輸控制協議(Transmission Control Protocol,縮寫爲 TCP)是一種面向連接的、可靠的、基於字節流的傳輸層通訊協議,由IETF的RFC 793定義。
TCP通信需要經過創建連接、數據傳送、終止連接三個步驟。TCP通信模型中,在通信開始之前,一定要先創建相關連接,才能發送數據,類似於生活中,“打電話”"。
套接字在工作時將連接的雙方分爲服務器端和客戶端,即C/S模式,TCP通訊原理如下圖:
準備階段
- MixNo主控板
- 掌控板
程序編寫
整體思路:
用掌控板來做TCP服務器,MixNo 來做TCP客戶端。(創建TCP連接時,主動發起連接的叫客戶端,被動響應連接的叫服務器)首先我們先用mpython編寫程序爲掌控板寫TCP客戶端來顯示客戶端的請求,用mixly【軟件關注童芯創悟進行獲取】編寫MixNo的TCP客戶端,向服務端發送消息
TCP服務器的編寫
TCP編程的服務端一般步驟是:
創建一個socket,用函數socket()
設置socket屬性,用函數setsockopt() , 可選
綁定IP地址、端口等信息到socket上,用函數bind()
開啓監聽和設置最大監聽數,用函數listen()
等待客戶端請求一個連接,用函數accept()
收發數據,用函數send()和recv(),或者read()和write()
關閉網絡連接
首先打開mpython,先讓配置掌控板的網絡(可以是sta模式,或者AP模式),然後套接字初始化。:
# 套接字初始化
socket(socket_family, socket_type, protocol)
# socket_family 就是指套接字家族可以是AF_UNIX(基於文件的)或AF_INET(基於網絡的)(IPV4)AF_INET6(IPV6)
#socket_type 就是指套接字類型,即SOCK_STREAM(TCP協議)或SOCK_DGRAM(UDP協議)
#protocol 是協議,默認爲0,一般不填
mywifi.sta.ifconfig() 用於獲得當前鏈接網絡的靜態IP地址信息,返回類型爲4元素元組,我們用元組中的第一項來做服務器的IP地址。
IP地址:192.168.0.4
NETMASK(子網掩碼): 255.255.255.0
GATEWAY(網關):192.168.0.1
DNS:類似本地的host文件。公網DNS註冊域名。
注意:返回的數據是一個4元組,元組中的每一項都是字符串格式。
conn,addr = listenSocket.accept()
# 阻塞,等待客戶端的請求連接,如果有新的客戶端來連接服務器,那麼會返回一個新的套接字專門爲這個客戶端服務
需要注意的是:在服務器未接收到任何客戶端的訪問請求時,程序將停留在該位置,只有有新的請求產生時,程序才能向下進行。所以,如果掌控板在這種情況下,需要處理一些實時程序的話,需要建立定時器中斷和外部中斷,否則無法對自定義程序進行有效處理。
ocket.recv()接收客戶端發來的數據。最大數據量是1024
注意:socket.recv()接收到的數據是二進制字符串格式(與正常的字符串有些差別,需要使用decode()函數來將其解碼轉化爲正常的字符串)
TCP客戶端的編寫
TCP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket()
2、設置socket屬性,用函數setsockopt() , 可選
3、綁定IP地址、端口等信息到socket上,用函數bind() , 可選
4、設置要連接的對方的IP地址和端口等屬性
5、連接服務器,用函數connect()
6、收發數據,用函數send()和recv(),或者read()和write()
7、關閉網絡連接
首先打開mixly,設置MixNo需要連接的wifi網絡(和服務器同一網絡),初始化套接字:
客戶端有了套接字後,馬上就可以調用connect()函數去連接服務器(ps:以元組或者列表的方式綁定服務器地址,和端口)。
建立連接後,就可以與服務器開始對話。在對話結束後,客戶端就可以關閉套接字,結束連接。
# tcp服務器代碼
import socket
from mpython import *
port=5001 # TCP服務端的端口,range0~65535
listenSocket=None
mywifi=wifi() # 創建wifi類
# 捕獲異常,如果在"try" 代碼塊中意外中斷,則停止關閉套接字
try:
mywifi.connectWiFi("ssid","password") # WiFi連接,設置ssid 和password
# mywifi.enable_APWiFi("wifi_name",13) # 還可以開啓AP模式,自建wifi網絡
ip= mywifi.sta.ifconfig()[0] # 獲取本機IP地址
listenSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創建socket,不給定參數默認爲TCP通訊方式
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 設置套接字屬性參數
listenSocket.bind((ip,port)) # 綁定ip和端口
listenSocket.listen(3) # 開始監聽並設置最大連接數
print ('tcp waiting...')
oled.DispChar("%s:%s" %(ip,port),0,0) # oled屏顯示本機服務端ip和端口
oled.DispChar('accepting.....',0,16)
oled.show()
while True:
print("accepting.....")
conn,addr = listenSocket.accept() # 阻塞,等待客戶端的請求連接,如果有新的客戶端來連接服務器,那麼會返回一個新的套接字專門爲這個客戶端服務
print(addr,"connected")
while True:
data = conn.recv(1024) # 接收對方發送過來的數據,讀取字節設爲1024字節
if(len(data) == 0):
print("close socket")
conn.close() # 如果接收數據爲0字節時,關閉套接字
break
data_utf=data.decode() # 接收到的字節流以utf8編碼解碼字符串
print(data_utf)
oled.DispChar(data_utf,0,48) # 將接收到文本oled顯示出來
oled.show()
oled.fill_rect(0,48,128,16,0) # 局部清屏
conn.send(data) # 返回數據給客戶端
# 當捕獲異常,關閉套接字、網絡
except:
if(listenSocket):
listenSocket.close()
mywifi.disconnectWiFi()
# tcp客戶端代碼程序
import time
import socket
import network_no
import machine
try:
nic = network_no.wifi_init1()
nic.connect("hockel","erised88")
print(nic.ifconfig())
sock = socket.socket()
sock.settimeout(5)
sock.connect(("192.168.43.246", 5001))
while True:
sock.send("Hello Handbit")
time.sleep_ms(1000)
sock.send("I'am MixNo")
time.sleep_ms(1000)
except:
sock.close()
程序演示
小結:
有了TCP通訊後,就可以把MixNo識別到的物體發送到掌控板上了,掌控板可以對發來的消息進行處理做出相應的動作(比如:口罩識別門禁,人體追蹤、顏色識別等等,當然這些在MixNo中也可以獨自完成)。
首發個人博客:www.hockel.club,歡迎關注哈。有問題的可以加入【MixNo QQ羣:1056344043】