Files
BitFlow-MoE/chat_moe.py
T

185 lines
5.7 KiB
Python

"""
串口发送工具: 通过串口向 micro:bit 发送对话命令
用法:
python chat_moe.py # 自动查找串口
python chat_moe.py COM3 # 指定串口
"""
import sys
import glob
import os
try:
import serial
import serial.tools.list_ports
except ImportError:
print("[ERROR] 需要安装 pyserial:")
print(" pip install pyserial")
sys.exit(1)
def find_serial():
"""自动查找 micro:bit 串口"""
ports = serial.tools.list_ports.comports()
for p in ports:
# 检查是否是 micro:bit (VID:PID = 0d28:0204)
if p.vid == 0x0d28 and p.pid == 0x0204:
return p.device
# 也检查名称包含 MICROBIT 的
if "MICROBIT" in p.description.upper():
return p.device
return None
def send_command(port, text):
"""发送文本并转换为ID命令"""
VOCAB_CHARS = (
"猫狗鸟鱼猪牛马鸡虫羊兔鸭鹅"
"坐跑飞游看吃睡走听来叫爬跳唱画读做"
"在上里到"
"的是好了"
"吗什么怎哪"
"你我他她们它"
"蓝绿红黄白"
"天地水火花草树木日月星云春夏秋冬"
"大小多高远快"
"有没会不"
"人头脚手眼腿"
"垫肉书子"
"一三只两"
"热冷落开"
"自然动植物质色样颜得都"
"你好吗谢谢再见早晚安静"
"很棒爱喜欢乐伤心气"
"名字叫谁和问答应"
"聊天话今天说"
"客用"
"bit"
"\n"
)
CH2I = {c: i for i, c in enumerate(VOCAB_CHARS)}
ctx_ids = [str(CH2I[c]) for c in text if c in CH2I]
if not ctx_ids:
print(f"[warn] 无法识别: '{text}'")
return
cmd = "GEN:" + ",".join(ctx_ids) + "|15"
print(f" 发送: {cmd}")
port.write((cmd + "\n").encode())
def main():
print("=" * 60)
print("BitFlow MoE v4 对话工具")
print("=" * 60)
# 串口
if len(sys.argv) > 1:
port_name = sys.argv[1]
else:
print("\n[search] 正在查找 micro:bit 串口 ...")
port_name = find_serial()
if port_name is None:
print("[ERROR] 未找到 micro:bit 串口!")
print(" 请确保:")
print(" 1. micro:bit 已通过 USB 连接")
print(" 2. main.py 已在 micro:bit 上运行")
print(" 3. 如已知串口, 可指定: python chat_moe.py COM3")
return
print(f"\n[connect] 打开串口: {port_name} @115200")
try:
ser = serial.Serial(port_name, 115200, timeout=2)
except Exception as e:
print(f"[ERROR] 无法打开串口: {e}")
return
print(" 连接成功!")
print()
# 等待 ready
ready = False
for _ in range(20):
if ser.in_waiting:
line = ser.readline().decode('utf-8', errors='ignore').strip()
print(f"< {line}")
if "READY" in line:
ready = True
print()
break
if not ready:
print("[warn] 未收到 READY 信号,micro:bit 可能还在启动...")
# 常用短语列表
phrases = [
"你好", "你好吗", "谢谢", "再见", "早安", "晚安",
"你叫什么名字", "你喜欢什么", "你喜欢猫吗", "你是谁",
"你会什么", "你开心吗", "你在做什么", "今天好吗",
"什么会飞", "什么会跑", "什么会游", "什么吃草",
"天是什么颜色", "猫吃什么", "猫是什么",
]
print("=" * 60)
print("常用短语 (输入序号发送, 或直接输入文字, 输入 q 退出):")
print("=" * 60)
for i, p in enumerate(phrases):
print(f" {i:2d}. {p}")
print()
try:
while True:
try:
query = input(">>> ").strip()
except EOFError:
break
if query.lower() == 'q':
break
if query == '':
continue
# 检查是否是序号
try:
idx = int(query)
if 0 <= idx < len(phrases):
print(f"\n 选择: {phrases[idx]}")
send_command(ser, phrases[idx])
# 读取输出
for _ in range(5):
if ser.in_waiting:
line = ser.readline().decode('utf-8', errors='ignore').strip()
if line.startswith('O:'):
ids = [int(x) for x in line[2:].split(',') if x.strip()]
text = "".join(VOCAB_CHARS.get(i, '?') for i in ids)
print(f"\n 回答: {text}")
print()
break
else:
print(f" {line}")
continue
except ValueError:
pass
# 直接输入文字
send_command(ser, query)
# 读取输出
for _ in range(5):
if ser.in_waiting:
line = ser.readline().decode('utf-8', errors='ignore').strip()
if line.startswith('O:'):
ids = [int(x) for x in line[2:].split(',') if x.strip()]
text = "".join(VOCAB_CHARS.get(i, '?') for i in ids)
print(f"\n 回答: {text}")
print()
break
else:
print(f" {line}")
except KeyboardInterrupt:
pass
finally:
ser.close()
print("\n[done] 已断开连接")
if __name__ == "__main__":
main()