1引言
1.1編寫(xiě)目的
采用圖表等形式簡(jiǎn)要介紹軟硬件設(shè)計(jì)基本結(jié)構(gòu)憾儒,作為后續(xù)二次開(kāi)發(fā)的基礎(chǔ)材料。
1.2背景
本項(xiàng)目為了解決STM機(jī)上禁止代客操作而客戶又因UI界面元素復(fù)雜對(duì)按鈕查找不方便之間的矛盾役电。項(xiàng)目硬件上主要由離線語(yǔ)音識(shí)別模塊和WIFI模塊組成,使用UART,SOCKET等通信方式傳遞控制信息售淡,采用C/S架構(gòu),通過(guò)將語(yǔ)音信息轉(zhuǎn)至視覺(jué)信心瞄摊,輔助客戶辦理業(yè)務(wù)勋又。
1.3定義
離線語(yǔ)音識(shí)別:采用不聯(lián)網(wǎng)的本地語(yǔ)音模型對(duì)語(yǔ)音進(jìn)行模式匹配,輸入匹配結(jié)果换帜。
輔助指示:通過(guò)對(duì)語(yǔ)音識(shí)別的內(nèi)容進(jìn)行封裝傳輸于STM機(jī)上顯式的標(biāo)識(shí)按鈕位置楔壤。
STM機(jī):自主柜員機(jī)。
2總體設(shè)計(jì)
2.1需求規(guī)定
語(yǔ)音識(shí)別模塊:
輸入:語(yǔ)音條目
輸出:UART 串口信息
處理功能: 對(duì)語(yǔ)音信息進(jìn)行匹配得到待UART發(fā)送的數(shù)據(jù)
功能性能需求:高識(shí)別率惯驼,識(shí)別迅速
輸入:UART 串口信息
輸出:SOCKET 通信 SOCK_STREAM
處理功能:
a. 接受串口信息蹲嚣,對(duì)串口信讀取后經(jīng)處理后通過(guò)SOCKET發(fā)送至WIFI模塊2
b. 根據(jù)按鈕選擇要鏈接的WIFI模塊2
功能性能需求:兩塊WIFI模塊鏈接速度迅速,SCOKCT鏈接穩(wěn)定傳輸無(wú)誤
輸入:SOCKET 通信 SOCK_STREAM
輸出:GPIO控制信息或UART 串口信息
處理功能:
a. 接受SOCKET信息,讀取后使STM機(jī)對(duì)應(yīng)UI界面元素高亮
b. 可以穿行的接受多個(gè)WIFI模塊1的控制信息
功能性能需求:兩塊WIFI模塊鏈接速度迅速祟牲,SCOKCT鏈接穩(wěn)定傳輸無(wú)誤隙畜,產(chǎn)生對(duì)STM機(jī)UI元素的控制信息
2.2運(yùn)行環(huán)境
軟件環(huán)境:
開(kāi)發(fā)語(yǔ)言:C++,MicroPython
使用服務(wù):SOCKET UART
2.3基本設(shè)計(jì)概念和處理流程
基本設(shè)計(jì)概念:
使用兩塊WIFI模塊間的SOCKET通信傳遞控制信息说贝,服務(wù)端通過(guò)按鈕選擇要鏈接的客戶端议惰,服務(wù)端檢測(cè)鏈接成功后即可開(kāi)始客戶端的信心傳輸工作。離線語(yǔ)音芯片將語(yǔ)音指令轉(zhuǎn)換為二進(jìn)制信息通過(guò)WIFI從客戶端傳遞至服務(wù)端乡恕,客戶端響應(yīng)產(chǎn)生對(duì)STM機(jī)UI元素的控制信息
流程圖:
使用按鈕選擇鏈接對(duì)應(yīng)的服務(wù)端
等待WIFI鏈接成功
說(shuō)出語(yǔ)音指令
語(yǔ)音指令經(jīng)芯片處理后由客戶端發(fā)送至服務(wù)端
服務(wù)端接受信息UI界面相應(yīng)
如改比業(yè)務(wù)完成選擇結(jié)束
斷開(kāi)兩塊WIFI芯片(服務(wù)端言询,客戶端)的鏈
2.4結(jié)構(gòu)
硬件結(jié)構(gòu)分為服務(wù)端和客戶端兩個(gè)部分:
客戶端為服務(wù)人員攜帶的便攜設(shè)設(shè)備,應(yīng)使用電池供電傲宜。主要組成部分為語(yǔ)音識(shí)別芯片VB-01以及ESP-32WIFI模塊(拾音器以及喇叭未畫(huà)出)运杭。負(fù)責(zé)語(yǔ)音信息的接受產(chǎn)生控制信息以及對(duì)控制信息的傳輸,在客戶端設(shè)備上可由按鈕選擇需要鏈接的STM機(jī)客戶端對(duì)其進(jìn)行控制函卒。
服務(wù)端由一塊ESP-8266芯片和UART轉(zhuǎn)USB器組成辆憔,負(fù)責(zé)將從客戶端接受到的控制信息轉(zhuǎn)換成控制UI界面的控制信息。
關(guān)系結(jié)構(gòu):
一對(duì)一通信:一個(gè)客戶端于一個(gè)服務(wù)端鏈接,產(chǎn)生控制信息虱咧,點(diǎn)對(duì)點(diǎn)通信熊榛。
多對(duì)一通信:多個(gè)客戶端于一個(gè)服務(wù)端鏈接,并行的傳遞控制信息彤钟。
2.5尚未問(wèn)決的問(wèn)題
說(shuō)明在概要設(shè)計(jì)過(guò)程中尚未解決而設(shè)計(jì)者認(rèn)為在系統(tǒng)完成之前必須解決的各個(gè)問(wèn)題来候。
未考慮到傳輸過(guò)程中的安全性以及與STM機(jī)連接的到形式和在該機(jī)上運(yùn)行的服務(wù)程序的傳輸協(xié)議和接入方式。
未設(shè)計(jì)詳細(xì)的PCB走線逸雹,原型模型使用開(kāi)發(fā)板以杜邦線形式鏈接营搅。按鍵較少,對(duì)應(yīng)方式為一對(duì)一對(duì)于多機(jī)的鏈接有一定問(wèn)題梆砸。
離線語(yǔ)音識(shí)別芯片的語(yǔ)音條目目前支持只有50條可以考慮使用存儲(chǔ)空間更大的芯片转质。
3軟件設(shè)計(jì)
客戶端源碼:
#通過(guò)按鈕鏈接網(wǎng)絡(luò)測(cè)試
import time
import network
import utime
from machine import Pin
def uartGet():
from machine import UART
# 初始化一個(gè)UART對(duì)象
uart = UART(2, baudrate=115200, rx=16, tx=17, timeout=10)
#初始化socket 對(duì)象
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(): # 判斷有無(wú)連接
print('connecting to network...')
sta_if.active(True) # 激活wifi接口
sta_if.connect(essid, password) # 連接現(xiàn)有wifi網(wǎng)絡(luò),需要替換為已知的熱點(diǎn)名稱(chēng)和密碼
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():
'''
斷開(kāi)網(wǎng)絡(luò)連接
'''
sta_if = network.WLAN(network.STA_IF)
if sta_if.isconnected():
sta_if.disconnect()
print('the network had been disconnect')
#初始化 按鈕對(duì)應(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 通過(guò)判斷只輸出單次的結(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名稱(chēng)
# PASSWORD = "qmy980902" # 修改為你WiFi密碼
port = 10000 # 端口號(hào)
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)名稱(chēng)
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)) # 綁定地址和端口號(hào)
listenSocket.listen(2) # 監(jiān)聽(tīng)套接字
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 設(shè)置套接字
print('tcp waiting...')
while True:
print("accepting.....")
conn, addr = listenSocket.accept() # 接收連接請(qǐng)求休蟹,返回收發(fā)數(shù)據(jù)的套接字對(duì)象和客戶端地址
print(addr, "connected")
while True:
data = conn.recv(1024) # 接收數(shù)據(jù)(1024字節(jié)大小)
if (len(data) == 0): # 判斷客戶端是否斷開(kāi)連接
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