基于STM32单片机的OPENMV颜色识别小球追踪系统设计
- 0、毕业设计选题原则说明(重点)
- 1、项目简介
- 1.1、系统功能
- 1.2、演示视频
- 2、部分电路设计
- 2.1、STM32单片机核心板电路设计
- 2.2、openmv使用说明
- 2.3、stm32与openmv通信电路设计
- 2.4、OLED液晶显示电路设计
- 2.5、二维云台控制电路
- 3、单片机代码展示
- 3.1、系统初始化
- 3.2、控制舵机转动角度
- 4、Openmv识别程序设计
- 4.1、Openmv识别小球程序
0、毕业设计选题原则说明(重点)
- 选题之前,同学们要弄明白一件事情,做毕业设计是干什么用的!
- 这里我告诉大家,毕业设计对于你来说,不是让你去搞研究,掌握运用所学知识的,也不是让你去比谁做的毕业设计多么牛逼,多么厉害。
- 说白点,它的作用就是一个,让你顺利毕业,能够拿到学位证,毕业证而已!!!
- 当你明白这一点后,作毕业设计的要求就是在满足老师的要求后,越简单越好,这样不但容易去做,而且你自己也容易去理解,掌握,同样也能花最少的钱!!!
- 满足老师的要求,这个没办法,毕竟他是决定你是否能通过答辩的人。
- 每年都有很多同学找到我的时候,后悔当初为什么要把功能写的那么复杂,后悔没有提前找我咨询一下!所以在这里提醒同学们,提交开题报告之前一定要多想想,不要自己随便写一堆提交上去!!!
1、项目简介
- 系统构成:本设计由STM32单片机电路+Openmv图像识别电路+舵机控制电路+二位云台+电源电路组成。
1.1、系统功能
- 功能介绍:
- 本系统通过OpenMV作为是识别模块去识别被测物体,当其识别到红色小球后,判断小球中心点所在的区域信息,并将其区域标志位通过串口发送给STM32,当STM32接收到位置信息后对x轴、y轴的两个舵机参数进行操作,最后通过定时器输出合适的PWM波,控制舵机旋转相应的角度,使OpenMV摄像头对准被测物体,以实现物体追踪功能。
- 使用oled显示x轴、y轴的实时坐标
1.2、演示视频
2、部分电路设计
2.1、STM32单片机核心板电路设计
- 基于 ARM Cortex-M3内核的STM32F1系列单片机属于主流STM32单片机,其中增强型STM32F103子系列单片机的CPU 主频高达72MHz,片内Flash容量高达1MB,芯片引脚数量多达144个,有 QFN、LQFP、CSP、BGA 等多种芯片封装形式,并具有多种片内外设、USB接口和CAN 接口。根据STM32F103单片机片内Flash容量的不同,ST 公司将其分为小容量(16-32KB)、中等容量(64-128KB)、大容量(256KB-1MB)3种。
- 电源电路:为单片机提供稳定的工作电压,通常采用3.3V电源供电。电源电路的设计要保证单片机在不同工作条件下都能获得稳定的电压输出,以确保单片机的正常工作。
- 晶振电路:提供单片机工作所需的时钟信号。晶振电路通过晶振和电容组成,为单片机提供稳定的工作脉冲,确保单片机的定时和同步需求。
- 复位电路:实现单片机的复位功能,类似于电脑的重启。复位电路通过电容和电阻的配合,实现单片机在上电启动时的自动复位,以及通过手动按键实现复位功能,保证单片机在程序跑飞或异常情况下能够重新开始执行程序。
STM32单片机是一种功能强大、易于使用、灵活且可靠的32位微控制器,基于ARM Cortex™-M内核。其主要功能特点包括:
- 高性能和低功耗:STM32系列单片机提供多种内核选择,如Cortex-M0、Cortex-M3、Cortex-M4等,满足不同应用场景对性能的需求,同时保持低功耗特性。
- 多种通信和外设接口:STM32单片机具备广泛的通信和外设接口,如I2C、SPI、USART、USB等,便于开发者实现各种复杂功能。
- 易于开发和调试:STM32单片机提供了丰富的软件和硬件工具,如HAL库、CubeMX等,帮助开发者快速创建和调试嵌入式系统。
- 高集成度和设计灵活性:STM32系列单片机全系列产品共用大部分引脚、软件和外设,优异的兼容性为开发人员带来最大的设计灵活性
单片机最小系统原理图如下图所示:
实物图:
2.2、openmv使用说明
- OpenMV 摄像头是一款紧凑、低能耗、经济实惠的电路板,它使您能够轻松地执行机器视觉应用。您可以使用高级Python 脚本(准确来说是MicroPython),而无需使用C/C++。Python 的强大数据结构使您能够轻松处理复杂的机器视觉算法输出。此外,您仍然可以完全掌控OpenMV,方便地使用外部触发来拍摄照片或执行算法,并且还可以利用算法的结果来控制输入/输出引脚。
- OpenMV 是一个开源,低成本,功能强大的 机器视觉模块。OpenMV上的机器视觉算法包括 寻找色块、人脸检测、眼球跟踪、边缘检测、标志跟踪 等。以STM32F427CPU为核心,集成了OV7725摄像头芯片,在小巧的硬件模块上,用C语言高效地实现了核心机器视觉算法,提供Python编程接口。
openmv实物图如下:
2.3、stm32与openmv通信电路设计
- 本系统将stm32单片机id串口引脚与openmv的串口引脚连接,然后进行通信。
- 由于stm32单片机不需要给openmv发送数据,因此只需要将stm32单片机的串口接收引脚与openmv的串口发送引脚相连接即可。
其具体电路原理图如下图所示:
2.4、OLED液晶显示电路设计
IIC-OLED模块是一种高品质、高性能的显示屏,采用了有机发光二极管(OLED)技术,通过四个针脚控制电源和信号来实现对显示内容的控制。该模块具有以下特点:
- 高分辨率和色彩深度:该OLED模块具有高达128x32像素的分辨率和16位色彩深度,可以呈现出细腻、清晰的画面效果。
- 显示角度广泛:该模块具有178度的广角度,可以在各种角度下提供清晰的图像显示,同时也适用于不同的应用场景。
- 低功耗:OLED技术具有自发光特性,因此相比其他类型的显示屏,该模块具有更低的功耗,延长了电池寿命。
- 高可靠性:该模块采用了高品质的材料和工艺,严格把控生产流程,保证了产品的稳定性和可靠性,适用于各种环境下的使用。
- 简单易用:该模块通过四个针脚进行控制,接口简单,易于集成到各种设备中。
IIC总线的OLED模块是一种高品质、高性能的显示屏,具有广泛的应用前景。
- 电路设计
- OLED模块实物图:
- ng)
2.5、二维云台控制电路
- 使用两个舵机进行二维云台的控制,他们分别设置为x轴舵机、y轴舵机。
- 舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
电路原理图
实物图:
3、单片机代码展示
3.1、系统初始化
void DeviceInit(void)
{
rcc_init(); /* 时钟初始化 */
SysTick_Init(); /* 初始化系统嘀答定时器,1ms定时一次 */
servo_init(); /* 舵机初始化 */
TIM2_init(20000, 72 - 1); /* 初始化定时器2,用于pwm控制舵机 */
app_uart_init(); /* 初始化相关串口 */
//OLED设备初始化
OLED_Init();
OLED_Clear();
OLED_ShowString(0,0,(u8 *)"X Y",16); //打印坐标
interrupt_open(); /* 初始化总中断 */
}
3.2、控制舵机转动角度
void servo_set_offset(u8 index)
{
int aim_temp;
if (duoji_doing[index].inc != 0)
{
aim_temp = duoji_doing[index].aim;
if (aim_temp > 2490)
{
aim_temp = 2490;
}
else if (aim_temp < 500)
{
aim_temp = 500;
}
if (abs_float(aim_temp - duoji_doing[index].cur) <= abs_float(duoji_doing[index].inc + duoji_doing[index].inc))
{
duoji_doing[index].cur = aim_temp;
duoji_doing[index].inc = 0;
}
else
{
duoji_doing[index].cur += duoji_doing[index].inc;
}
}
}
4、Openmv识别程序设计
4.1、Openmv识别小球程序
for blob in blobs:#寻找最大
if blob[2] * blob[3] > max_size:
max_blob = blob
max_size = blob[2] * blob[3]
img.draw_rectangle((max_blob[0],max_blob[1],max_blob[2],max_blob[3]),color=(255,255,255))
img.draw_cross(max_blob[5], max_blob[6],size=2,color=(255,0,0))
img.draw_string(max_blob[0], (max_blob[1]-10), "red", color=(255,0,0))
print("中心X坐标",max_blob[5],"中心Y坐标",max_blob[6],"识别颜色类型","红色")
block_cx=max_blob[5]
block_cy=max_blob[6]