功能描述
- 采集摄像头画面,并且实时显示在LCD上
- 二维码识别:可以扫描二维码,转换成文本信息
- 人脸检测:识别摄像头图像中的人脸并且框选
- 人脸识别:拍摄人脸,与系统中的图片进行比较
- 聊天机器人:可以和AI进行对话
- 音频播放:两个 2W/8Ω 的喇叭,形成双通道(悲,在最后录制视频的时候,把焊盘给拔下来了)
- 图片或者视频轮播:循环波形系统中的图片或视频
硬件介绍
Maix Dock(M1W) 是本次使用开发板,其中板载了很多常用的接口和外设,比如:
- RISC-V 64bit 双核处理器
- 只需要单根 typeC 线即可完成供电和下载
- 支持 2.4G 802.11.b/g/n 无线功能
- DAC+PA(支持 2x3W 扬声器)
- Micro SD 卡插槽(TF card)
- DVP摄像头接口
- MEMS 麦克风
- LCD接口
实物展示:
额。。。发现这样只预留了摄像头和LCD,其他外设并不好连接并且我还外接了一个电路板,所以又只能让设备”裸奔“了。
环境搭建
参考官方文档:MaixPy-v1 文档简介 - Sipeed Wiki
需要注意:Maix-I K210仅支持MaixPy-v1!!!,不能使用最新的MaixPy-v4。
本次项目所使用的工具:
- MaixPy IDE:用于便捷调试代码
- kflash_gui:刷写板卡固件
- uPyLoader-win:上传或下载板卡中的文件
- CH340驱动:Maix Dock 使用了
CH340
作为驱动芯片
环境搭建的非常便捷,只需要选择一下路径,一路Next、Next就可以了
硬件外设驱动

根据上述的硬件使用资源图,就可以编写对应的初始化了
# 按键IO
key1IO = 15
key2IO = 11
# WIFI-初始化
fm.register(8, fm.fpioa.GPIO5, force=True)
wifi_en = GPIO(GPIO.GPIO5, GPIO.OUT)
wifi_en.value(0)
# 麦克风-初始化
sample_rate = 16000
record_time = 4 #s
sample_points = 2048
wav_ch = 2
fm.register(20,fm.fpioa.I2S0_IN_D0)
fm.register(30,fm.fpioa.I2S0_WS)
fm.register(32,fm.fpioa.I2S0_SCLK)
rx = I2S(I2S.DEVICE_0)
rx.channel_config(rx.CHANNEL_0, rx.RECEIVER, align_mode=I2S.STANDARD_MODE)
rx.set_sample_rate(sample_rate)
print(rx)
recorder = audio.Audio(path="/sd/receive.wav", is_create=True, samplerate=sample_rate)
queue = []
frame_cnt = record_time*sample_rate//sample_points
# 喇叭-初始化
i2s = I2S(I2S.DEVICE_0)
i2s.channel_config(i2s.CHANNEL_1, I2S.TRANSMITTER, resolution=I2S.RESOLUTION_16_BIT,
cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.RIGHT_JUSTIFYING_MODE)
fm.register(34, fm.fpioa.I2S0_OUT_D1, force=True)
fm.register(35, fm.fpioa.I2S0_SCLK, force=True)
fm.register(33, fm.fpioa.I2S0_WS, force=True)
# 摄像头-初始化
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(1)
sensor.set_vflip(0)
sensor.run(1)
sensor.skip_frames(30)
# 显示屏-初始化
lcd.init(freq=15000000)
lcd.rotation(2)
lcd.mirror(True)
# LED-初始化
my_led.LED_Init()
# 按键-初始化
fm.register(key1IO, fm.fpioa.GPIO3, force=False)
key_fun = GPIO(GPIO.GPIO3, GPIO.IN, GPIO.PULL_UP)
fm.register(key2IO, fm.fpioa.GPIO4, force=False)
key_switch = GPIO(GPIO.GPIO4, GPIO.IN, GPIO.PULL_UP)
AI
OneNET
OneNET是中国移动下的一个物联网开放平台。网址链接:OneNET-AI平台-首页
开发十分的便捷,仅需四个步骤如下:
完成前三个步骤后,就可以在控制台中看到自己已经开通的服务,后面就根据官方的API文档进行调用了,我用人脸检测进行举例
获取Token
API请求格式:
- 请求方式:
GET
- url:
http://ai.heclouds.com:9090/v1/user/app/accessToken?aiKey=xxxxx&secretKey=yyyyy
- http-header:
{Content-Type: application/json }
- 返回值:
{
'stateCode': '0x0000',
'message': 'success',
'data': {
'accessToken': ‘XXXXXXXXXXX’,
'expireTime': 1440
}
}
通过解析返回的JSON文件,当“stateCode”==“0”的时候,就可以获取到正确的”accessToken”了,以下是官方的Python代码
根据官方的文档和代码,进行修改来适应Maixpy的库,修改后代码如下:
def GetKey():
headers = {
'Content-Type': 'application/json'
}
url = "http://ai.heclouds.com:9090/v1/user/app/accessToken?aiKey=换成你的aikey&secretKey=换成你的secretKey"
res = my_http_client.get(url, headers=headers)
#print("response:", res.status_code)
content = res.content
#print("Content (bytes):", content)
content_str = content.decode('utf-8')
parsed_json = ujson.loads(content_str)
#print("Parsed JSON:", parsed_json)
if parsed_json.get('stateCode') == "0x0000":
return parsed_json.get('data', {}).get('accessToken')
return ''
⚠️注意:记得将上述代码中的url中的aiKey和secretKey替换成如下创建的。
- 成功返回:'accessToken'的值
- 失败返回:''
人脸检测
能力介绍:
- 接口能力:快速检测图像中是否有人脸,并返回人脸位置,可实现多人脸检测;
- 图片格式:现支持PNG、JPG、JPEG、BMP,不支持GIF图片;
- 图片大小:上传图片大小不超过2M;图片中主体人脸部分无遮挡,且像素不小于80*80;
- 业务应用:利用自动识别检测人脸技术,应用于特定环境下的人流量统计等场景。
API请求格式: - 请求方式:
POST
- url:
http://ai.heclouds.com:9090/v1/aiApi/picture/FACE_RECO
- http-header:
{token: xxxxxxxx或者Login-Token: xxxxxxxx, Content-Type: application/json }
- request-body:
{ 'picture' : [“base64Str”] }
,base64Str:base64编码格式的图片 - 返回值:
{
"stateCode": "0x0000",
"message": "success",
"data": [
{
"box": {
"x": 499,
"y": 212,
"width": 410,
"height": 410
},
"confidence": 0.9999998807907104,
"label": "face",
"angle": -1.5592374801635744
}
]
}
根据官方的文档和代码,进行修改来适应Maixpy的库,修改后代码如下:
def GetFace(img):
aiKey = GetKey()
headers = {
'Content-Type': 'application/json',
'token': aiKey
}
url = 'http://ai.heclouds.com:9090/v1/aiApi/picture/FACE_RECO'
"""
# 使用本地图片,上传识别
f = open("/sd/1.png", "rb")
file_content = f.read()
base64_bytes = ubinascii.b2a_base64(file_content)
base64Str = base64_bytes.decode().strip()
f.close()
"""
# 使用函数参数,上传识别
base64Str = ubinascii.b2a_base64(img.compress(quality=90)).decode().strip()
data = {
'picture':[base64Str]
}
res = my_http_client.post(url, headers=headers, data=ujson.dumps(data))
#print(res.content)
content = res.content
content_str = content.decode('utf-8')
parsed_json = ujson.loads(content_str)
retCode = parsed_json.get('stateCode')
if retCode == "0x0000":
first_data_item = parsed_json.get('data', [])[0] if parsed_json.get('data') else None
if first_data_item:
box_info = first_data_item.get('box')
print("OneNetGetFace find info:", box_info)
return box_info
else:
print("OneNetGetFace data err\n")
return "-1"
else:
print("OneNetGetFace on find\n")
return "-1"
人脸对比
能力介绍:
- 接口能力:比对两张图片中人脸的相似度,并返回相似度分值;
- 图片格式:现支持PNG、JPG、JPEG、BMP,不支持GIF图片;
- 图片大小:上传图片大小不超过2M;图片中主体人脸部分像素不小于80*80;
- 业务应用:用于比对多张图片中的人脸相似度并返回两两比对的得分,可用于判断两张脸是否是同一人的可能性大小;如智能手机或电脑的登录验证、人证合一验证、会场签到等。
API请求格式: - 请求方式:
POST
- url:`http://ai.heclouds.com:9090/v1/aiApi/picture/FACE_COMPARE?supportMultiFace=false `
- http-header:
{token: xxxxxxxx或者Login-Token: xxxxxxxx, Content-Type: application/json }
- 返回值:
{
"stateCode":"0x0000",
"message":"success",
"data": {
"boxes":[
{
"height": 455, "width":355, "x":527, "y":191
},
{
"height": 455, "width":355, "x":527, "y":191
}
],
"confidence":0.99995
}
}
根据官方的文档和代码,进行修改来适应Maixpy的库,修改后代码如下:
def CompFace(aiKey, secretKey, img1,img2):
aiKey = GetKey(aiKey, secretKey)
headers ={
'Content-Type':'application/json',
'token':aiKey
}
url = 'http://ai.heclouds.com:9090/v1/aiApi/picture/FACE_COMPARE'
base64Str_1 = ubinascii.b2a_base64(img1.compress(quality=90)).decode().strip()
f = open(img2, "rb")
file_content = f.read()
base64_bytes = ubinascii.b2a_base64(file_content)
base64Str_2 = base64_bytes.decode().strip()
f.close()
data = {
'picture':[base64Str_1,base64Str_2]
}
res = my_http_client.post(url, headers=headers, data=ujson.dumps(data))
gc.collect()
#print(res.content)
return res.content
AI对话
能力介绍:
- 接口能力:基于自然语言处理相关技术,对用户问题进行语义匹配与检索,提供自动问答、闲聊对话、任务信息自动提取等功能;
- 业务应用:企业网站咨询,电商平台客服等场景。
API请求格式: - 请求方式:
POST
- url:` http://ai.heclouds.com:9090/v1/aiApi/nlp/es/chatbot `
- http-header:
{token: xxxxxxxx或者Login-Token: xxxxxxxx, Content-Type: application/json }
- 返回值:
{
"text": "String"
"relationalId": "String"
"index": "String"
}
根据官方的文档和代码,进行修改来适应Maixpy的库,修改后代码如下:
def AI(aiKey, secretKey, text):
aiKey = GetKey(aiKey, secretKey)
url = 'http://ai.heclouds.com:9090/v1/aiApi/nlp/es/chatbot'
headers ={
'Content-Type':'application/json',
'token':aiKey
}
data = {
'text':text
}
response = my_http_client.post1(url, headers=headers, data=ujson.dumps(data))
#print(response.text)
if response == '':
return ''
return response.text
问题总结
板载麦克风无法使用
使用的是官方提供的Maixpy-v1的例程,并不能正常的采集音频。
后来发现是MIC的引脚并不是对的,需要自己手动修改
提供的例程管脚是:
fm.register(20,fm.fpioa.I2S0_IN_D0)
fm.register(19,fm.fpioa.I2S0_WS)
fm.register(18,fm.fpioa.I2S0_SCLK)
但是实际上原理图中分为:MIC和MIC0。属于有点粗心大意,乍一看看着管教就是对的
Maxipy IDE卡死
在软件中一点击连接串口(板卡),整个IDE就用不了了,过N久后可以动一下,但是一点击又卡死了。
暂未解决
Maixpy库的不同
在Maixpy官方的固件中,存在着和python中部分精简的库,其中在JSON解析、网络请求的部分都有些些许的不同,其中排查了一个问题很久,在进行base64编码的时候,ubinascii在末尾有一个换行符是需要去除的:ubinascii.b2a_base64(f.read()).decode("utf-8").strip()
焊接水平不行
一开始使用座子直接飞线上去,可以正常使用,但是一不小心就容易把线扯下来
后面绘制了一个转接板,刚好立在上面,
但是还是给我撤下来了啊啊啊!!!焊盘都掉了……想重新焊接个座子再试一下,发送喇叭播不了声音了
项目总结
1. 一开始在电脑上测试对接的是大模型平台全都是百度的,但是百度的接口都是https,其中有几个可以使用http,后面就换到移动的平台了
2. 测试代码的时候比较麻烦,不知道是否还有其他方法,我是在IDE中串口中进行调试的:Ctrl + E:复制整段代码,Ctrl+D运行。
3. 在使用的时候查看相关资料,总是会看到Maixpy-V4版本的方法,但是这款K210仅支持V1的一些简单功能。
4. 焊接水平大大的不行,把板卡的引脚都弄掉了😬