上一篇《自制ASRPRO开发板,玩转语音控制》介绍了自制的ASRPRO-CORE开发板。本篇笔记分享下使用ASRPRO开发板,语音控制emo表情机器人。
1、ASRPRO模块介绍
天问五幺ASRPRO-CORE模块是一款针对低成本离线语音应用方案开发的通用、便携、低功耗高性能语音识别模组。它采用最新的ASRPRO芯片,内置神经网络处理器,支持DNN、TDNN、RNN等神经网络及卷积运算,实现语音识别、声纹识别、语音增强、语音检测等功能,具备强劲的回声消除和环境噪声抑制能力。
2、emo表情机器人介绍
详见《ESP32C3手表变身桌面emo表情机器人》。这块手表的主控是ESP32C3,配备了一块1.69英寸的触摸屏,分辨率达到240x320,显示驱动采用的是ST7789,触摸驱动则是CST816T。
3、ASRPRO程序
选择串口通信的示例,适当修改,增加语音控制命令:
点击生成模型:
点击下载:
当提示“是否连接设备ASR-PRO?”时,关闭GND开关,再迅速打开,即可进行下载。如果没有进入下载模式,多重复关开GND开关试试。
4、语音控制
语音控制原理:ASRPRO接收语音,根据语音内容通过串口1输出字符串,ESP32C3通过串口接收字符串,并根据字符串内容显示出不同的表情。
测试代码如下:
from machine import UART, Pin, SPIimport st7789import time
# 初始化串口uart = UART(1, baudrate=9600, bits=8, parity=None, stop=1, tx=Pin(21), rx=Pin(20))
# 初始化屏幕def config(): spi = SPI(1, baudrate=26666666, polarity=0, sck=Pin(5), mosi=Pin(6), miso=Pin(8))
return st7789.ST7789(spi, 240, 320, dc=Pin(2, Pin.OUT), cs=Pin(3, Pin.OUT), inversion=False, rotation=3, options=0)
tft = config()tft.init()
# 定义眼睛的位置和大小eye_radius = 40 # 圆的半径eye_distance = 120 # 两个圆心之间的距离left_eye_x = 100right_eye_x = left_eye_x + eye_distanceeye_y = 100
# 定义眼珠的位置和大小eyeball_radius = 25 # 圆的半径eyeball_width = 50 # 眯眼矩形的宽度eyeball_height = 10 # 眯眼矩形的高度move_dis = eye_radius - eyeball_radius -2
def draw_open_eyes(): # 绘制睁开的眼睛 tft.fill_circle(left_eye_x, eye_y, eye_radius, st7789.WHITE) # 左眼 tft.fill_circle(right_eye_x, eye_y, eye_radius, st7789.WHITE) # 右眼 tft.fill_circle(left_eye_x, eye_y, eyeball_radius, st7789.BLACK) # 左眼球 tft.fill_circle(right_eye_x, eye_y, eyeball_radius, st7789.BLACK) # 右眼球
def draw_closed_eyes(): # 绘制闭上的眼睛 tft.fill_circle(left_eye_x, eye_y, eye_radius, st7789.WHITE) # 左眼 tft.fill_circle(right_eye_x, eye_y, eye_radius, st7789.WHITE) # 右眼 tft.fill_rect(left_eye_x - eye_radius, eye_y - eye_radius, eye_radius * 2 + eye_distance + 2, eye_radius - 5, st7789.BLACK)# 上眼皮 tft.fill_rect(left_eye_x - eye_radius, eye_y + 5, eye_radius * 2 + eye_distance + 2, eye_radius, st7789.BLACK)# 下眼皮
def draw_ji_eyes(): # 绘制斗鸡眼 tft.fill_circle(left_eye_x, eye_y, eye_radius, st7789.WHITE) # 左眼 tft.fill_circle(right_eye_x, eye_y, eye_radius, st7789.WHITE) # 右眼 triangle_eye = [(100, 80), (80, 115), (88, 120), (100, 95), (112, 120), (120, 115)] cen_x, cen_y = tft.polygon_center(triangle_eye) tft.fill_polygon(triangle_eye, 0, 0, st7789.BLACK, 1.57, cen_x, cen_y) tft.fill_circle(left_eye_x, eye_y, 5, st7789.BLACK) # 左眼球 tft.fill_polygon(triangle_eye, eye_distance, 0, st7789.BLACK, 4.71, cen_x, cen_y) tft.fill_circle(right_eye_x, eye_y, 5, st7789.BLACK) # 右眼球
def draw_happy_eyes(): # 绘制快乐的眼睛 tft.fill_circle(left_eye_x, eye_y, eye_radius, st7789.WHITE) # 左眼 tft.fill_circle(right_eye_x, eye_y, eye_radius, st7789.WHITE) # 右眼 tft.fill_circle(left_eye_x, eye_y, eyeball_radius, st7789.BLACK) # 左眼球 tft.fill_circle(right_eye_x, eye_y, eyeball_radius, st7789.BLACK) # 右眼球 tft.fill_circle(left_eye_x, eye_y + move_dis, eyeball_radius, st7789.WHITE) # 左眼球 tft.fill_circle(right_eye_x, eye_y + move_dis, eyeball_radius, st7789.WHITE) # 右眼球
def draw_angry_eyes(): # 绘制愤怒的眼睛 draw_ji_eyes() tft.fill_circle(40, 35, 10, st7789.WHITE) # 生气标志 tft.fill_circle(38, 33, 10, st7789.BLACK) tft.fill_circle(65, 35, 10, st7789.WHITE) tft.fill_circle(67, 33, 10, st7789.BLACK) tft.fill_circle(40, 60, 10, st7789.WHITE) tft.fill_circle(38, 62, 10, st7789.BLACK) tft.fill_circle(65, 60, 10, st7789.WHITE) tft.fill_circle(67, 62, 10, st7789.BLACK)
def draw_sweat_eyes(): # 绘制流汗的表情 tft.fill_circle(left_eye_x, eye_y, eye_radius, st7789.WHITE) # 左眼 tft.fill_circle(right_eye_x, eye_y, eye_radius, st7789.WHITE) # 右眼 tft.fill_circle(left_eye_x, eye_y + move_dis, eyeball_radius, st7789.BLACK) # 左眼球 tft.fill_circle(right_eye_x, eye_y + move_dis, eyeball_radius, st7789.BLACK) # 右眼球 tft.vline(right_eye_x + eye_radius, eye_y - eye_radius, 10, st7789.WHITE) tft.vline(right_eye_x + eye_radius + 5, eye_y - eye_radius, 15, st7789.WHITE) tft.vline(right_eye_x + eye_radius + 10, eye_y - eye_radius, 20, st7789.WHITE)
def main(): # 初始状态为黑屏 tft.fill(st7789.BLACK) draw_open_eyes()
while True: # 读取从串口接收的数据 if uart.any(): uart_MSG = uart.read() print("Received:", uart_MSG)
if uart_MSG == b'happy\r\n': tft.fill(st7789.BLACK) draw_happy_eyes() elif uart_MSG == b'angry\r\n': tft.fill(st7789.BLACK) draw_angry_eyes() elif uart_MSG == b'sweat\r\n': tft.fill(st7789.BLACK) draw_sweat_eyes() elif uart_MSG == b'closed\r\n': tft.fill(st7789.BLACK) draw_closed_eyes() elif uart_MSG == b'open\r\n': tft.fill(st7789.BLACK) draw_open_eyes()
time.sleep_ms(100)
if __name__ == "__main__": main()
注意,ASRPRO输出的字符串带有'\r\n'。
我只列了5种表情,可自行增加,也可以显示文字、图片。
领取专属 10元无门槛券
私享最新 技术干货