栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

openmv追踪颜色小车

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

openmv追踪颜色小车

目录​​​​​​​

目录

一、预想功能

二、系统框架

 三、硬件介绍

四、软件介绍

openmv程序

沁恒CH32V103最小系统

串口接收函数

 pwm初始化

小车位置判断和控制

五、实际效果

学习引用文章:


一、预想功能

制作基于沁恒CH32V103最小系统和openmv的颜色追踪小车,他可以识别到所需要的颜色进而追踪所需颜色。

二、系统框架

 三、硬件介绍

openmv:由openmv识别所需的色块,并且把所识别的色块中心xy坐标以数据包的形式发送给沁恒CH32V103最小系统。

沁恒CH32V103最小系统:接收openmv所发送过来的数据包,经过对xy坐标的判断和计算去通过pwm控制电机。

l298n:电机驱动模块,接收沁恒CH32V103最小系统的pwm来控制两边的两个电机。

四、软件介绍

openmv程序
import sensor, image, time, math
from pyb import UART
import json
import ustruct


blue_threshold   = (25, 67, -37, 26, -63, -26)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()

uart = UART(3,115200)   #定义串口3变量
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters

def find_max(blobs):    #定义寻找色块面积最大的函数
    max_size=0
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob=blob
            max_size = blob.pixels()
    return max_blob

def sending_data(cx,cy):
    global uart;
    #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
    #data = bytearray(frame)
    data = ustruct.pack(" 

沁恒CH32V103最小系统

串口接收函数
#include "Uart.H"
#include "Motor.H"

//u8 x_coordinate;
u8 data_Correctness;
u16 openmv_data[7];
u8 number=0;

void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

//========================================================================
// 函数: void USARTx_CFG(void)
// 描述: 串口初始化函数
// 参数: 无
// 返回: 无
// 版本:
// 日期:
// 备注:USART2 TX-->A.2   RX-->A.3
//========================================================================
void USARTx_CFG(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能串口2时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟

  USART_DeInit(USART2);

  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;              //设置PA2为复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //设置PA3为浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 115200;                 //设置串口波特率为115200
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;  //字长为8位数据格式
  USART_InitStructure.USART_StopBits = USART_StopBits_1;       //1个停止位
  USART_InitStructure.USART_Parity = USART_Parity_No;          //无奇偶校验位
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流控制
  USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送和接收模式
  USART_Init(USART2, &USART_InitStructure);                    //初始化串口

  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;      //抢占优先级为1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;           //子优先级为1
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //IRQ通道使能
  NVIC_Init(&NVIC_InitStructure);                              //中断优先级初始化

  USART_Cmd(USART2, ENABLE);                                   //使能串口
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);               //开启中断
}

//========================================================================
// 函数: void USART2_IRQHandler(void)
// 描述: 串口2中断函数
// 参数: 无
// 返回: 无
// 版本:
// 日期:
// 备注:接收openmv传来的数据
//========================================================================

void USART2_IRQHandler(void)
{
    u8 temp;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //中断产生
    {
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);    //清除中断标志
        temp = USART_ReceiveData(USART2);               //接收数据
        Openmv_Receive_Data(temp);
    }

}




void Openmv_Receive_Data(u16 data)//接收Openmv传过来的数据
{
    static u8 state = 0;
    if(state==0&&data==0x2C)
    {
        state=1;
        openmv_data[number++]=data;
    }
    else if(state==1&&data==18)
    {
        state=2;
        openmv_data[number++]=data;
    }
    else if(state==2)
    {
        openmv_data[number++]=data;
        if(number>19||data == 0x5B) state=3;    //the last of char is openmv[19]
    }
    else if(state==3)       //state == 3  检测是否接受到结束标志
    {
            if(openmv_data[number-1] == 0x5B)
            {
                state = 0;
                data_Correctness = 1;
                USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);
            }
            else   //wrong thing
            {
                state = 0;
                number=0;
            }
    }
    else    //wrong thing
    {
        state = 0;
        number=0;
    }
}


void USART2_Rx_Task(void)
{
    u16  posX,posY;
    if(data_Correctness == 1)
    {

        posX = openmv_data[3]<<8 | openmv_data[2];
        posY = openmv_data[5]<<8 | openmv_data[4];
        data_Correctness = 0;
        number = 0;
        car_control(posX,posY);
        USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
    }
}






 pwm初始化
#include "pwm.h"
//========================================================================
// 函数: TIM1_PWMOut_Init( u16 arr, u16 psc, u16 ccp )
// 描述: pwm初始化函数
// 参数: arr 周期,psc 预分频器值,ccp 占空比
// 返回: 无
// 版本:
// 日期:
// 备注:
//========================================================================
void TIM1_PWMOut_Init( u16 arr, u16 psc, u16 ccp )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimebaseInitTypeDef TIM_TimebaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );//使能GPIOA外设时钟和TIM1时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;        //配置PA8引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //设置为复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置输出速度:50MHz
    GPIO_Init( GPIOA, &GPIO_InitStructure );         //GPIO初始化

    TIM_TimebaseInitStructure.TIM_Period = arr;      //指定下次更新事件时要加载到活动自动重新加载寄存器中的周期值。
    TIM_TimebaseInitStructure.TIM_Prescaler = psc;   //指定用于划分TIM时钟的预分频器值。
    TIM_TimebaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;    //时钟分频因子
    TIM_TimebaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM计数模式,向上计数模式
    TIM_TimebaseInit( TIM1, &TIM_TimebaseInitStructure); //根据指定的参数初始化TIMx的时间基数单位

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;            //指定TIM模式
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//指定TIM输出比较状态,即使能比较输出
    TIM_OCInitStructure.TIM_Pulse = ccp;                         //指定要加载到捕获比较寄存器中的脉冲值。
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    //指定输出极性。
    TIM_OC1Init( TIM1, &TIM_OCInitStructure ); //根据TIM_OCInitStruct中指定的参数初始化TIM1 Channel1。
    TIM_OC2Init( TIM1, &TIM_OCInitStructure );

    TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );         //使能CCR1上的TIM1外设预加载寄存器
    TIM_OC2PreloadConfig( TIM1, TIM_OCPreload_Disable );

    TIM_CtrlPWMOutputs(TIM1, ENABLE );                  //启用定时器1PWM输出
    TIM_ARRPreloadConfig( TIM1, ENABLE );               //使能ARR上TIM1外设预加载寄存器
    TIM_Cmd( TIM1, ENABLE );                            //使能TIM1
}

小车位置判断和控制
#include "Motor.H"


u8 motor;
u8 left = 0;
u8 right = 1;
u8 run = 2;




void car_control(u16 x_coordinate,u16 y_coordinate)
{
    if(x_coordinate < 50 && x_coordinate != 0)
    {
        motor = left;
    }
    else if (x_coordinate >= 200 && x_coordinate != 0)
    {
        motor = right;
    }
    else if (x_coordinate > 50 && x_coordinate < 200 && y_coordinate >0)
    {
        motor = run;
    }




    switch(motor)
    {
    case 0:TIM_SetCompare1(TIM1,400);
           TIM_SetCompare2(TIM1,100);
           break;
    case 1:TIM_SetCompare1(TIM1,100);
           TIM_SetCompare2(TIM1,400);
           break;
    case 2:TIM_SetCompare1(TIM1,x_coordinate/2-y_coordinate/4);
           TIM_SetCompare2(TIM1,x_coordinate/2+y_coordinate/4);
           break;

    }
}








五、实际效果

openmv追踪小车

学习引用文章:

(4条消息) 使用openMV3与stm32进行通讯_qq_43243338的博客-CSDN博客_openmv与stm32通信

(4条消息) 【DIY】基于OpenMV的STM32追球小车_淹死的鱼-CSDN博客_openmv stm32

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/283120.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号