我有一个项目,我房间外的超声波传感器正在检测是否有人距离它不到 73 厘米。好的,可以了,之后会亮一个LCD,提示外面的人要不要进,要进1,不要进2。如果有人按下 1,它会向我的 python 代码发送一个有人想要的序列信息。现在如果有人想要,一个语音到文本的函数将执行,如果整个语音输入包含一个与任何一个相同的词关键字数组中的单词,它会通过串行向 arduino 发送回信息,并使带有连接到我门把手的绳子的伺服器旋转。现在,问题是一旦我检测到语音输入并检查了关键字,它就会发送信息,但不会使伺服旋转。然而,一旦整个事情再次循环并且那个人按下 1,舵机就会旋转,但我什至还没有启动语音命令。就像,语音转文本功能后的串行命令卡在了 arduino 端,代码就停止了。提前谢谢大家!
注意:我已经检查了接线,从我的 arduino 到我的 PC 的 USB 连接,一切都是安全的,这就是为什么我得出结论是因为代码。
Python代码:
import time
import tkinter
import tkinter as tk
import serial
import serial.tools.list_ports
import threading
import speech_recognition as sr
import concurrent.futures
from win10toast import ToastNotifier
# Arduino stuff
com4 = serial.Serial(port="COM4", baudrate=9600)
keywords = ["sige lang", "buksan", "papasukin", "open"]
time.sleep(2)
# Functions
def speech_to_text():
# Initialize recognizer
r = sr.Recognizer()
# Use microphone as source
with sr.Microphone() as source:
print("Speak Anything:")
# Adjust for ambient noise
r.adjust_for_ambient_noise(source)
# Record the audio
audio = r.listen(source)
try:
# Recognize speech using Google Speech Recognition
text = r.recognize_google(audio)
return text
except:
print("Sorry, could not recognize your voice")
return ""
def show_notification(title, message):
toaster = ToastNotifier()
toaster.show_toast(title, message, duration=3)
def arduino_connection():
com_ports = list(serial.tools.list_ports.comports())
arduino_connected = False
for port, desc, hwid in sorted(com_ports):
if 'USB VID:PID=1A86:7523' in hwid:
arduino_connected = True
break
return arduino_connected
def wait_for_keypad_keypress():
# with concurrent.futures.ThreadPoolExecutor() as executor:
while True:
person_outside = com4.readline().decode().strip()
if person_outside == "Wants in":
print("Wants in")
show_notification("test", "Someone wants to go in, Romy!")
speech = speech_to_text()
if any(word in speech for word in keywords):
byte_to_send = 65 # Example byte value
com4.write(byte_to_send.to_bytes(1, 'big'))
print("done")
# Logic
arduino_is_connected = arduino_connection()
if arduino_is_connected:
print("connected")
com4.write("Establish connection".encode())
time.sleep(1)
connection_established = com4.readline().decode().strip()
print(connection_established)
if connection_established:
com4.write("Start detecting".encode())
detecting_state = com4.readline().decode().strip()
print(detecting_state)
if detecting_state == "Detecting":
wait_for_keypad_keypress()
# main_window = tkinter.Tk()
# main_window.withdraw()
# main_window.mainloop()
Arduino代码:
#include <Key.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Servo.h>
// Variables
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte rows = 4;
const byte columns = 3;
char keys[rows][columns] = {
{ '1', '2', '3' },
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
byte rowPins[rows] = { 8, 7, 6, 5 };
byte columnPins[columns] = { 4, 3, 2 };
const int trigPin = 11;
const int echoPin = 10;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, columnPins, rows, columns);
Servo servo;
long duration = 0;
long distance = 0;
bool continueDetecting = false;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Wire.begin();
lcd.init();
servo.attach(9);
}
bool connected = false;
void loop() {
if (!connected) {
String connectToPython = Serial.readString();
if (connectToPython == "Establish connection") {
connected = true;
Serial.println("Connection established");
String detectingState = Serial.readString();
if (detectingState == "Start detecting") {
Serial.println("Detecting");
while (true) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) * 0.0343;
delay(500);
if (distance <= 73) {
lcd.clear();
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("Wanna come in?");
lcd.setCursor(0, 1);
lcd.print("1 = Yes | 2 = No");
unsigned long startTime = millis();
char keyPress = NO_KEY;
while (keyPress == NO_KEY && (millis() - startTime) < 5000) {
keyPress = keypad.getKey();
delay(50);
}
if (keyPress == '1') {
Serial.println("Wants in");
int receivedByte = Serial.read();
String servoState = Serial.readString();
if (receivedByte == 65) {
spinDoorknob();
}
}
}
}
}
}
}
}
void spinDoorknob() {
servo.write(180);
delay(1000);
servo.write(0);
delay(300);
servo.write(90);
}
我尝试为连载阅读添加延迟,但是,根据我在其他论坛上看到的,延迟只会让事情变得更糟,所以我删除了它们。我试图运行该程序,但是,同样的事情发生了。
我也试过发送序列号后换行
我也总是得到这个错误: WNDPROC 返回值无法转换为 LRESULT TypeError: WPARAM 很简单,所以必须是一个 int 对象(得到 NoneType)
win10Toast库通知消失后