目录:

  • 总体设计
    • 1.基础硬件DIY设计
      • 1)整体原理图
      • 2)PCB电路
    • 2.OpenMV简单识别程序设计 与 STM32控制程序设计
      • 1)OpenMV简单识别程序设计【microPython】
      • 2)STM32控制程序设计 【C语言】
        • ①对OpenMV发送的数据包进行解析
        • ②小车的简单PID控制
        • ③系统状态设定
    • 3.效果展示
      • 1)整体效果图
  • Github项目地址、设计下载

本帖相关分享资料整理【程序+原理图-手工PCB】,最后有下载链接

注:本文仅用于学习交流分享,[若有不妥之处,请指正,感谢]

关键词:【OpenMV】【颜色识别】【PID】【STM32】
最后面有程序与原理图PCB分享

用到的工具有

  • openMV IDE
  • Keil 5 编译器
  • Altium Designer

实现的小功能有:
①设别颜色小球,并自动追寻小球
②简单测试与颜色小球的粗略距离,并且在小球10cm处停车
③按键调节PID参数以及调节识别的颜色

总体设计

1.基础硬件DIY设计
2.openMV简单识别程序设计 与 单片机控制程序设计
3.效果展示

1.基础硬件DIY设计

电路硬件:
[MCU] STM32F103C8T6最小系统板
[稳压电源]【L7805】 7.2V稳压5.0V 【AMS1117-3.3】5.0V稳压3.3V
[外围电路] 按键、蜂鸣器、OLED、干簧管

1)整体原理图

2)PCB电路

2.OpenMV简单识别程序设计 与 STM32控制程序设计

1)OpenMV简单识别程序设计【microPython】


识别小球颜色并通过串口定时发送小球坐标与距离的数据包

#2018.8.2   【microPython】
import sensor, image, time , pyb
from pyb import UART
from pyb import Timer
from pyb import LED
import jsonled = pyb.LED(3) # Red LED = 1, Green LED = 2, Blue LED = 3, IR LEDs = 4.
thresholds = [(27, 67, 19, 91, 45, 76), # 红色#(21, 75, 3, -38, 34, 68), # 绿色(27, 90, -3, -28, 31, 125),(0, 30, 0, 64, -128, 0)]  # generic_blue_thresholds
threshold_index = 1 # 0 for red, 1 for gre9en, 2 for bluesensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)   #320*240
sensor.skip_frames(time = 100)
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)
uart.init(115200, bits=8, parity=None, stop=1, timeout_char=1000) # 使用给定参数初始化def tick(timer):            # we will receive the timer object when being calledglobal dataif blobs:print("Find")print('you send:',output_str)uart.write(data)tim = Timer(4, freq=10)      # create a timer object using timer 4 - trigger at 1Hz
tim.callback(tick)          # set the callback to our tick functiondef find_max(blobs):max_size=0for blob in blobs:if blob[2]*blob[3] > max_size:max_blob=blobmax_size = blob[2]*blob[3]return max_blobdef Uart_Receive():   #UART接收 改变框小球的颜色阈值global threshold_indexif uart.any():temp_data = uart.readchar()if temp_data==0:   #红色threshold_index=0print(temp_data,threshold_index)elif temp_data==1:threshold_index=1print(temp_data,threshold_index)while(True):clock.tick()img = sensor.snapshot()Uart_Receive()blobs = img.find_blobs([thresholds[threshold_index]])if blobs:max_blob = find_max(blobs)b = max_blob[0] #方框元组L = (max_blob[2]+max_blob[3])/2l=int(1000/L)#x_error = max_blob[5]-img.width()/2   #求横向偏差x_error = max_blob[5]-img.width()/2img.draw_rectangle(max_blob[0:4])        # 画矩形img.draw_cross(max_blob[5], max_blob[6]) # 画十字#发送 小球的(x,y,l,n)#x为横坐标,y为纵坐标,l为粗略的距离,n为小球颜色(0:红 1:绿)output_str="%d,%d,%d,%d" % (max_blob.cx(),max_blob.cy(),l,threshold_index) #10进制字符包checkout=0xAA+0x55+0x07+int(max_blob.cx()/2)+max_blob.cy()+l+threshold_indexdata = bytearray([0xAA,0x55,0x07,int(max_blob.cx()/2),max_blob.cy(),l,threshold_index,0x00,0x00,checkout])#转成16进制#uart.write(data)time.sleep(1)led.on()else:print("NO FIND")data = bytearray([0xAA,0x55,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x06])uart.write(data)led.off()
图3 抓取到绿色小球 图4 抓取到红色小球

2)STM32控制程序设计 【C语言】

①对OpenMV发送的数据包进行解析
void USART1_IRQHandler(void)                 //串口1中断服务程序
{uint8 i=0,j=0;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  {//接收中断control_data[data_number]=USART_ReceiveData(USART1);data_number++; if(data_number<(MAX_DATA_LENS+4))                   {  //定义数据长度未包括包头和包长3个字节,+4if(control_data[0]==0xaa)//数据包包头字节{if(data_number>3){if(control_data[1]==0x55){ if(data_number>=(control_data[2]+3))  {//接收完数据包(第三个字节为数据长度,数据长度不包含开头和校验字)for(i=0;i<=(data_number-2);i++) {j +=control_data[i];}if(j==control_data[data_number-1]) //判断校验是否成功{j=0;recv1_data_ok=1;   //接收到正确完整数据包标志位置              }else{recv1_data_ok=0;}j=0;data_number=0;                                                   }}else{recv1_data_ok=0;data_number=0;}}}else{ recv1_data_ok=0;data_number=0;}}else{recv1_data_ok=0;data_number=0;}} }
②小车的简单PID控制
#include "my_include.h"extern CAR_STATUS_e car_mode;
extern moty_duty run_duty;
extern u8 control_data[MAX_DATA_LENS];
extern float C_P; //cameraP
extern float C_D; //cameraD
extern int16 ser_duty;
extern int16 x_error;
extern int16 last_x_error;
extern uint8 ball_colcor;
extern uint8 BEEP_ON_OFF;extern uint8 out_edge;//出界void Car_mode_control()//小车简单控制逻辑单元
{if(control_data[3]<50 && control_data[3]!=0) //左出界{out_edge=Left;}else if(control_data[3]>110 && control_data[3]!=0) //右出界{out_edge=Right;}//--------------------车位状态判断-----------------//if(out_edge==Left && control_data[4]==0 && control_data[5]==0){car_mode=finding_L;}else if(out_edge==Right && control_data[4]==0 && control_data[5]==0){car_mode=finding_R;}else if (control_data[3]>0 && control_data[4]>0 && control_data[5]>0){car_mode=run;}if(control_data[5]<=12 && control_data[5]>=3){LED1=0;car_mode=stop;}else {LED1=1;}if(Boma4==0)//强制菜单{car_mode=stop;}//寻找小球的 色号(0为红,1为绿) if(Boma3==0){BEEP_ON_OFF=OFF;}else {BEEP_ON_OFF=ON;}
}void PWM_updata()//速度控制中心
{if(car_mode == run){TIM_SetCompare1(TIM1,run_duty.Speed_Duty_R); //右为  TIM1  CH1TIM_SetCompare4(TIM1,run_duty.Speed_Duty_L);  //左为  TIM1  CH4}else if(car_mode == finding_R){TIM_SetCompare1(TIM1,1400);   //右为  TIM1  CH1TIM_SetCompare4(TIM1,1400); //左为  TIM1  CH4}else if(car_mode == finding_L){TIM_SetCompare1(TIM1,1500); //右为  TIM1  CH1TIM_SetCompare4(TIM1,1500); //左为  TIM1  CH4}else if(car_mode == stop){TIM_SetCompare1(TIM1,0); //右为  TIM1  CH1TIM_SetCompare4(TIM1,0);  //左为  TIM1  CH4}
}void PD_control()
{last_x_error=x_error;x_error=control_data[3]-80;ser_duty = C_P*x_error-C_D*(last_x_error-x_error);run_duty.Speed_Duty_R=1550-ser_duty;//正为正转run_duty.Speed_Duty_L=1350-ser_duty;//左边FTM波//限幅  run_duty.Speed_Duty_L=run_duty.Speed_Duty_L<1300?1300:run_duty.Speed_Duty_L;run_duty.Speed_Duty_L=run_duty.Speed_Duty_L>1600?1600:run_duty.Speed_Duty_L;//右边FTM波//限幅    run_duty.Speed_Duty_R=run_duty.Speed_Duty_L<1300?1300:run_duty.Speed_Duty_R;run_duty.Speed_Duty_R=run_duty.Speed_Duty_L>1600?1600:run_duty.Speed_Duty_R;}
③系统状态设定
typedef struct D  //速度结构体
{int16 Speed_Duty_L;int16 Speed_Duty_R;
}moty_duty;typedef enum   //枚举小车简单状态
{finding_R=4,finding_L=3,run=2,stop=1,error=0,
}
CAR_STATUS_e;  //车子状态 typedef enum
{mode_ON_OFF=0,car_run=1,flash=2,   picture=3,}
MENU_LIST_e; //OLED菜单

3.效果展示

    DESIGN
May 31 12:00 June 12:00 Tue 02 12:00 Wed 03 12:00 Thu 04 12:00 部分功能验证 原理图 PCB 程序设计 小车整体搭建 设计制作步骤

1)整体效果图

OLED页面设计
OELD可通过拨码开关切换页面

①在OLED上显示小球的实时坐标【x,y】以及距离 l
② 显示小球在摄像头中的坐标并在屏幕上用“x”表示出来

调试界面
预留五个调试按键

①可调节PD参数
②切换追踪小球颜色阈值

图1 小车整体效果图 图2 小车整体效果图

附【Download】:
程序+硬件(原理图+PCB):

Github项目地址、设计下载

Dwfish 淹死的鱼 2018.1

【DIY】基于OpenMV的STM32追球小车相关推荐

  1. 基于OpenMV和正点原子开发的自动追球小车(带云台舵机)

    电赛备赛前,通过OpenMV加舵机云平台由,做了一个追着球跑的小车,由于疫情,以前录制的视频也删除了,最终呈现的效果和B站一位Up主的相似,大家可以参考参考,链接如下:STM32 颜色识别 自动跟随小 ...

  2. 基于OpenMV的自动驾驶智能小车模拟系统

    一.项目简介 基于机器视觉模块OpenMV采集车道.红绿灯.交通标志等模拟路况信息,实现一辆能车道保持.红绿灯识别.交通标志识别.安全避障以及远程WiFi控制的多功能无人驾驶小车. 赛道规格: 1.编 ...

  3. 无人机寻迹要两个单片机吗_基于OpenMV的循迹无人机设计

    基于OpenMV的循迹无人机设计 发表时间:2020-08-24 基于OpenMV机器视觉模块进行目标识别算法的研究.利用图像的滤波.二值化等算法对摄像头采集的图像进行预处理;利用边缘检测和形状识别算 ...

  4. 最简单DIY基于STM32单片机的WIFI智能小车设计方案

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 第三篇:最简单DIY基于STM32F ...

  5. 最简单DIY基于STM32单片机的蓝牙智能小车设计方案

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 文章目录 STM32库函数开发系列文 ...

  6. 基于FPV体感头追的小车检测系统(1)—硬件介绍(2022海南省电子大学生电子设计竞赛一等奖)

    11月底,海南电赛终于结束了,比其他省的电赛晚一些,难度也相对简单一些,今年海南本科生电赛的模式也有了很大的变化,仿照电赛研究生的模式,题目自选,且有实物展示和PPT展示与答辩环节,说实话个人觉得相较 ...

  7. 最简单DIY基于STM32的远程控制电脑系统②(无线遥杆+按键控制)

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 第三篇:最简单DIY基于STM32F ...

  8. 最简单DIY基于STM32的远程控制电脑系统①(电容触摸+按键控制)

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 第三篇:最简单DIY基于STM32F ...

  9. 最简单DIY基于ESP8266的物联网智能小车①(webserver服务器网页简单遥控版)

    ESP8266和ESP32物联网智能小车开发系列文章目录 第一篇:最简单DIY基于ESP8266的物联网智能小车①(webserver服务器网页简单遥控版) 文章目录 ESP8266和ESP32物联网 ...

最新文章

  1. tomcat配置文件修改
  2. IT经理世界:专注莫如史玉柱
  3. Qt Creator用定位器搜索
  4. 提升心力---摆脱拿着锤子看啥都是钉子
  5. 简述java的线程_Java多线程的简述
  6. Iterator迭代器接口讲解
  7. Linux网络设置(第二版) --Linux网络设置
  8. mqtt c语言 单片机,MQTT--单片机实现即时通讯
  9. html5shiv主要解决IE6-8 无法识别HTML5的新标签,父节点不能包裹子元素,以及应用CSS样式...
  10. 二叉线索树的先序、中序、后序的线索化及其遍历
  11. [LuoguP1352][FJSC]没有上司的舞会
  12. Selenium Automated test 's Installation environment
  13. Boost组件lexical_cast
  14. AI上推荐 之 xDeepFM模型(显隐性高阶特征交互的组合策略)
  15. 元旦节前python网络编程趣味小游戏
  16. matlab入门(适合初学者)
  17. 进制转换表与课程内容
  18. 计算机无法安装hp网络打印机,hp打印机驱动安装失败怎么办 hp打印机驱动安装失败的解决办法...
  19. 云控系统搭建需要那个运行商网线
  20. linux skb机制,skb 的分配细节

热门文章

  1. 输入/输出(全称:Input Output)
  2. 【实用的开源项目】使用服务器部署memos,一款拥有社交功能的、好看的自托管备忘录
  3. 计算机取证磁盘镜像研究,计算机取证磁盘镜像研究与虚拟仿真实现
  4. 语音识别(ASR)论文优选:Tied Reduced RNN-T Decoder
  5. 平凡前端之路_03.HTML5的音频视频多媒体
  6. 中国移动设备用户体验调研报告
  7. 华为mate7刷机经历
  8. 西安建筑科技大学的计算机专业怎么样,西安建筑科技大学-XAUAT
  9. 手机号码段:中国工信.三大运营商号段-update2019-09
  10. 论文阅读:EfficientDet:可扩展且高效的目标检测