K210视觉循迹与STM32串口通信实现智能车功能

目录

个人感慨与感悟

K210视觉循迹


个人感慨与感悟

本人是一名大二的二本学生,本篇文章记录一下我这一年多的学习历程(主要还是针对标题的内 容)。下面是我的一些经历和感悟,不感兴趣的可以直接跳过-——————————

       高考完之后,在我收到录取通知书之后,父母让我提前学点大学的东西,比如高数英语之类的。后来,我就在b站上面逛逛,然后了解到了python这门语言。后来……..被卖课的骗了,上了及几十节基础语法(上网上搜,随便一搜一大堆),花了三千多(服了,当时我还傻乎乎的分期付款);正如我前几篇文章。

        开学之后,在新生群里,看到有机器人之类的社团招生。想着给自己的大学生活找点事情做做,进入社团之后,我被那些智能车给深深的迷住了。从此开启造车之路。

        大一上没学啥。就学了Arduino的一些基础知识,如digitalRead(),analogWrite()函数之类的,后来在期末的时候勉强做出了一个小车。仅仅能控制正转反转哈哈哈。当时一直不理解寻迹小车是生么个逻辑,为什么检测到黑线能直走,为什么检测到十字路口就能转弯;(实际上,就是循迹传感器检测到黑线返回高电平(也有的是低电平),单片机检测到为高电平(低电平),我就控制电机,从而它才能走。而不是检测到高电平它自己就动,而是我写了代码让他动而已)

第一次做的小车

​​​​

大一下学的还行,还是学arduino。现在看来进度挺慢的。就学了一些模块,如超声波,机械臂,esp8266,激光传感器,播放器之类的。因为口罩原因,所有吉林省电赛推迟举办了,然后我就碰巧让我遇上了,那年省赛是自主命题,也是小车循迹,不过那时候我还没有完全搞清楚循迹的逻辑,很菜,然后连循迹都没循好,(扇形那块卡住了),后来和学长合作,给学长了做了个人机互界面

人机交互,发送数据
淘晶驰的显示屏

 升大二时候的暑假,打了电赛,也取得了一点成绩(大佬轻喷,手下留情),我做的是E题,激光追踪,主控还是用的Mega2560,搭配云台,K210。

2023电赛

 大二上,也就是这个学期。提前一个月准备   吉林省人工智能创新大赛。打了四次板子,车身外壳用3d打印机打的,最后比赛前一天晚上摄像头被我搞坏了,哎。好了,正式开始正题吧

K210视觉循迹

       K210基于MicroPython 语言,而“MicroPython 是 Python 3 编程语言的精简高效实现。说人话就是K210用python编程。

       我是利用K210检测物体的方法来写的循迹,这个方法的话肯定是没有利用二值化那些方法寻线好,因为我选择的赛道是全地形赛道,需要识别不同颜色的障碍物,所以只能靠检测物体来做。

全地形赛道

 先附上源码(参考CSDN一些大佬文章写的,不是纯手搓哈哈哈,刚接触K210,还没那个实力

/(ㄒoㄒ)/~~)

# Untitled - By: ZWHSONDER - 周四 10月 26 2023

# 导入模块
import sensor, time, image ,lcd                                 
from machine import UART 
from fpioa_manager import fm 


# 配置串口引脚
fm.register(18, fm.fpioa.UART1_TX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)


# 感光元件设置
sensor.reset()                                              
                

sensor.set_pixformat(sensor.RGB565)                        
sensor.set_framesize(sensor.QVGA)                           

sensor.set_auto_exposure(1)                                 

sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)          


sensor.set_vflip(1)                                                                              
sensor.set_hmirror(False)         
sensor.skip_frames(time = 2000) 




# 显示屏初始化
lcd.init(freq=15000000)



# 创建时钟对象
clock = time.clock()                                       



# 寻找色块
# 定义类
class color_property():
    cx                      =  0                            
    cy                      =  0                           
    flag                    =  0                           
    color                   =  0                            
    pixels_max              =  0                                      

    color_threshold         = (0, 0, 0, 0, 0, 0)            
    color_roi               = (0,0,320,240)                 
    color_x_stride          =  1                            
    color_y_stride          =  1                            
    color_pixels_threshold  =  100                          
    color_area_threshold    =  100                          
    color_merge             =  True                         
    color_margin            =  1                            




# 定义黑色色块
black = color_property()
black.color_threshold         = (0, 20, -9, 4, -5, 6)
black.color_roi               = (0,120,320,240)
black.color_x_stride          =  1
black.color_y_stride          =  1
black.color_pixels_threshold  =  4000
black.color_area_threshold    =  4000
black.color_merge             =  True
black.color_margin            =  1





#串口发送数据
def sending_data(x,y):
    FH = bytearray([0x2C,0x12,x,y,0x5B])
    uart_A.write(FH);

# 定义寻找色块函数
def opv_find_blobs(color,led_flag):
    color.pixels_max = 0                                    
    color.flag       = 0                                   
    color.led_flag   = 0                                    

    for blobs in img.find_blobs([color.color_threshold],    
    roi = color.color_roi,                                 
    x_stride = color.color_x_stride,                        
    y_stride = color.color_y_stride,                       
    pixels_threshold = color.color_pixels_threshold,        
    area_threshold = color.color_area_threshold,            
    merge = color.color_merge,                              
    margin = color.color_margin):                           
        img.draw_rectangle(blobs[0:4])                     
        if color.pixels_max < blobs.pixels():               
            color.pixels_max = blobs.pixels()
            color.cx = blobs.cx()
            color.cy = blobs.cy()                           
            color.w = blobs.w()
            color.h = blobs.h()
            color.flag = 1                                 
            color.density = blobs.density()                                           



def zi_tai_jiao_zheng():    #只用于循普通黑线中的姿态矫正
      opv_find_blobs(black,1)
      if black.flag == 1:                              # 标记画面中被找到的最大色块的中心坐标
         if black.w<90:
            if black.cx>180:
               if black.cy>160:
                  if black.cy<240:
                     if black.cx<215:
                        sending_data(1,1)
                        print("x=%d,y=%d"%(black.cx,black.cy))
                     elif black.cx<240:
                          sending_data(1,2)
                          print("x=%d,y=%d"%(black.cx,black.cy))
                     elif black.cx<260:
                          sending_data(1,3)
                          print("x=%d,y=%d"%(black.cx,black.cy))
                     elif black.cx<290:
                          sending_data(1,4)
                          print("x=%d,y=%d"%(black.cx,black.cy))
                     elif black.cx<320:
                          sending_data(1,5)
                          print("x=%d,y=%d"%(black.cx,black.cy))
                     elif black.cx<345:
                          sending_data(1,6)
                          print("x=%d,y=%d"%(black.cx,black.cy))
            elif black.cx<180:
                   if black.cy>160:
                      if black.cy<240:
                         if black.cx>130:
                            sending_data(2,1)
                            print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx>110:
                              sending_data(2,2)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx>90:
                              sending_data(2,3)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx>70:
                              sending_data(2,4)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx>40:
                              sending_data(2,5)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx>15:
                              sending_data(2,6)
                              print("x=%d,y=%d"%(black.cx,black.cy))

def shi_zi():
      opv_find_blobs(black,1)
      if black.flag == 1:
         if black.w >300:
            if black.h >60:#80
               if black.cx>140:
                  if black.cx<220:
                     if black.cy>160:
                        if black.cy<200:
                           sending_data(4,1)
                           time.sleep(1)
                           print("222222222w=%d,h=%d"%(black.w,black.h))



# 主函数
while(True):
    clock.tick()                                            
    img = sensor.snapshot()                               
    opv_find_blobs(black,1)                                 
    opv_find_blobs(red,3)
    zi_tai_jiao_zheng()
    shi_zi()
    lcd.display(img)

我用的固件是maixpy v0.6.2 84 g8fcd84a58.bin(固件不同,库也不同)

大概思路:首先,定义一个类函数(这样方便定义不同颜色)。定义黑色的色块。识别到黑色色块画矩形。然后对黑色色块加些限制条件,根据不同条件(这样我们就会知道小车处于什么状态),向C8T6发送不同的数据,从而32执行不同的代码,决定小车往哪走。

导入各类模块

          

# 导入模块
import sensor, time, image,lcd                                 
from machine import UART 
from fpioa_manager import fm 

①import sensor,time,image,lcd   

# 导入感光元件模块 sensor 跟踪运行时间模块 time 机器视觉模块 image

导入这些模块,才能使用里面的函数

②from machine import UART 

#导入串口库函数(为了K210和stm32之间串口通信)

③from fpioa_manager import fm

#GPIO重定向函数(导入这个函数,我们就可以定义引脚了(K210得映射引脚,不然就用不了,就是把芯片上的引脚映射到具体K210板子上外拓的引脚上)

配置引脚

# 配置串口引脚
fm.register(18, fm.fpioa.UART1_TX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)

①fm.register(18, fm.fpioa.UART1_TX, force=True)

#映射串口引脚,我这里是将芯片上串口一的发送引脚映射到k210板子上的18号位引脚

fm.register(pin,function,force=False)

pin:芯片外部IO口,也就是K210板子上面外拓的引脚

function:芯片功能,例如这儿的   UART1_TX,它的功能就是发送数据

force=True:强制注册,清除之前的注册记录

②uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)

#设置串口引脚一系列参数;machine.UART(uart,baudrate,bits,parity,stop,timeout, read_buf_len)

uart:串口编号

baudrate:波特率

bits:数据位,默认8

parity:校验,默认None,0为偶校验,1为奇校验

stop:停止位,默认1

timeout:串口接收超时时间

read_buf_len:串口接收缓冲大小

感光元件设置

#感光元件设置
sensor.reset()                                                           

sensor.set_pixformat(sensor.RGB565)                         
sensor.set_framesize(sensor.QVGA)                           

sensor.set_auto_exposure(1)                               

sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)          

sensor.set_vflip(1)                                                                           
sensor.set_hmirror(False)        
sensor.skip_frames(time = 2000)                             

①sensor.reset()

# 重置并初始化感光元件 默认设置为 摄像头频率 24M 不开启双缓冲模式(用人话说就是“初始化摄像头”

②sensor.set_pixformat(sensor.RGB565)

#sensor.set_pixformat(pixformat);设置像素格式;pixformat有2个参数:

sensor.GRAYSCAL:灰度图像,每像素 8 位(1 字节)(处理速度快)

sensor.RGB565:   彩色图像,每像素为16位(2字节),5位用于红色,6位用于                              绿色,5位用于蓝色(但是处理速度比灰度图像要慢)

③sensor.set_framesize(sensor.QVGA) 

sensor.set_framesize(framesize),设置每帧大小,其实就是图像尺寸,有以下的参数:

sensor.VGA    sensor.QVGA   sensor.QQVGA  sensor.QQQVGA  从左到右,帧数逐渐变小(尺寸变小),每秒钟拍下的照片变多,从而更精确

④sensor.set_auto_exposure(1)

#设置自动曝光

⑤sensor.set_auto_gain(False)

#关闭自动增益,自动增益:放大电路的增益自动随信号强度调整而自动控制方法,会影响对颜色的判断,所以建议关掉,也就是False

⑥set_auto_whitebal(False)

#关掉自动白平衡;白平衡:是描述显示器中红、绿、蓝三基色混合生成后白色精确度的一项指标,数值越高,色调越暖,数值越低,色调越冷!

⑦sensor.set_vflip(1)

#将画面垂直反转(我的K210有点奇怪,就是它的图像是左右反的(镜像),所以我得让他图像反转过来)

⑧sensor.set_hmirror(False)

#不水平翻转,如果是True则水平翻转,这主要是针对lcd屏内显示的图像(如果图像是倒着,则用该函数)

sensor.skip_frames(time = 2000)

#sensor.skip_frames([n, time]):n:摄像头配置后跳过的帧数;time:等待时间

如果n和time均没指定,则默认跳过300毫秒的帧。(我这里是跳过2000毫秒的帧数)

显示屏和时钟

lcd.init(15000000)
clock = time.clock()     

①lcd.init(freq=15000000)

# 初始化lcd屏,lcd.init(type=1,freq=15000000,color=lcd.BLACK)

type:lcd类型

freq:通信频率

color:LCD初始化的颜色

而我这里传了一个参数叫freq(即-频率),是指驱动lcd的时钟频率,这里是15MHZ,其它参数默认

②clock = time.clock()

#创建一个时钟;用于计算 FPS(每秒帧数)

定义类(寻找色块)

class color_property():
    cx                      =  0                           
    cy                      =  0                            
    flag                    =  0                            
    color                   =  0                                                   
    pixels_max              =  0                                                   

    color_threshold         = (0, 0, 0, 0, 0, 0)            
    color_roi               = (0,0,320,240)                 
    color_x_stride          =  1                            
    color_y_stride          =  1                            
    color_pixels_threshold  =  100                          
    color_area_threshold    =  100                          
    color_merge             =  True                         
    color_margin            =  1                            

①cx,cy:分别代表色块正中心的x轴值和y轴值

②flag:色块标志位,1代表找到色块,0代表没找到色块

③color:色块颜色标志位,下面在实例化类的时候,你可以设定值(比如:实例化黑色块,你设它为666,那么则666代表黑色)

④pixels_max:色块像素最大值(搞这个便于我们筛选掉那些误判的小像素,减少影响)

⑤color_threshold:色块颜色阈值,识别是哪种颜色就是靠的这个(阈值怎么调,网上一搜一大堆,这里就不赘述了哈)

⑥color_roi:色块寻找区域(感兴趣区域);

(x轴起始值,y轴起始值,x轴结束值,y轴结束值)选择感兴趣的区域,这四个值根据你想要检测的区域来设定,一旦设定了,它就只能检测你设定的区域里的色块,就算其他区域有咱想要的色块,他也不会检测到!!!

⑦color_x_stride,color_y_stride:色块的x轴y轴像素最小宽度(同样可以减小误差),假如我们想要的色块很大,那太小的肯定不符合,但我们又不想让它检测到,那就可以设置最小宽度,值小于这个宽度的就不检测。

⑧color_pixels_threshold,color_area_threshold:色块像素个数阈值;色块被框面积阈值   (这两用法和⑦简直一毛一样的作用,那既然一样,为什么还要写这个,因为有特殊情况,所以我们写⑧纯粹是多给它个限制条件而已,保险,防止误判!!!)

⑨color_merge,color_margin:

1.是否合并寻找到的色块 ,True 则合并 False 则不合并;

2.色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个相距1像素 则会将这些色块合并;

实例化类

这里我就写一个黑色块,其他色块可以自行添加

# 实例化类
# 黑色
black = color_property()
black.color_threshold         = (0, 20, -9, 4, -5, 6)
black.color_roi               = (0,120,320,240)
black.color_x_stride          =  1
black.color_y_stride          =  1
black.color_pixels_threshold  =  4000
black.color_area_threshold    =  4000
black.color_merge             =  True
black.color_margin            =  1

这些参数定义类上面都说过,所以这里就没必要再次阐述,我就说一下color_roi参数的设置

为什么我这里设置(0,120,320,240),而不是(0,0,320,240)。因为如果是从y轴0开始的话,识别范围大,而我这里设置从y轴120开始,则就意味着,在y轴我只检测从120-240内的颜色,它识别范围变小,所以误差也就变小,容错率变高。你也可以设置成其他数,看需求。

串口发送数据

我这里我就大概解释一下,不仔细说了

这一步很重要,是用于K210和STM32之间通信。两者通信的根本是在于发送“字符”或者“数字”;

#串口发送数据
def sending_data(x,y):
    FH = bytearray([0x2C,0x12,x,y,0x5B])
    uart_A.write(FH);

UART.write(buf):串口发送数据函数,buf:需要发送的数据

那么这里为什么我要在这个数组里加上“0x2C,0x12,0x5B”呢?

答:串口有   起始位,数据位,校验位,停止位。0x2C,0x12为起始位。

①为什么要有起始位?

起始位是相当于告诉单片机,我从这里“开始”。所以,如果STM32串口检测到0x2C,则意味这串口接收到数据了。     ps:那么为什么不直接接收“数据位”呢?因为会有时候接收不到数据,比如说我发“123456”,而我只收到“23456”,那么请问这个数据还有用吗,答案是肯定没有用的!而有了“开始位”则不一样,比如说我接收,好,如果开头接收到的第一个数据不是0x2C,则我们就不要了呗,直到再次检测到0x2C !两个起始位保险一点,道理一样的!

②什么是数据位呢?

“数据位”就是你要发送的数据,例如单个字符,还是数字。就是我上面所说的“两者通信的根本是在于发送“字符”或者“数字”。

③什么停止位?

一般停止位为1,是告诉单片机,我们检测到1,数据接收完了(一整个数组),那么0x5B又是什么呢?他既是检测数据接收的完整性的一个东西,又是告诉单片机我接收完成,但是得等到检测停止位为1,才能停止接收,直下一次检测再检测到开始位。

定义寻找色块的函数

之前那是定义色块,这里是寻找色块!两者的区别就是字面上的意思,定义色块 or  寻找色块

def opv_find_blobs(color,led_flag):
    color.pixels_max = 0                                    
    color.flag       = 0                                    
    color.led_flag   = 0                                    

    for blobs in img.find_blobs([color.color_threshold],   
    roi = color.color_roi,                                  
    x_stride = color.color_x_stride,                        
    y_stride = color.color_y_stride,                       
    pixels_threshold = color.color_pixels_threshold,       
    area_threshold = color.color_area_threshold,            
    merge = color.color_merge,                              
    margin = color.color_margin):                          
        img.draw_rectangle(blobs[0:4])                      
        if color.pixels_max < blobs.pixels():               
            color.pixels_max = blobs.pixels()
            color.cx = blobs.cx()                           
            color.cy = blobs.cy()
            color.w = blobs.w()
            color.h = blobs.h()
            color.flag = 1                                  
            color.density = blobs.density()                 

(写到这里,已是凌晨3:28 ; 累,但是生命的意义在于不停的创作!)

①:

color.pixels_max = 0   :   重置色块最大像素数量

color.flag = 0   :  重置色块标志位

color.led_flag = 0  :  重置LED标志位

每一次都重置,可以避免误判,之前检测到的色块影响;

②:

    for blobs in img.find_blobs([color.color_threshold],   
    roi = color.color_roi,                                  
    x_stride = color.color_x_stride,                        
    y_stride = color.color_y_stride,                       
    pixels_threshold = color.color_pixels_threshold,       
    area_threshold = color.color_area_threshold,            
    merge = color.color_merge,                              
    margin = color.color_margin):        

这个是一个函数,寻找色块函数(原始函数):

img.
find_blobs
([thresholds],
roi
=my_roi,
x_stride
=
0
,
y_stride
=
0
,

invert
=
False
,
area_threshold
=
0
,
pixels_threshold
=
0
,
merge
=
False
)

参数 用法
[thresholds] 必须是元组列表,定义你想追踪的颜色范围。
roi 色块寻找区域(感兴趣区域)
x_stride 色块x轴像素最小宽度
y_stride 色块y轴像素最小宽度
pixels_threshold 色块像素个数阈值
area_threshold 色块被框面积阈值
merge color.color_merge实际上就是我们在定义类的时候的True
margin 色块合并间距

  • ③ img.draw_rectangle(blobs[0:4])

    标记色块 参数
    img.draw_rectangle(x, y, w, h[, color[, thickness=1[, fill=False]]])
    画矩形

    (x,y)
    :
    起始坐标;w:宽度;
    h:
    长度;color:颜色;thickness:边框粗细;fill:是否填充。

    img.draw_circl(x, y, radius[, color[, thickness=1[, fill=False]]])
    画圆


    x,y

    :
    圆心;
    radius:
    半径;
    color
    :颜色;
    thickness:
    线条粗细;

    fill
    :是否填充。

    img.draw_arrow(x0, y0, x1, y1[, color[, size,[thickness=1]]])
    画箭头


    x0,y0

    :
    起始坐标;(
    x1,y1

    :
    终点坐标;
    color:
    颜色;
    size:
    箭头位置

    大小。
    thickness
    :线粗细。

    img.draw_cross(x, y[, color[, size=5[, thickness=1]]])
    画十字交叉


    x,y

    :
    交叉坐标;
    color:
    颜色;
    size:
    尺寸;
    thickness
    :线粗

    细。

    ④if color.pixels_max < blobs.pixels():

       这个就是判断,判断是否找到面积最大的色块

    其实就是一系列赋值而已

    color.pixels_max = blobs.pixels()      # 将面积最大的色块的像素值赋值给color

    color.cx = blobs.cx()     # 将面积最大的色块的 x轴 中心坐标值 赋值给 color
    color.cy = blobs.cy()
    color.w = blobs.w()    #将面积最大的色块的宽度赋值给color
    color.h = blobs.h()
    color.flag = 1     # 标志画面中有找到色块
    color.density = blobs.density()   # 将面积最大的色块的 色块密度比 赋值给 color

     姿态矫正

    其实就是在走普通直线过程中可能会走歪,然后纠正一下而已啦

    ps:我这里纠正靠的是,K210识别到歪了之后,然后串口发送数据给C8T6,然后C8T6收到对应的数据,从而控制车子向左向右偏!(由此可见串口通信的重要性) 

    def zi_tai_jiao_zheng():    #只用于循普通黑线中的姿态矫正
          opv_find_blobs(black,1)
          if black.flag == 1:               # 标记画面中被找到的最大色块的中心坐标
             if black.w<90:
                if black.cx>180:
                   if black.cy>160:
                      if black.cy<240:
                         if black.cx<215:
                            sending_data(1,1)
                            print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx<240:
                              sending_data(1,2)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx<260:
                              sending_data(1,3)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx<290:
                              sending_data(1,4)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx<320:
                              sending_data(1,5)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                         elif black.cx<345:
                              sending_data(1,6)
                              print("x=%d,y=%d"%(black.cx,black.cy))
                elif black.cx<180:
                       if black.cy>160:
                          if black.cy<240:
                             if black.cx>130:
                                sending_data(2,1)
                                print("x=%d,y=%d"%(black.cx,black.cy))
                             elif black.cx>110:
                                  sending_data(2,2)
                                  print("x=%d,y=%d"%(black.cx,black.cy))
                             elif black.cx>90:
                                  sending_data(2,3)
                                  print("x=%d,y=%d"%(black.cx,black.cy))
                             elif black.cx>70:
                                  sending_data(2,4)
                                  print("x=%d,y=%d"%(black.cx,black.cy))
                             elif black.cx>40:
                                  sending_data(2,5)
                                  print("x=%d,y=%d"%(black.cx,black.cy))
                             elif black.cx>15:
                                  sending_data(2,6)
                                  print("x=%d,y=%d"%(black.cx,black.cy))
    

    原谅本人才疏学浅,只想出通过判断中心坐标和色块宽度和高度来确定车子所处的方向,还有许许多多的办法,欢迎各位大佬指教

    ①opv_find_blobs(black,1)先调用色块寻找函数,并定义参数(为黑色)

    ② if black.flag == 1 判断是否为最大色块,实际上这样做的目的就是检测最大色块

    ③然后就是层层判断,先判断宽度再判断中心坐标,因为K210摄像头是有x轴,y轴。所以我们通过色块的中心坐标与摄像头中心坐标对比,来确定车身处于哪个方向

    其他:例如十字路口,左直角,右直角。同理!!!

    主函数

    必须有主函数

    # 主函数
    while(True):
        clock.tick()                                            # 跟踪运行时间
        img = sensor.snapshot()                                 # 拍摄一张照片
        opv_find_blobs(black,1)                             
        zi_tai_jiao_zheng()
        shi_zi()
        zuo_zhi_jiao()
        you_zhi_jiao()
        mei_you_hei_xian()
        lcd.display(img)
    

    这个就是把我上面写的这些函数放里面就行了,不停循环检测;

    这就是K210部分的全部内容,欢迎各位大佬指正!人非圣贤,孰能无过!

    后期有空再更新STM32部分的知识,谢谢大家的阅读

    物联沃分享整理
    物联沃-IOTWORD物联网 » K210视觉循迹与STM32串口通信实现智能车功能

    发表评论