参赛经历——2020年TI杯辽宁省大学生电子设计竞赛

文章目录
  1. 1. 前言
  2. 2. 题目要求
  3. 3. 硬件与软件准备
    1. 3.1. STM32单片机
    2. 3.2. OPENMV视觉模块
    3. 3.3. USART HMI串口屏
    4. 3.4. 激光测距模块
    5. 3.5. 二维云台
    6. 3.6. 蜂鸣器/LED指示灯
  4. 4. 硬件设计
    1. 4.1. 稳压电路
    2. 4.2. 电路接线图
    3. 4.3. 系统实物图
    4. 4.4. STM32F103ZET6与其他器件的连接
  5. 5. 软件设计
    1. 5.1. STM32程序总流程图
    2. 5.2. OPENMV视觉模块
      1. 5.2.1. OPENMV程序总流程图
      2. 5.2.2. 非接触式物体尺寸测量原理
      3. 5.2.3. 形状识别原理
    3. 5.3. USART HMI串口屏
    4. 5.4. 激光测距模块
    5. 5.5. 二维云台
    6. 5.6. 蜂鸣器/LED指示灯
  6. 6. 后续与总结

前言

2020年10月10日至10月13日,我与人组队参加了TI杯辽宁省大学生电子设计竞赛,所选题目为G题——非接触物体尺寸形态测量。在这次竞赛中我主要负责程序相关工作,其中涉及到STM32单片机、OPENMV图像识别模块、激光测距模块、串口屏上位机开发等诸多方面的知识,积累了相当多的经验。经过一个月的前期准备与四天三夜的刻苦奋斗,最终取得了省二等奖的优异成绩。
整理这个笔记,也是对竞赛做一个全面回顾,总结竞赛过程中遇到的困难与解决问题的方法,列举相关参考资料,为今后的读研与工作提供一些参考。

题目要求

设计并制作一个非接触式物体形状和尺寸自动测量装置,测量被测目标的形状尺寸、 测量头中心点与被测目标之间的距离等参数,并用激光束指示出被测目标的中心位置。
图1 题目要求

硬件与软件准备

STM32单片机

STM32是高性能,低成本,低功耗的嵌入式微控制器。本次竞赛采用的STM32F103ZET6型号单片机,作为整个测量系统的控制中心使用,实现程序的整体流程控制,对二维云台的舵机PWM控制,以及与OPENMV图像识别模块、激光测距模块、串口屏的信息交换处理。
所用IDE为Keil μVision V5.21.1.0
STM32的学习资料可以在此下载 正点原子资料下载中心

OPENMV视觉模块

OpenMV是一款低价,可扩展的机器视觉模块。本次竞赛采用OPENMV2-M3摄像头,该模块采用STM32F427VG微处理器与OV7725感光元件。可以通过编写简单的Python语言脚本,实现数据采集和图像处理。在本次竞赛中用于识别区域内色块,进行相应处理实现形状识别功能。
OPENMV参考资料: OPENMV中文入门教程 OpenMV Cam快速参考
使用与之配套的OPENMV IDE进行程序开发。

USART HMI串口屏

USART HMI串口屏是一款编程简单,易于调试的可触摸显示模块。可以通过图形化软件快速制作显示界面。在本次竞赛中用于显示测距与形状识别结果信息,同时为形状识别提供测量启动按键。本次竞赛使用中景园2.8寸TFT LCD串口屏。
USART HMI参考资料: USART HMI入门教程
使用与之配套的USART HMI IDE进行程序开发。

激光测距模块

本次竞赛采用摩天MyAntenn-L1型号激光测距模块。与超声波测距模块相比,激光测距模块可以更为灵敏,精确度高,且可以满足用激光束指示出被测目标的中心位置之要求。

二维云台

二维云台有两个自由度,通过控制两个舵机的角度即可实现任意对任意方向的瞄准。本次竞赛将OPENMV视觉模块与激光测距模块安装在二维云台上,通过回传的图像确定下一时刻舵机的移动方向,做一个简单的闭环控制,最后使激光测距模块指向待测图形的中心。

蜂鸣器/LED指示灯

作为单片机启动,串口屏按键以及测量结束的提示信号。

硬件设计

稳压电路

采用LM2596S-ADJ来实现12V到6.5V(云台供电)的稳压和5V的稳压。LM2596S-ADJ是德州仪器(TI)生产的3A电流输出降压开关型集成稳压芯片,它内含固定频率振荡器(150KHZ)和基准稳压器(1.23v),并具有完善的保护电路、电流限制、热关断电路等功能,使它的性能很稳定。利用该器件只需极少的外围器件便可构成高效稳压电路。所以,LM2596S-ADJ稳压芯片十分适合系统的稳压电路设计。
图2 稳压电路

电路接线图

图3 电路接线图

系统实物图

图4 系统实物图

STM32F103ZET6与其他器件的连接

  • 串口屏—USART1—PA9(TX),PA10(RX)
  • 激光测距模块—USART2—PA2(TX),PA3(RX)
  • OPENMV视觉模块—USART3—PB10(TX),PB11(RX)
  • 舵机PWM—TIM3—PA6(CH1),PA7(CH2)
  • 蜂鸣器与指示灯—PE14,PE15

软件设计

STM32程序总流程图

图5 STM32程序总流程图

OPENMV视觉模块

OPENMV程序总流程图

图6 OPENMV程序总流程图

OPENMV程序总流程图如上图所示,测量分为“普通测量”与“追踪测量”两种。
普通测量模式下,激光测距模块已事先对准待测图形中心,可以直接调用OPENMV内置库函数识别特定色块,读取色块的各项信息,以此可以判断出待测图形的形状。将图形形状等信息以串口信号形式发送至单片机,结合单片机接收到的来自激光测距模块的距离信息。即可根据相似三角形原理计算出图形的尺寸(正方形或三角形的边长、圆的直径)。为提高测量精确度,这里采取了多次读取求平均值的方法。
追踪测量模式下,激光测距模块未对准待测图形中心,如果摄像头没有观察到待测图形色块,则向单片机发送“移动”信号,控制舵机按照设定好的方式来回运动(从左到右,从上到下,覆盖可能找到色块的所有方向);摄像头观察到色块后,向单片机发送“对准”信号,通过一个简单的闭环控制使激光测距模块对准色块中心(设定值为摄像头视野中心坐标,实际值为色块在摄像头视野中的坐标,被控量为两个舵机的PWM值)。完成对准后所执行程序同普通测量模式。

非接触式物体尺寸测量原理

图7 相似三角形法测量图形尺寸

本次竞赛的物体尺寸测量基于相似三角形原理,公式如下所示: \[\frac{L} {x} = \frac{ {L'} } {f}\] 首先进行一次测试以求出摄像头焦距\(f\),可以将某已知边长\(L\)的物体放置在摄像头前已知距离\(x\)的位置,使用测试程序测量像素点的长度\(L'\),便可用上式求出摄像头焦距\(f\),该值为固定值,一旦确定便不会改变。
普通测量或追踪测量模式下,通过来自激光测距模块的距离\(x\),与来自OpenMV摄像头模块的像素点长度\(L’\),以及固定的摄像头焦距\(f\),便可以求出待测物体的长度\(L\)

形状识别原理

图8 形状识别原理

本次竞赛待测形状有正方形、圆形与正三角形,如上图所示。
调用OPENMV摄像头模块的库函数img.find_blobs可以识别摄像头内所有符合要求的色块blobs。使用自定义的函数find_max(blobs)筛选出最大的色块max_blob,一般情况下是待测色块。
调用库函数img.draw_rectangle(max_blob.rect())可为待测色块绘制一个矩形将其包住,如上图所示。
可以获取到待测色块矩形的像素点长与宽,两者乘积即为矩形像素点面积\(S_{square}\)。此外还可以通过max_blob.pixels()得到色块像素点面积\(S_{blob}\)(即图中蓝色区域面积)。
设二者比值\(\frac{S_{blob}}{S_{square}} = k\),则可根据\(k\)值区分不同的形状,由上图可知正方形\(k = 1\),圆形\(k = \frac{\pi }{4} \approx 0.785\),正三角形\(k = 0.5\)
结合实际情况,当\(k \geqslant 0.9\)时,判断图形为正方形;当\(k \leqslant 0.6\)时,判断图形为三角形;其余情况为圆形。

USART HMI串口屏

图9 串口屏主界面

串口屏使用USART HMI配套IDE进行图形界面的编辑与程序烧录。本次竞赛所用串口屏主界面如上图所示。按下“普通测量”或“追踪测量”键后,串口屏将向STM32单片机发送不同的串口信号。STM32接到信号后向OPENMV视觉模块发送串口信号,蜂鸣器鸣响提示,OPENMV根据不同的信号按照图5所示程序流程进行测量。
至于立体测量,竞赛时间有限没做出来。

激光测距模块

STM32单片机与激光测距模块的通信通过单片机的串口USART2实现,设置波特率为38400。
根据摩天MyAntenn-L1型号激光测距模块参考手册,结合实际情况使用快速测距模式。
在STM32主函数写下代码printf("iFACM");便可启用快速测距模式。
注意这里需要对printf函数进行重定义,重定义代码位于usart.c文件下,具体如下:
(这里将原有例程中的USART1改成了USART2。这样才能用printf通过USART2发送字符串信号。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;

};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
USART2->DR = (u8) ch;
return ch;
}
#endif

USART2串口中断函数如下所示,通常串口接收到的数据以0x0d,0x0c结尾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void USART2_IRQHandler(void)                	//串口2中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断
{
Res = USART_ReceiveData(USART2); //读取接收到的数据
if(Res!=0x0d&&Res!=0x0a)
{
USART_RX_BUF2[USART_RX_STA2] = Res ;//USART_RX_BUF2
USART_RX_STA2++;
}
else
{
USART_RX_STA2 = 0;
Distance_cal();
}
}
}
激光测距模块距离处理函数如下:
1
2
3
4
5
6
7
8
9
10
11
void Distance_cal(void)//数据处理
{
if(USART_RX_BUF2[0]=='D'&&USART_RX_BUF2[3]=='.')
{
dis=(USART_RX_BUF2[2]-48)*1000+(USART_RX_BUF2[4]-48)*100+(USART_RX_BUF2[5]-48)*10+(USART_RX_BUF2[6]-48);
}
else if(USART_RX_BUF2[0]=='D'&&USART_RX_BUF2[4]=='.')
{
dis=(USART_RX_BUF2[2]-48)*10000+(USART_RX_BUF2[3]-48)*1000+(USART_RX_BUF2[5]-48)*100+(USART_RX_BUF2[6]-48)*10;
}
}
在快速测距模式下,数据格式为D=1.234m或D=12.34m。 注意串口输出的数字为'0'到'9'的ASCII码,需要减去'0'的ASCII码,即48。

二维云台

二维云台的两个舵机采用PWM控制,分别使用定时器TIM3的CH1与CH2通道。
TIM1为20ms的定时器中断,根据外部状态(识别色块过程中的二维云台“移动”或“对准”状态)每隔20ms对舵机PWM值进行更新。
通过来自OPENMV摄像头的信息判断二维云台的工作状态。摄像头未识别到色块时,二维云台处于“移动”状态,舵机按照设定好的方式来回运动,搜寻目标色块;摄像头识别到色块后,二维云台处于“对准”状态,通过一个简单的闭环控制使激光测距模块对准色块中心,以便接下来的测量。
二维云台移动对准色块效果

蜂鸣器/LED指示灯

使用TIM1定时器中断,根据外部状态(串口屏是否有按键按下,是否完成测量)每隔20ms对蜂鸣器与LED指示灯状态进行更新。

后续与总结

这次竞赛基本上发挥了自己本科阶段在单片机电子方面的全部实力,最后做出来的东西也实现了测距、判断物体形状与尺寸的基本功能。当然软件上还有一些bug,不过将将能用。
记得竞赛结束前大概两个小时,我一时手贱改了改程序还不备份,结果整个系统全不能用了,全都不好使了。当时心态彻底炸了,因为其实不改也行。还好使用Ctrl+Z大法把程序恢复到了修改前的状态,在竞赛结束前一小时一切恢复正常。这里特地感谢帮我稳住心态,提供安慰的队友。接下来仓促地写了写设计报告,随后封箱等待测评。
测评是在竞赛结束两周后,鬼知道这两周时间会发生什么,设备还好不好用。不过还好一切正常,最终拿了省二等奖(这次电赛我们学校成绩不咋好,二十五个队伍就拿了两个二等奖和三个三等奖)。
参加电赛的那个学期,基本上算是我大学阶段的高光时刻了,除了电赛还拿了其他几个比赛的奖,当然这里也有取舍,有一些比赛我就放弃了。随后就是下坡路了,考研一战寄了,二战将将考上本校,二战复试结束后暂时也没什么事,所以就搭建了这个博客。
既然已经到谷底了,就该触底反弹了,虽然接下来会遇到新的挑战,落入新的谷底,但是干就完了!任何时刻都不轻言放弃。