1引言
1.1編寫目的
采用圖表等形式簡要介紹軟硬件設(shè)計基本結(jié)構(gòu),作為后續(xù)二次開發(fā)的基礎(chǔ)材料。
1.2背景
本項目為了解決STM機(jī)上禁止代客操作而客戶又因UI界面元素復(fù)雜對按鈕查找不方便之間的矛盾。項目硬件上主要由離線語音識別模塊和WIFI模塊組成,使用UART,SOCKET等通信方式傳遞控制信息,采用C/S架構(gòu),通過將語音信息轉(zhuǎn)至視覺信心,輔助客戶辦理業(yè)務(wù)。
1.3定義
離線語音識別:采用不聯(lián)網(wǎng)的本地語音模型對語音進(jìn)行模式匹配,輸入匹配結(jié)果。
輔助指示:通過對語音識別的內(nèi)容進(jìn)行封裝傳輸于STM機(jī)上顯式的標(biāo)識按鈕位置。
STM機(jī):自主柜員機(jī)。
2總體設(shè)計
2.1需求規(guī)定
語音識別模塊:
輸入:語音條目
輸出:UART 串口信息
處理功能: 對語音信息進(jìn)行匹配得到待UART發(fā)送的數(shù)據(jù)
功能性能需求:高識別率,識別迅速
輸入:UART 串口信息
輸出:SOCKET 通信 SOCK_STREAM
處理功能:
a. 接受串口信息,對串口信讀取后經(jīng)處理后通過SOCKET發(fā)送至WIFI模塊2
b. 根據(jù)按鈕選擇要鏈接的WIFI模塊2
功能性能需求:兩塊WIFI模塊鏈接速度迅速,SCOKCT鏈接穩(wěn)定傳輸無誤
輸入:SOCKET 通信 SOCK_STREAM
輸出:GPIO控制信息或UART 串口信息
處理功能:
a. 接受SOCKET信息,讀取后使STM機(jī)對應(yīng)UI界面元素高亮
b. 可以穿行的接受多個WIFI模塊1的控制信息
功能性能需求:兩塊WIFI模塊鏈接速度迅速,SCOKCT鏈接穩(wěn)定傳輸無誤,產(chǎn)生對STM機(jī)UI元素的控制信息
2.2運(yùn)行環(huán)境

軟件環(huán)境:
開發(fā)語言:C++,MicroPython
使用服務(wù):SOCKET UART
2.3基本設(shè)計概念和處理流程
基本設(shè)計概念:
使用兩塊WIFI模塊間的SOCKET通信傳遞控制信息,服務(wù)端通過按鈕選擇要鏈接的客戶端,服務(wù)端檢測鏈接成功后即可開始客戶端的信心傳輸工作。離線語音芯片將語音指令轉(zhuǎn)換為二進(jìn)制信息通過WIFI從客戶端傳遞至服務(wù)端,客戶端響應(yīng)產(chǎn)生對STM機(jī)UI元素的控制信息
流程圖:
使用按鈕選擇鏈接對應(yīng)的服務(wù)端
等待WIFI鏈接成功
說出語音指令
語音指令經(jīng)芯片處理后由客戶端發(fā)送至服務(wù)端
服務(wù)端接受信息UI界面相應(yīng)
如改比業(yè)務(wù)完成選擇結(jié)束
斷開兩塊WIFI芯片(服務(wù)端,客戶端)的鏈
2.4結(jié)構(gòu)
硬件結(jié)構(gòu)分為服務(wù)端和客戶端兩個部分:
客戶端為服務(wù)人員攜帶的便攜設(shè)設(shè)備,應(yīng)使用電池供電。主要組成部分為語音識別芯片VB-01以及ESP-32WIFI模塊(拾音器以及喇叭未畫出)。負(fù)責(zé)語音信息的接受產(chǎn)生控制信息以及對控制信息的傳輸,在客戶端設(shè)備上可由按鈕選擇需要鏈接的STM機(jī)客戶端對其進(jìn)行控制。
服務(wù)端由一塊ESP-8266芯片和UART轉(zhuǎn)USB器組成,負(fù)責(zé)將從客戶端接受到的控制信息轉(zhuǎn)換成控制UI界面的控制信息。

關(guān)系結(jié)構(gòu):
一對一通信:一個客戶端于一個服務(wù)端鏈接,產(chǎn)生控制信息,點(diǎn)對點(diǎn)通信。

多對一通信:多個客戶端于一個服務(wù)端鏈接,并行的傳遞控制信息。

2.5尚未問決的問題
說明在概要設(shè)計過程中尚未解決而設(shè)計者認(rèn)為在系統(tǒng)完成之前必須解決的各個問題。
未考慮到傳輸過程中的安全性以及與STM機(jī)連接的到形式和在該機(jī)上運(yùn)行的服務(wù)程序的傳輸協(xié)議和接入方式。
未設(shè)計詳細(xì)的PCB走線,原型模型使用開發(fā)板以杜邦線形式鏈接。按鍵較少,對應(yīng)方式為一對一對于多機(jī)的鏈接有一定問題。
離線語音識別芯片的語音條目目前支持只有50條可以考慮使用存儲空間更大的芯片。
3軟件設(shè)計
客戶端源碼:
#通過按鈕鏈接網(wǎng)絡(luò)測試
import time
import network
import utime
from machine import Pin
def uartGet():
from machine import UART
# 初始化一個UART對象
uart = UART(2, baudrate=115200, rx=16, tx=17, timeout=10)
#初始化socket 對象
import socket
client = socket.socket()
client.connect(('192.168.4.1', 10000))
while True:
if uart.any():
bin_data = uart.readline()
print(bin_data)
client.send(bin_data)
def connectnetWifi(essid,password):
sta_if = network.WLAN(network.STA_IF) # 配置wifi模式為station
if not sta_if.isconnected(): # 判斷有無連接
print('connecting to network...')
sta_if.active(True) # 激活wifi接口
sta_if.connect(essid, password) # 連接現(xiàn)有wifi網(wǎng)絡(luò),需要替換為已知的熱點(diǎn)名稱和密碼
while not sta_if.isconnected():
utime.sleep(1) # 未連接上就等待一下,直到連接成功
print("essid: {},password: {}".format(essid,password))
print(sta_if.config("essid"))
print('network config:', sta_if.ifconfig()) # 輸出當(dāng)前wifi網(wǎng)絡(luò)給自己分配的網(wǎng)絡(luò)參數(shù)
print('------------------------------------')
def disconnectWifi():
'''
斷開網(wǎng)絡(luò)連接
'''
sta_if = network.WLAN(network.STA_IF)
if sta_if.isconnected():
sta_if.disconnect()
print('the network had been disconnect')
#初始化 按鈕對應(yīng)的針腳
pressKey1 = Pin(32)
pressKey2 = Pin(33)
pressKey3 = Pin(14)
pressKey4 = Pin(12)
flag = True
while True:
if flag == True:
if pressKey1.value()==1:
print("1")
flag = False
if pressKey1.value()==1:
print("2")
flag = False
if pressKey3.value()==1:
disconnectWifi()
print('3')
flag = False
connectnetWifi('ESP-32','1234567890')
uartGet()
if pressKey4.value()==1:
disconnectWifi()
print("4")
flag = False
connectnetWifi('ESP-8266', '1234567890')
# socketClinet()
#每次接受的數(shù)據(jù)為持續(xù)的000 或111 通過判斷只輸出單次的結(jié)果
if pressKey1.value()==0 and pressKey2.value() == 0 and pressKey3.value()==0 and pressKey4.value()==0:
flag = True
服務(wù)端源碼:
import network
import socket
import time
# SSID = "7-704" # 修改為你的WiFi名稱
# PASSWORD = "qmy980902" # 修改為你WiFi密碼
port = 10000 # 端口號
wlan = None # wlan
listenSocket = None # 套接字
from machine import UART
import time
uart = UART(1,baudrate=9600)
import network
ap = network.WLAN(network.AP_IF) # 指定用ap模式
ap.active(True) # 啟用wifi前需要先激活接口
ap.config(essid="ESP-32") # 設(shè)置熱點(diǎn)名稱
ap.config(authmode=3, password='1234567890') # 設(shè)置認(rèn)證模式與密碼
print(ap.ifconfig())
# Catch exceptions,stop program if interrupted accidentally in the 'try'
try:
# connectWifi(SSID, PASSWORD)
ip = ap.ifconfig()[0] # 獲取IP地址
listenSocket = socket.socket() # 創(chuàng)建套接字
print("bind ip:{} port:{}".format(ip,port))
listenSocket.bind((ip, port)) # 綁定地址和端口號
listenSocket.listen(2) # 監(jiān)聽套接字
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 設(shè)置套接字
print('tcp waiting...')
while True:
print("accepting.....")
conn, addr = listenSocket.accept() # 接收連接請求,返回收發(fā)數(shù)據(jù)的套接字對象和客戶端地址
print(addr, "connected")
while True:
data = conn.recv(1024) # 接收數(shù)據(jù)(1024字節(jié)大?。? if (len(data) == 0): # 判斷客戶端是否斷開連接
print("closesocket")
conn.close() # 關(guān)閉套接字
break
print(data)
print(type(data))
print("send uart data")
uart.write(data)
# ret = conn.send(data) # 發(fā)送數(shù)據(jù)
except:
if (listenSocket): # 判斷套接字是否為空
listenSocket.close() # 關(guān)閉套接字
演示視頻:
https://www.bilibili.com/video/BV1tf4y1M7Ae?spm_id_from=333.999.0.0