目录
关于亚博的K210视觉模块
亚博的这款K210视觉模块是我在准备2023年电赛的时候入手的,自我感觉功能强大,易于上手,而且官网资料丰富,还有专门的技术服务。可用于循迹,数字识别,颜色识别,物体识别,二维码识别等。
K210与stm32f103c8t6串口通信接线图
说明:用K210的串口引脚与stm32f1的USART3串口三相连
TX-----------PB11(USART3_RX)
RX----------PB10(USART3_TX)
K210模型训练识别物体与stm32通信过程
在Maixhub官网进行模型的训练,用maixpy.IDE打开训练模型生成的main.py文件,进行代码的修改和串口通信的添加。修改完成后将模型的三个代码放在SD卡的根目录下,同时将main.py保存到k210开发板boot.py,实现K210的脱机运行。按上图接线,运行代码即可实现。调试时可以通过外接oled显示。
模型训练过程可参考连接:k210视觉模块进行模型训练和数字识别,初学者,有大佬有好的方法可以分享一下_哔哩哔哩_bilibili
演示视频:
k210视觉模块识别数字并把信息传到stm32_哔哩哔哩_bilibili
代码
k210的main.py里需要加入的代码
from fpioa_manager import fm
from machine import UART
import time
# binding UART2 IO:6->RX, 8->TX
fm.register(6, fm.fpioa.UART2_RX)
fm.register(8, fm.fpioa.UART2_TX)
yb_uart = UART(UART.UART2, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
//注意通信协议,波特率必须一致否则会出现乱码传错的问题
以下两行代码加在主循环中的识别后在k210界面显示类别准确率代码之后
array = bytearray([obj.classid()]) //obj.classid()代表识别到的物体的类别信息
yb_uart.write(array) //通过串口发送出去
一个模型的案例代码
# generated by maixhub, tested on maixpy3 v0.4.8
# copy files to TF card and plug into board and power on
import sensor, image, lcd, time
import KPU as kpu
import gc, sys
from fpioa_manager import fm
from machine import UART
import time
# binding UART2 IO:6->RX, 8->TX
fm.register(6, fm.fpioa.UART2_RX)
fm.register(8, fm.fpioa.UART2_TX)
yb_uart = UART(UART.UART2, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
input_size = (224, 224)
labels = ['H', 'O', 'K', 'R']
anchors = [2.72, 1.34, 5.45, 4.94, 4.0, 2.69, 3.28, 4.25, 1.47, 2.86]
def lcd_show_except(e):
import uio
err_str = uio.StringIO()
sys.print_exception(e, err_str)
err_str = err_str.getvalue()
img = image.Image(size=input_size)
img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
lcd.display(img)
def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing(sensor_window)
sensor.set_hmirror(True)
sensor.set_vflip(True)
sensor.run(1)
lcd.init(type=1)
lcd.rotation(2)
lcd.clear(lcd.WHITE)
if not labels:
with open('labels.txt','r') as f:
exec(f.read())
if not labels:
print("no labels.txt")
img = image.Image(size=(224, 224))
img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
lcd.display(img)
return 1
try:
img = image.Image("startup.jpg")
lcd.display(img)
except Exception:
img = image.Image(size=(224, 224))
img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
lcd.display(img)
try:
task = None
task = kpu.load(model_addr)
kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
while(True):
img = sensor.snapshot()
t = time.ticks_ms()
objects = kpu.run_yolo2(task, img)
t = time.ticks_ms() - t
if objects:
for obj in objects:
pos = obj.rect()
img.draw_rectangle(pos)
img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
if obj.value()>0.5:
array = bytearray([obj.classid()])
yb_uart.write(array)
img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))
lcd.display(img)
except Exception as e:
raise e
finally:
if not task is None:
kpu.deinit(task)
if __name__ == "__main__":
try:
# main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
main(anchors = anchors, labels=labels, model_addr="/sd/model-86165.kmodel")
except Exception as e:
sys.print_exception(e)
lcd_show_except(e)
finally:
gc.collect()
stm32f103代码
Serial3.c代码
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
uint8_t Serial3_RxData;
uint8_t Serial3_RxFlag;
void Serial3_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART3, ENABLE);
}
uint8_t Serial3_GetRxFlag(void)
{
if (Serial3_RxFlag == 1)
{
Serial3_RxFlag = 0;
return 1;
}
return 0;
}
uint8_t Serial3_GetRxData(void)
{
return Serial3_RxData;
}
void USART3_IRQHandler(void)
{
if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
{
Serial3_RxData = USART_ReceiveData(USART3);
Serial3_RxFlag=1;
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
}
serial3.h代码
#ifndef __SERIAL3_H
#define __SERIAL3_H
extern uint8_t Serial3_RxData;
extern uint8_t Serial3_RxFlag;
void Serial3_Init(void);
uint8_t Serial3_GetRxFlag(void);
uint8_t Serial3_GetRxData(void);
#endif
main.c代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial3.h"
//串口三:B10,B11
uint8_t RxData3;
int main(void)
{
OLED_Init();
Serial3_Init();//串口三接k210只接收
OLED_ShowString(1,1,"Rxdata:");
while (1)
{
if(Serial3_GetRxFlag()==1)//当接收到数据时
{
RxData3=Serial3_GetRxData();
OLED_ShowHexNum(1,8,RxData3,2);
}
本人新手小白,有不对的地方欢迎各位大佬指点!