本帖最后由 湘里人 于 2025-1-14 16:26 编辑
一、刷micropython_unihiker_k10官方库
具体方法见官方介绍:烧录固件
二、百度千帆大模型:
https://qianfan.cloud.baidu.com/ ... fa8684dc35f119d4f3f
登陆界面
登陆成功后,点击页面上方的“大模型服务与开发平台ModelBuilder”
在右侧找到“应用接入”
创建应用:输入应用名称和应用描述,选择全部服务,点击“确定”创建应用。
应用创建完后,复制 API Key和 Secret Key用于“获取AccessToken”。
二、语音识别和语音合成应用
网址:https://console.bce.baidu.com/ai/#/ai/speech/app/create
1、创建应用。
2、应用创建完后,复制 API Key和 Secret Key用于“获取AccessToken”。
3、领取语音应用的免费额度
进入https://console.bce.baidu.com/ai-engine/speech/overview/index,领取免费资源
三、api调用
进入示例代码中心:https://console.bce.baidu.com/support/?u=dhead#/api
在“全部产品”中选择“千帆ModelBuilder”或“语音技术”
1.获取AccessToken
2、示例代码的获取,以语音识别为例。
四、界面美化 unihiker_k10官方库集成了LVGL(轻量级和多功能图形库),为创建美观的视觉效果提供了可能,但官方固件对中文支持不是很好。
1、建立中文字库,实现中文显示
具体操作见我以前的帖子:K10官方micropython_unihiker_k10固件支持中文显示的方法
2、机器人的动态表情,命名为change_eyes.py
- from unihiker_k10 import screen, acce
- import time, gc
- import lvgl as lv
- import fs_driver, math
-
- # 初始化LVGL和屏幕
- screen.init(dir=2)
- scrn = lv.screen_active()
- scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
-
- # 初始化文件系统驱动
- fs_drv = lv.fs_drv_t()
- fs_driver.fs_register(fs_drv, 'S')
-
-
- # 创建开口向上的弧线
- arc3 = lv.arc(scrn)
- arc3.set_size(200, 100) # 设置弧线的大小
- arc3.set_bg_angles(90, 100) # 设置背景角度为0到180度,表示开口向上
- arc3.set_angles(0, 180) # 设置显示角度为0到180度
- arc3.align(lv.ALIGN.BOTTOM_MID, 50, -60) # 将弧线放置在屏幕底部中间位置,稍微向上移动
-
- # 创建第一个蓝色实心球(眼球)
- eye1 = lv.led(scrn)
- eye1.set_size(60, 30) # 设置大小为32x20像素
- eye1.set_color(lv.color_hex(0x0000FF)) # 设置颜色为蓝色
- eye1.align(lv.ALIGN.TOP_LEFT, 50, 90) # 将眼球放置在第一个圆球的中间
-
- # 创建第二个蓝色实心球(眼球)
- eye2 = lv.led(scrn)
- eye2.set_size(60, 30) # 设置大小为32x20像素
- eye2.set_color(lv.color_hex(0x0000FF)) # 设置颜色为蓝色
- eye2.align(lv.ALIGN.TOP_RIGHT, -50, 90) # 将眼球放置在第二个圆球的中间
-
-
- def animate_mouth():
- for angle in range(360, 300, -10):
- arc3.set_angles(angle, angle + 180) # 设置显示角度为0到180度
- # time.sleep(2) # 持续2秒
- time.sleep(0.1)
- for angle in range(300, 360, 10):
- arc3.set_angles(angle, angle + 180) # 设置显示角度为0到180度
- # time.sleep(2) # 持续2秒
- time.sleep(0.1)
-
-
- # 动态改变眼球的水平位置以模拟表情变化
- def change_eyes():
- # # 向左看
- eye1.align(lv.ALIGN.TOP_LEFT, 40, 90)
- eye2.align(lv.ALIGN.TOP_RIGHT, -60, 90)
- time.sleep(0.2) # 持续1秒
-
- # 向右看
- eye1.align(lv.ALIGN.TOP_LEFT, 60, 90)
- eye2.align(lv.ALIGN.TOP_RIGHT, -40, 90)
- time.sleep(0.2) # 持续1秒
-
- # 回到中间
- eye1.align(lv.ALIGN.TOP_LEFT, 50, 90)
- eye2.align(lv.ALIGN.TOP_RIGHT, -50, 90)
- time.sleep(0.2) # 持续1秒
- animate_mouth()
- # 启动眼球变化
- change_eyes()
-
- # 启动表情变化
- # change_expression()
-
-
复制代码
3、上传字库和机器人表情文件
五、主脚本
- from unihiker_k10 import screen, mic, button, wifi,speaker
- import ubinascii
- import json
- import time
- import urequests as requests
- import lvgl as lv
- import fs_driver, math
- from change_eyes import change_eyes
- from machine import Timer
- # 全局变量
- scrn = None
- font_cn = None
- token= None
- AItoken=None
- text = ""
- label_title = None
-
-
-
- # 连接WiFi
- def connect_wifi(ssid, password):
- wifi.connect(ssid=ssid, psd=password, timeout=50000)
- while not wifi.status():
- time.sleep(0.1)
- print("WiFi connected:", wifi.info())
-
-
-
- # 初始化屏幕和字体
- def init_screen():
- global scrn, font_cn, label_title
- screen.init(dir=2)
- scrn = lv.screen_active()
- scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
- fs_drv = lv.fs_drv_t()
- fs_driver.fs_register(fs_drv, 'S')
- font_cn = lv.binfont_create("S:my_font_16.bin")
- if font_cn is None:
- print("字体加载失败")
- else:
- print("字体加载成功")
-
- # 创建一个新的标签
- label_title = lv.label(scrn)
- label_title.set_text("字体加载成功")
- label_title.set_width(200)
- label_title.align(lv.ALIGN.TOP_LEFT, 20, 20)
- if font_cn:
- label_title.set_style_text_font(font_cn, 0) # 设置中文字体
- scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
-
-
-
-
-
- # 更新标签的回调函数
- def update_label():
- global text
- print("text:",text, time.localtime())
- label_title.set_text(text)
-
-
-
-
- # 百度语音识别
- def baidu_speech_recognize(audio_file, token):
- print("token:",token)
- url = "https://vop.baidu.com/server_api"
- with open(audio_file, "rb") as f:
- audio_data = f.read()
- base64_data = ubinascii.b2a_base64(audio_data)[:-1].decode('utf-8')
- payload = json.dumps({
- "format": "wav",
- "rate": 16000,
- "channel": 1,
- "cuid": "UNIHIKER_K10",
- "speech": base64_data,
- "len": len(audio_data),
- "token": token
- })
- headers = {
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'
- }
- response = requests.post(url, headers=headers, data=payload)
- print(response.text)
- data = json.loads(response.text)
- return ''.join(data['result'])
-
- def Baidu_TTS(filename,text, token):
- # 设置请求参数
- params = {
- 'tok': token,
- 'tex': text, # 直接使用text,不需要quote_plus
- 'per': 5,#基础音库:度小宇=1,度小美=0,度逍遥(基础)=3,度丫丫=4,精品音库:度逍遥(精品)=5003,度小鹿=5118,度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5
- 'spd': 5,#中语速
- 'pit': 5,#中语调
- 'vol': 9,#中音量
- 'aue': 6,#wav,3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k);
- 'cuid': "ZZloekkfqvZFKhpVtFXGlAopgnHnHCgQ",#用户唯一标识
- 'lan': 'zh',
- 'ctp': 1 #客户端类型选择,web端填写固定值1
- }
- headers = {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Accept': '*/*'
- }
- # 将参数编码,然后放入body,生成Request对象
- data = urlencode(params).encode('utf-8')
- # 发送POST请求
- response = requests.post("http://tsn.baidu.com/text2audio", headers=headers,data=data)
- # 检查响应状态码
- if response.status_code == 200:
- # 将返回的音频数据写入文件
- print("开始生成合成音频")
-
- gc.collect() # 写入前收集垃圾
- with open(filename, "wb") as f:
- f.write(response.content)
- gc.collect() # 写入后收集垃圾
- print("完成生成合成音频")
- else:
- print("无法获取音频文件")
-
-
- def Baidu_Big_Model(text,AItoken):#大模型对话函数
- url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie_speed?access_token="+AItoken
-
- payload = json.dumps({
- "messages": [
- {
- "role": "user",
- "content": text
- }
- ],
- "temperature": 0.95,
- "top_p": 0.8,
- "penalty_score": 1,
- "enable_system_memory": False,
- "disable_search": False,
- "enable_citation": False,
- "system": "请将回答控制在30字,最后加个‘完’字结束对话",
- "response_format": "text"
- })
- headers = {
- 'Content-Type': 'application/json'
- }
-
- response = requests.post(url, headers=headers, data=payload.encode('utf-8'))
-
- if response.status_code == 200:
- print(response.text)
- data = json.loads(response.text)
- decoded_str= data['result']
- return(decoded_str)
-
- def urlencode(params):#编码成 URL 编码格式的字符串
- encoded_pairs = []
- for key, value in params.items():
- # 确保键和值都是字符串
- key_str = str(key)
- value_str = str(value)
- # 手动实现简单的URL编码
- encoded_key = key_str.replace(" ", "%20")
- encoded_value = value_str.replace(" ", "%20")
- encoded_pairs.append(f"{encoded_key}={encoded_value}")
- return "&".join(encoded_pairs)
-
- #获取token
- def get_access_token(API_KEY,SECRET_KEY):
-
- url = "https://aip.baidubce.com/oauth/2.0/token"
- params = {
- 'grant_type': 'client_credentials',
- 'client_id': API_KEY,
- 'client_secret': SECRET_KEY
- }
- data = urlencode(params).encode('utf-8')
-
- response = requests.post(url, data=data)
- access_token=json.loads(response.text)['access_token']
- print(access_token)
- return access_token
-
-
-
-
-
- # 开始录音
- def start_recording():
- global scrn, font_cn,label_title,token,AItoken,text
-
- print("开始录音")
- text ="开始对话"
- mic.recode_sys(name="sound.wav", time=5)
- # label_title.set_text("开始录音……")
- # 上传录音并识别
- print("音频上传,进行百度识别")
- text ="音频上传,进行百度识别"
- time.sleep(0.1)
- label_title.set_text(text)
- time.sleep(0.1)
- text = baidu_speech_recognize("sound.wav", token)
- print("百度语音识别结果:", text)
- text = Baidu_Big_Model(text,AItoken)
- time.sleep(0.1)
- label_title.set_text(text)
- time.sleep(0.1)
- audio_file = "audio2.wav"
- Baidu_TTS(audio_file,text, token)#语音合成
- time.sleep(0.1)
- #播放音频
- print("播放音频")
- speaker.play_sys_music(audio_file)
-
-
- def up_recording():
- global scrn, font_cn,label_title,token,AItoken
- label_title.set_text("功能暂未开发")
- # 初始化板载按键传感器 A 和 B
- def init_buttons():
- bt_a = button(button.a)
- bt_b = button(button.b)
- bt_a.event_pressed = start_recording
- bt_b.event_pressed = up_recording
-
- # 主函数
- def main():
- global scrn, font_cn,label_title,token,AItoken,text
- connect_wifi("r……", "wi……")
- init_screen()
- init_buttons()
- API_KEY = "sexS8Y……"
- SECRET_KEY = "nS2qMT……yjhTKrsWQ"
- token = get_access_token(API_KEY,SECRET_KEY)#语音识别和语音合成的token
-
- print(token)
- API_KEY = "ShZO7VeT……lmnF"
- SECRET_KEY = "b5bxt……xV"
- # AItoken ="24.1bd84e812aa……………………"
- AItoken = get_access_token(API_KEY,SECRET_KEY)#大模型的token
-
- text ="按A键开始与大模型对话"
- label_title.set_text(text)
-
- # tim1 = Timer(1)
- # tim1.init(period=100, mode=Timer.PERIODIC, callback=lambda t:update_label())
- while True:
- # # # 启动眼球变化
- change_eyes()
- time.sleep(0.1)
-
- if __name__ == "__main__":
- main()
-
-
-
-
复制代码
需修改部分
文件打包【字库,change_eyes.py,main.py】baiduK10.zip
效果图
六、待完善之处
1、语音识别和合成调用所需时间太长
2、机器人的表情和文字显示会因其它程序的运行而中断
多次尝试,没有解决。
|