项目概述
这是一个集成了语音识别和串口通信功能的智能控制工具,旨在通过自然语言语音指令实现对硬件设备的远程控制。该工具采用pyqt5 GUI 界面设计,支持多种串口参数配置,能够实时识别语音指令并通过串口发送控制设备的指令集命令。
核心功能
1、智能语音识别:集成 Vosk 本地语音识别引擎,支持离线使用
2、灵活的串口配置:支持波特率、校验位、停止位、流控制等完整参数设置
3、实时状态显示:动态显示识别过程和系统状态
4、历史记录查看:完整记录所有识别结果和操作日志
5、用户友好界面:采用 PyQt5 构建的图形界面
代码如下:
主程序入口
import sys
from PyQt5.QtWidgets import QApplication
from ui import MainWindow#主程序入口if __name__ == "__main__":app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec_())
语音识别具体实现
import vosk
import pyaudio
from PyQt5.QtCore import pyqtSignal, QThread#VOSK语音识别模块class SpeechRecognitionThread(QThread):recognized_signal = pyqtSignal(str)current_text_signal = pyqtSignal(str)def __init__(self, serial_connection, model_path):super().__init__()self.serial_connection = serial_connectionself.model_path = 'model/voskmodelsmallcn'self.stop_flag = Falsedef run(self):try:model = vosk.Model(self.model_path)recognizer = vosk.KaldiRecognizer(model, 16000)recognizer.SetWords(True)p = pyaudio.PyAudio()stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=4000)while not self.stop_flag:data = stream.read(4000)if recognizer.AcceptWaveform(data):result = recognizer.Result()self.recognized_signal.emit(result)self.process_command(result)else:partial_result = recognizer.PartialResult()self.current_text_signal.emit(partial_result)stream.stop_stream()stream.close()p.terminate()except Exception as e:self.recognized_signal.emit(f"语音识别错误: {str(e)}")def stop(self):self.stop_flag = Truedef process_command(self, result):command = result.lower()if "打开 冻结" in command:self.send_serial_command("\x02OFZ:1\x03")elif "关闭 冻结" in command:self.send_serial_command("\x02OFZ:0\x03")def send_serial_command(self, command):try:if self.serial_connection and self.serial_connection.is_open:self.serial_connection.write(command.encode())self.recognized_signal.emit(f"发送指令: {command}")else:self.recognized_signal.emit("串口未打开")except Exception as e:self.recognized_signal.emit(f"发送指令错误: {str(e)}")
GUI界面
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QWidget, QLabel, QPushButton, QLineEdit, QComboBox, QTextEdit
from PyQt5.QtCore import QCoreApplication
from serial_config import SerialConfig
from speech_recognition import SpeechRecognitionThread
import serial
import serial.tools.list_ports# UI模块class MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("语音控制工具")self.setGeometry(200, 200, 500, 400)self.serial_config = SerialConfig()self.serial_connection = Noneself.init_ui()def init_ui(self):self.layout = QVBoxLayout()self.port_label = QLabel("串口号:")self.layout.addWidget(self.port_label)self.port_input = QComboBox()self.layout.addWidget(self.port_input)self.populate_ports()self.baudrate_label = QLabel("波特率:")self.layout.addWidget(self.baudrate_label)self.baudrate_input = QLineEdit("19200")self.layout.addWidget(self.baudrate_input)self.parity_label = QLabel("效验位:")self.layout.addWidget(self.parity_label)self.parity_input = QComboBox()self.parity_input.addItems(["None", "Even", "Odd"])self.layout.addWidget(self.parity_input)self.stopbits_label = QLabel("停止位:")self.layout.addWidget(self.stopbits_label)self.stopbits_input = QComboBox()self.stopbits_input.addItems(["1", "1.5", "2"])self.layout.addWidget(self.stopbits_input)self.flowcontrol_label = QLabel("流控制:")self.layout.addWidget(self.flowcontrol_label)self.flowcontrol_input = QComboBox()self.flowcontrol_input.addItems(["None", "Xon/Xoff", "RTS/CTS", "DTR/DSR"])self.layout.addWidget(self.flowcontrol_input)self.start_button = QPushButton("开始语音识别")self.start_button.clicked.connect(self.start_recognition)self.layout.addWidget(self.start_button)self.stop_button = QPushButton("停止语音识别")self.stop_button.clicked.connect(self.stop_recognition)self.layout.addWidget(self.stop_button)self.status_label = QLabel("状态: 等待开始")self.layout.addWidget(self.status_label)self.output_text = QTextEdit()self.output_text.setReadOnly(True)self.layout.addWidget(self.output_text)container = QWidget()container.setLayout(self.layout)self.setCentralWidget(container)def populate_ports(self):try:ports = serial.tools.list_ports.comports()for port in ports:self.port_input.addItem(port.device)except Exception as e:self.status_label.setText(f"串口获取错误: {str(e)}")def start_recognition(self):try:self.serial_config.port = self.port_input.currentText()self.serial_config.baudrate = int(self.baudrate_input.text())self.serial_config.parity = self.get_parity(self.parity_input.currentText())self.serial_config.stopbits = self.get_stopbits(self.stopbits_input.currentText())self.serial_config.flowcontrol = self.get_flowcontrol(self.flowcontrol_input.currentText())self.serial_connection = serial.Serial(self.serial_config.port, self.serial_config.baudrate,parity=self.serial_config.parity,stopbits=self.serial_config.stopbits,bytesize=self.serial_config.bytesize, timeout=1)self.status_label.setText(f"状态: 串口 {self.serial_config.port} 已打开")model_path = "model/voskmodelsmallcn" # 本地模型路径self.recognition_thread = SpeechRecognitionThread(self.serial_connection, model_path)self.recognition_thread.recognized_signal.connect(self.update_output)self.recognition_thread.current_text_signal.connect(self.update_status)self.recognition_thread.start()except Exception as e:self.status_label.setText(f"启动识别错误: {str(e)}")def stop_recognition(self):try:if self.recognition_thread:self.recognition_thread.stop()self.recognition_thread.wait()if self.serial_connection and self.serial_connection.is_open:self.serial_connection.close()self.status_label.setText("状态: 语音识别已停止")except Exception as e:self.status_label.setText(f"停止识别错误: {str(e)}")QCoreApplication.quit()def update_status(self, text):self.status_label.setText(f"当前识别: {text}")def update_output(self, text):self.output_text.append(text)def get_parity(self, parity):if parity == "None":return serial.PARITY_NONEelif parity == "Even":return serial.PARITY_EVENelif parity == "Odd":return serial.PARITY_ODDdef get_stopbits(self, stopbits):if stopbits == "1":return serial.STOPBITS_ONEelif stopbits == "1.5":return serial.STOPBITS_ONE_POINT_FIVEelif stopbits == "2":return serial.STOPBITS_TWOdef get_flowcontrol(self, flowcontrol):if flowcontrol == "None":return Falseelif flowcontrol == "Xon/Xoff":return serial.XONXOFFelif flowcontrol == "RTS/CTS":return serial.RTSCTSelif flowcontrol == "DTR/DSR":return serial.DTRDSR
Serial配置界面
import serial#配置串口class SerialConfig:def __init__(self):self.port = Noneself.baudrate = 19200self.parity = serial.PARITY_NONEself.stopbits = serial.STOPBITS_ONEself.flowcontrol = Falseself.bytesize = 8 # 数据位,默认8