硬件介绍
资料
固件地址:下载站 - Sipeed
esp 8285 烧录工具:Flash 下载工具用户指南 - ESP32 - — ESP 测试工具 latest 文档
无线模块的烧录文档:更新板载 ESP32 固件 - Sipeed Wiki
AT 固件地址: Resources | Espressif Systems
openmv接口讲解:image — 机器视觉 — MicroPython 1.22 文档
sipeed接口库:标准库 - Sipeed Wiki
sipeed py工具:下载站 - Sipeed
特性
CPU : RISC-V 64bit 双核处理器,400Mhz 标准频率(可超频)
图象识别:QVGA@60FPS/VGA@30FPS
MEMS麦克风:MSM261S4030H0、灵敏度 : -26(dB,dBFS @1kHz1Pa)
音频:DAC+PA(支持 2x3W 扬声器)
Micro SD 卡插槽(TF card)
下载电路:只需要连接 USB typeC 线即可完成下载
24P DVP 和 24P MCU LCD 连接器
无线功能:支持 2.4G 802.11.b/g/n
介绍
MaixDock 开发是以M1W AI模块作为核心单元,功能非常强大。模块内置64位双核处理器芯片,拥有8M的片上SRAM,在AI机器视觉、听觉性能方面表现突出,内置多种硬件加速单元(KPU、FPU、FFT等),总算力最高可达1TOPS,可以方便地实现各类应用场景的机器视觉/听觉算法,也可以进行语言方向扫描和语言数据输出的前置处理工作。
配备2.4 英寸 LCD (分辨率:240*320)以及OV2640 鱼眼相机。
OV2640是一款由Omni Vision公司生产的1/4寸CMOS UXGA(1632x1222)图像传感器。支持整帧、子采样、缩放和取窗口等不同方式输出影像数据,其UXGA图像最高可达15帧/秒,SVGA可达30帧/秒,CIF可达60帧/秒。
开发环境搭建
下一个ide就不用其他了,下载地址: 下载站 - Sipeed
固件下载地址: 下载站 - Sipeed
烧录工具地址:github.com
固件版本从自带的6.2升级到6.3
项目框图
由m1w拍照并保存到sd卡中,取出sd卡相片后通过大语言模型。解析后的描述信息通过串口发送到m1w,并通过屏幕显示出来。
开发代码
点灯
原理图:
三个led引脚,使用io12 13 14
由灯的接线图,可知,io低电平,灯点亮。
sd卡
测试sd卡的,使用了官方例程:------- ‘capture_image_tool’。
SD卡的测试浪费了两天时间,这里要说一下,还是得看多官方疑难文档。
按照例程的readme来看,只要是spi接口的SD卡,格式是 FAT32 with MBR(msdos) partition,就能用。
对于sd卡,我的理解所有的接口都是spi,所以觉得只要卡没坏,sipeed m1w就是能够挂载sd卡的。
后来换了个卡,例程才好用了。
效果
代码
引入全局变量 board_info
from board import board_info
注册三个led,是将具体的物理引脚主导到gpio外设的某个对象上,如下图的GPIO0。类gpio可看成软件上的概念,只有和实际物理引脚对应,才能实现物理控制作用。
fm.register(board_info.LED_R, fm.fpioa.GPIO0)
fm.register(board_info.LED_G, fm.fpioa.GPIO1)
fm.register(board_info.LED_B, fm.fpioa.GPIO2)
配置gpio对象,设置为输出
led_r=GPIO(GPIO.GPIO0,GPIO.OUT)
led_g=GPIO(GPIO.GPIO1,GPIO.OUT)
led_b=GPIO(GPIO.GPIO2,GPIO.OUT)
加一个while 循环,通过变量led -r g b,就可以实现对led的控制了。
创建新的uart接口,并标记正确的引脚
from machine import UART
fm.register(15, fm.fpioa.UART2_TX, force=True)
fm.register(17, fm.fpioa.UART2_RX, force=True)
uart_A = UART(UART.UART2, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
显示当前序号的相片并序号标记指向下一张相片
show_posi = 0
showPic = None
def show_pic():
global show_posi
global showPic
os.chdir("/sd")
dirs = os.listdir()
images_dir = "cap_images"
cuposi = 0
flag = 0
for d in dirs:
if d[-4:] in ['.jpg', '.png', '.bmp']:
cuposi +=1
if cuposi == show_posi:
flag = 1
images_ST = "/sd/{}".format(d)
print("get pic name is ", images_ST)
showPic = image.Image(images_ST)
lcd.display(showPic)
break
if flag == 0:
show_posi = 0
在相片上显示信息,并自动换行
posiY = 10
def showPicWithStr(str):
global showPic
global posiY
if showPic is None:
return
print("showPicWithStr : ",str," len:",len(str)," posiY: ",posiY)
showPic.draw_string(30,posiY, str, color=(0,0,0), x_spacing=8,scale=1,mono_space=False,thickness =2)
posiY +=15
lcd.display(showPic)
计算相片名字并截取当前摄像头数据并保存到sd卡
if takephoto == 1:
time.sleep_ms(500)
del img0
img0 = sensor.snapshot()
f_name = "{}_{}.jpg".format(images_dir, save_count)
img0.save(f_name, quality=95)
dirs = os.listdir()
print(dirs);
save_count += 1
takephoto = 0
根据标记位的值选择显示sd卡里的相片还是实时显示摄像头的数据
if fakg == 0:
del img0
img0 = sensor.snapshot()
lcd.display(img0)
else:
show_posi+=1
print("show posi pic :",show_posi)
show_pic()
while(True):
if fakg == 0:
break
if uart_A.any():
time.sleep_ms(10)
jpeg_buff = uart_A.read()
print("recv = ", jpeg_buff)
showPicWithStr(jpeg_buff)
-------------------------------------------------------------------------------------------------------------------------------------------
保存,读取,发送数据通过串口到pc
print("take photo!!!!!")
#save [pic]
img0 = sensor.snapshot()
lcd.display(img0)
img0.save("zsy002.jpg", quality=95)
# read pic
imagedata = open("zsy002.jpg",'rb').read()
# send pic
uart_A.write(b"222222")
time.sleep_ms(2000)
posiY = 10
senlen = uart_A.write(imagedata)
print("send iamge len: ",senlen)
time.sleep_ms(1000)
uart_A.write(b"111111")
得到串口下发的大模型解析数据,并展示到屏幕上
takephoto =0
jishuq =15
while(jishuq):
if uart_A.any():
miaoshuStr = uart_A.read(30)
print("image str: ",miaoshuStr)
showPicWithStr(miaoshuStr)
else:
time.sleep_ms(2000)
jishuq -= 1
time.sleep_ms(20000)
pc上python的代码讲解
python的pc程序,是基于官方的图片解析的例程。
官方api的认证
appid = "6e00****" #填写控制台中获取的 APPID 信息
api_secret = "ZTg0YmVkYzMwYmI2NGE3OTZ*****" #填写控制台中获取的 APISecret 信息
api_key ="9ee9507efb642039b147c3e6*****" #填写控制台中获取的 APIKey 信息
imagedata = open("ImageUnderstanding_Python/img_1.png",'rb').read()
imageunderstanding_url = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image"#云端环境的服务地址
text =[{"role": "user", "content": str(base64.b64encode(imagedata), 'utf-8'), "content_type":"image"}]
打开串口
ser = serial.Serial("COM4", 115200,timeout=0.5)
ser.set_buffer_size(tx_size=30)
if ser.isOpen(): # 判断串口是否成功打开
print("打开串口成功。")
print(ser.name) # 输出串口号
else:
print("打开串口失败。")
得到k210拍摄的相片,并发送到大数据模型,等到大模型的描述信息返回,并通过串口发送到k210
answer = ""
FileJpg = None
while True:
com_input = ser.read(8192)
if com_input: # 如果读取结果非空,则输出
if com_input[0:6] == b"111111":
print("end image")
if FileJpg != None:
FileJpg.close()
FileJpg = None
imagedata = open("ImageUnderstanding_Python/zsy1.jpg",'rb').read()
text =[{"role": "user", "content": str(base64.b64encode(imagedata), 'utf-8'), "content_type":"image"}]
question = checklen(getText("user","最简单的用英语描述一下,不超过200字"))
main(appid, api_key, api_secret, imageunderstanding_url, question)
getText("assistant", answer)
ser.write( answer.encode())
continue
if com_input[0:6] == b"222222":
print("start image")
if FileJpg != None:
FileJpg.close()
FileJpg= open('ImageUnderstanding_Python/zsy1.jpg', 'wb+')
continue
print(len(com_input))
if FileJpg != None:
FileJpg.write(com_input)
效果展示
疑难杂症
无线模块不可使用,以上日志看得出来只有一级boot,8285模块固件烧录缺失,需要重新烧录固件。
烧录串口指令失败,返回的都是乱码。
通过烧录工具,能看到晶振是0,看其他人的晶振都是有数据的,不确定是不是芯片错误,导致指令执行返回数据错误。
跳转用户程序后,无法运行,失败了,再次芯片重启运行,无限循环重启。
一个月了,受不了了,我觉得我的板卡里的8285是坏掉的。
不管他了,烧录程序已经把我逼疯了。
---------------------------------------------------------------------------
关于显示的颠倒问题,开发过程中出现了图片和字体显示方向颠倒的问题。图像正的,字体是倒着的。
查看接口draw_string的参数,由位置,间距和字符串,但是没有对于显示颠倒的解释。
后来测试发现,字体不能调正,它是固定按照xy坐标,正的方向现实的,所以那个显示颠倒是因为图像倒了。
图像的显示分为两个部分:sensor的方向,lcd的方向。
这里就设计到两个接口:
sensor.set_vflip(1) 摄像头垂直翻转。
lcd.rotation(0) 显示的屏幕旋转几个90度
我的问题是摄像头拍的反了,垂直倒过来就好了。
如下
创建uart2 乱码
发了一串字符,只能得到前几个字符是正确的,后面的字符都是错误的,如下
发了一大串1.
只有几个字符是正确的
原因
打开的uart模式不一致,这里犯了经验错误了,直接使用默认配置读写了。
接口初始化说明
和这里保持一致即可
---------------------------
例程有讲,在字符串出现 \n时,会自动换行,可验证例程:
import lcd, time
import image
lcd.init(freq=15000000)
img = image.Image()
# img.draw_rectangle((0,0,240,240), fill=True, color=(30,30,30))
str = b'hello \nmaixpy'
img.draw_string(60, 100, str, scale=4)
lcd.display(img)
while True:
time.sleep_ms(10) # ohter event
验证确实有用,但是加载汉字字库‘0xA00000_font_uincode_16_16_tblr.Dzk’后
换行的转义就会失效,不知道问题出现在哪里,有机会研究研究。
文档
大模型的讲解 :Maix Bit(K210)保姆级入门上手教程---外设基本使用_maixbit-CSDN博客
官方Wiki: Board - Sipeed Wiki
结语
电子森林的文本编辑器支持 ctrl+s保存,这点真好用。
算是第二次测试这类ai开发板子,有点陌生,有点无从下手,不过每天参与一点,慢慢就能入门,还算大概了解一点。
看多了,学多了,也就会了,希望电子森林活动越来越好。