什么是避障小车

用红外光电传感器,探测到物体即输出脉冲,输入到单片机中处 理一下,再对电机驱动模块进行控制,实现壁障的功能,这样的避障小车又称为简单的避障机器人。

各种避障方法:
1、红外线避障 2、超声波避障

红外避障原理

基本硬件 红外发射管和接收管:分离式和一体式

变送电路:模拟量;数字量:将模拟量经过比较器输出开关量

选择模块简介:


不怕光HJ-IR2传感器 • 1、HJ-IR2相当于一个红外电子开关,检测到障碍输出低电平,平 时高电平。。 • 2、前方有障碍物时,红外管发出的红外信号经红外接收管接收 回来后,经集成的芯片放大,比较后,输出一低电平,点亮模块 上的LED发光管,同时可以输出一个低平信号,信号可以作为单 片机的信号输入检测控制外部各种驱动模块之用。 • 3、模块三线制,VCC为电原+5V,OUT为信号输出端,GND接电源 负极。 • 4、探测距离大概为1~30CM(探测距离的长短和供电电压、电流还 有周围环境有关,这里只作为参考) • 5、工作电压5V 工作电流 18-30ma左右。

2路壁障模块的输出 :

在一般电子设计比赛等对壁障模块功能要求不高的场合,完全可 以采用比较器输出开关量,这样编程简单,易于实现; 1路壁障模块模块则输出1路开关量,可以接单片机的普通输入IO 口;

2路壁障模块原理 :

根据小车的运行情况有以下几种运动方式:
若没有被任何一个探头检测到,小车直行; 左边探头检测到物体时小车向右转 ; 右这探头检测到物体时小车向左转 •;上述算法描述是最简单的红外壁障算法,如果有一定的速度需求, 则在以上算法上进行改进。

壁障模块的安装调试步骤 :

将2路探头呈一行布置在智能车前方,探头朝前面, 可以采用铜柱+螺丝方式固定; 将中控板固定在车身上; 正确连接中控板和探头的杜邦线; 正确连接控制主板; 将小车放到地面上,前方10CM处放物体,调节电位器, 保证某探头在经过物体时,LED的状态不同。 若无论怎么调节电位器,LED状态都不变化,则应该 是杜邦线接触不好,要更换。

简单源码分析—IO口定义

简单源码分析—算法分析

主程序:


#include "stm32f10x.h"
#include "interface.h"
#include "LCD1602.h"
#include "IRCtrol.h"
#include "motor.h"
#include "UltrasonicCtrol.h"
#include "redvoid.h"//全局变量定义
unsigned int speed_count=0;//占空比计数器 50次一周期
char front_left_speed_duty=SPEED_DUTY;
char front_right_speed_duty=SPEED_DUTY;
char behind_left_speed_duty=SPEED_DUTY;
char behind_right_speed_duty=SPEED_DUTY;unsigned char tick_5ms = 0;//5ms计数器,作为主函数的基本周期
unsigned char tick_1ms = 0;//1ms计数器,作为电机的基本计数器
unsigned char tick_200ms = 0;//刷新显示char ctrl_comm = COMM_STOP;//控制指令
char ctrl_comm_last = COMM_STOP;//上一次的指令
unsigned char continue_time=0;int main(void)
{delay_init();GPIOCLKInit();UserLEDInit();
//  LCD1602Init();
//  IRCtrolInit();TIM2_Init();MotorInit();//UltraSoundInit();RedRayInit();ServoInit();while(1){  if(tick_5ms >= 5){tick_5ms = 0;tick_200ms++;if(tick_200ms >= 40){tick_200ms = 0;LEDToggle(LED_PIN);}VoidRun();}}
}

串口部分:

#include "uart.h"
#include "interface.h"//UART function
//UART1 TxD GPIOA9   RxD GPIOA10
void USART1Conf(u32 baudRate)
{USART_InitTypeDef USART_InitSturct;//定义串口1的初始化结构体GPIO_InitTypeDef GPIO_InitStruct;//定义串口对应管脚的结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA , ENABLE);//打开串口管脚时钟//USART1_Tx_Pin Configure GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//输出引脚GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;//设置最高速度50MHzGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//推挽复用输出GPIO_Init(GPIOA , &GPIO_InitStruct);//将初始化好的结构体装入寄存器//USART1_Rx_Pin ConfigureGPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO模式悬浮输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;//输入引脚GPIO_Init(GPIOA, &GPIO_InitStruct);//将初始化好的结构体装入寄存器//USART1 Configure RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);//时钟使能USART_InitSturct.USART_BaudRate = baudRate;//波特率19200USART_InitSturct.USART_WordLength = USART_WordLength_8b;//数据宽度8位USART_InitSturct.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitSturct.USART_Parity = USART_Parity_No;//无奇偶校验USART_InitSturct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitSturct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//使能发送与接收USART_Init(USART1 , &USART_InitSturct);//将初始化好的结构体装入寄存器   //USART1_INT ConfigureUSART_ITConfig(USART1 , USART_IT_RXNE , ENABLE);//使能接收中断
//  USART_ITConfig(USART1 , USART_IT_TXE , ENABLE);USART_Cmd(USART1 , ENABLE);//打开串口USART_ClearFlag(USART1 , USART_FLAG_TC);//解决第一个数据发送失败的问题
}void PutChar(u8 Data)
{USART_SendData(USART1 , Data);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等待发送完毕
}
void PutStr(char *str)//发送一个字符串
{while(*str != '\0'){USART_SendData(USART1 , *str++);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等待发送完毕}
}void PutNChar(u8 *buf , u16 size)
{u8 i;while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); //防止第一字节丢失for(i=0;i<size;i++){USART_SendData(USART1 , buf[i]);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等待发送完毕}
}

电机模块:

#include "motor.h"
#include "interface.h"
#include "stm32f10x.h"//GPIO配置函数
void MotorGPIO_Configuration(void)
{       GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = FRONT_LEFT_F_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_Init(FRONT_LEFT_F_GPIO, &GPIO_InitStructure);    GPIO_InitStructure.GPIO_Pin = FRONT_LEFT_B_PIN;  GPIO_Init(FRONT_LEFT_B_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = FRONT_RIGHT_F_PIN;    GPIO_Init(FRONT_RIGHT_F_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = FRONT_RIGHT_B_PIN;   GPIO_Init(FRONT_RIGHT_B_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BEHIND_LEFT_F_PIN;   GPIO_Init(BEHIND_LEFT_F_GPIO, &GPIO_InitStructure);  GPIO_InitStructure.GPIO_Pin = BEHIND_LEFT_B_PIN;  GPIO_Init(BEHIND_LEFT_B_GPIO, &GPIO_InitStructure);  GPIO_InitStructure.GPIO_Pin = BEHIND_RIGHT_F_PIN; GPIO_Init(BEHIND_RIGHT_F_GPIO, &GPIO_InitStructure);  GPIO_InitStructure.GPIO_Pin = BEHIND_RIGHT_B_PIN;    GPIO_Init(BEHIND_RIGHT_B_GPIO, &GPIO_InitStructure);  }//根据占空比驱动电机转动
void CarMove(void)
{   BEHIND_RIGHT_EN;/* //左前轮if(front_left_speed_duty > 0)//向前{if(speed_count < front_left_speed_duty){FRONT_LEFT_GO;}else{FRONT_LEFT_STOP;}}else if(front_left_speed_duty < 0)//向后{if(speed_count < (-1)*front_left_speed_duty){FRONT_LEFT_BACK;}else{FRONT_LEFT_STOP;}}else                //停止{FRONT_LEFT_STOP;}*///右前轮if(front_right_speed_duty > 0)//向前{if(speed_count < front_right_speed_duty){FRONT_RIGHT_GO;}else                //停止{FRONT_RIGHT_STOP;}}else if(front_right_speed_duty < 0)//向后{if(speed_count < (-1)*front_right_speed_duty){FRONT_RIGHT_BACK;}else                //停止{FRONT_RIGHT_STOP;}}else                //停止{FRONT_RIGHT_STOP;}//左后轮if(behind_left_speed_duty > 0)//向前{if(speed_count < behind_left_speed_duty){BEHIND_LEFT_GO;} else                //停止{BEHIND_LEFT_STOP;}}else if(behind_left_speed_duty < 0)//向后{if(speed_count < (-1)*behind_left_speed_duty){BEHIND_LEFT_BACK;}  else                //停止{BEHIND_LEFT_STOP;}}else                //停止{BEHIND_LEFT_STOP;}/*       //右后轮if(behind_right_speed_duty > 0)//向前{if(speed_count < behind_right_speed_duty){BEHIND_RIGHT_GO;}  else                //停止{BEHIND_RIGHT_STOP;}}else if(behind_right_speed_duty < 0)//向后{if(speed_count < (-1)*behind_right_speed_duty){BEHIND_RIGHT_BACK;}  else                //停止{BEHIND_RIGHT_STOP;}}else                //停止{BEHIND_RIGHT_STOP;}*/
}//向前
void CarGo(void)
{front_left_speed_duty=SPEED_DUTY;front_right_speed_duty=SPEED_DUTY;behind_left_speed_duty=SPEED_DUTY;behind_right_speed_duty=SPEED_DUTY;
}//后退
void CarBack(void)
{front_left_speed_duty=-SPEED_DUTY;front_right_speed_duty=-SPEED_DUTY;behind_left_speed_duty=-SPEED_DUTY;behind_right_speed_duty=-SPEED_DUTY;
}//向左
void CarLeft(void)
{front_left_speed_duty=-20;front_right_speed_duty=SPEED_DUTY;behind_left_speed_duty=-20;behind_right_speed_duty=SPEED_DUTY+10;//增加后轮驱动力
}//向右
void CarRight(void)
{front_left_speed_duty=SPEED_DUTY;front_right_speed_duty=-20;behind_left_speed_duty=SPEED_DUTY+10;//增加后轮驱动力behind_right_speed_duty=-20;
}//停止
void CarStop(void)
{front_left_speed_duty=0;front_right_speed_duty=0;behind_left_speed_duty=0;behind_right_speed_duty=0;
}void MotorInit(void)
{MotorGPIO_Configuration();CarStop();
}

红外遥控配置:

#include "IRCtrol.h"
#include "interface.h"unsigned char ir_rec_flag=0;//接收数据标志位 1 有新数据 0 没有
unsigned char IRCOM[4];//use time3 realize delay systick已经在main函数中使用了,在中断中不能重复使用
void Time3Init(void)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);TIM_TimeBaseStructure.TIM_Period = 1;TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1);//72M / 72 = 1usTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
}//1us 延时
void DelayUs(vu32 nCount)
{u16 TIMCounter = nCount;TIM_Cmd(TIM3, ENABLE);TIM_SetCounter(TIM3, TIMCounter);while (TIMCounter>1){TIMCounter = TIM_GetCounter(TIM3);}TIM_Cmd(TIM3, DISABLE);
}//外部中断配置 红外遥控配置
void IRCtrolInit(void)
{GPIO_InitTypeDef  GPIO_InitStructure;EXTI_InitTypeDef  EXTI_InitStructure;//定义一个外部中断相关的结构体NVIC_InitTypeDef NVIC_InitStructure; //定义一个中断的结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);GPIO_InitStructure.GPIO_Pin = IRIN_PIN;//配置使能GPIO管脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//配置GPIO模式,输入上拉GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//配置GPIO端口速度GPIO_Init(IRIN_GPIO , &GPIO_InitStructure);GPIO_EXTILineConfig(IRIN_PORTSOURCE , IRIN_PINSOURCE);EXTI_InitStructure.EXTI_Line = IRIN_EXITLINE;//将对应的GPIO口连接到中断线上EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//中断事件类型,下降沿EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择模式,中断型EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能该中断EXTI_Init(&EXTI_InitStructure);//将配置好的参数写入寄存器NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);   //阶级为0,不可嵌套NVIC_InitStructure.NVIC_IRQChannel =    IRIN_IRQCH;//打开PINA_8的外部中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//主优先级0,最高NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    //子优先级,最低NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    //使能该模块中断NVIC_Init(&NVIC_InitStructure);    //中断初始化,将结构体定义的数据执行Time3Init();
}/*******************************************************************************
* 函 数 名 :DelayIr
* 函数功能 :0.14MS 延时
* 输    入 :无
* 输    出 :无
*******************************************************************************/
void DelayIr(unsigned char x)
{while(x--){DelayUs(140);}
}void IRIntIsr(void)
{unsigned char j,k,N=0;DelayIr(15);if (IRIN==1) { return;} continue_time = 40;//连发信号,表示指令持续 40*5 = 200ms 无指令停车//确认IR信号出现while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。{DelayIr(1);}for (j=0;j<4;j++)         //收集四组数据{ for (k=0;k<8;k++)        //每组数据有8位{while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。{DelayIr(1);}while (!IRIN)          //等 IR 变为高电平{DelayIr(1);}while (IRIN)           //计算IR高电平时长{DelayIr(1);N++;           if (N>=30){ return;}                  //0.14ms计数过长自动离开。}                        //高电平计数完毕                IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”N=0;}//end for k}//end for jk = ~IRCOM[3];if (IRCOM[2] != k){ return; }//指令转换switch(IRCOM[2]){case 0x46: ctrl_comm = COMM_UP;break;case 0x15: ctrl_comm = COMM_DOWN;break;case 0x44: ctrl_comm = COMM_LEFT;break;case 0x43: ctrl_comm = COMM_RIGHT;break;case 0x40: ctrl_comm = COMM_STOP;break;default :  return;}ir_rec_flag = 1;}

红外避障模块:

#include "redvoid.h"
#include "interface.h"
#include "motor.h"extern char ctrl_comm;//获取红外避障模块状态
char GetVoidStatus(void)
{char left=0,right=0;char count;if(VOID_L_IO == BARRIER_Y){count = 2;while(--count)//10ms 采集2次均要采集到前面障碍物信息,滤波{if(VOID_L_IO == BARRIER_N)break;Delayms(1);}if(count == 0) left = 1;}if(VOID_R_IO == BARRIER_Y){count = 2;while(--count)//10ms 采集2次均要采集到前面障碍物信息,滤波{if(VOID_R_IO == BARRIER_N)break;Delayms(1);}if(count == 0) right = 2;}return left + right;
}//延时的同时检测红外,一旦发生障碍物,就停止并跳出延时
void DelayCheck(int ms)
{while(ms--){Delayms(1);if(VOID_NONE != GetVoidStatus()){CarStop();return;}}
}//红外避障处理
//处理方式:左边检测到  后退500ms 右转500ms
//          右边检测到  后退500ms 左转500ms
//          两边检测到  后退700ms 右转500ms
//          没检测到    直行
void VoidRun(void)
{char status;status = GetVoidStatus();switch(status){case VOID_LEFT: ctrl_comm = COMM_RIGHT;CarBack(); Delayms(500); CarRight(); DelayCheck(500);break;case VOID_RIGHT:ctrl_comm = COMM_LEFT;CarBack(); Delayms(500); CarLeft(); DelayCheck(500);    break;case VOID_BOTH:ctrl_comm = COMM_RIGHT;CarBack(); Delayms(700); CarRight(); DelayCheck(500);break;case VOID_NONE:ctrl_comm = COMM_UP;CarGo();break;default: break;}
}

基于STM32红外避障小车的设计(有代码)相关推荐

  1. stm32捕获占空比_基于STM32超声波避障小车

    不管是对于初学者还是对于一个玩过单片机的电子爱好者来说,或多或少都接触到过小车项目,今天给大家介绍的的一个项目基于STM32超声波避障小车.这也是我曾经的一个课设,在此开源分享给大家,全文5000多字 ...

  2. 51单片机小车的立项书_毕业论文:基于51单片机智能避障小车的设计报告(范文1)...

    <毕业论文:基于51单片机智能避障小车的设计报告.doc>由会员分享,可免费在线阅读全文,更多与<毕业论文:基于51单片机智能避障小车的设计报告>相关文档资源请在帮帮文库(ww ...

  3. 避障小车的原理和代码实现

    目录 一.避障小车原理 二.代码实现 三.避障小车图片演示 一.避障小车原理 红外避障模块分析 跟随小车的原理 左边跟随模块能返回红外,输出低电平,右边不能返回,输出高电平,说明物体在左边,需要左转 ...

  4. 避障跟随测距c语言程序,红外避障小车c语言程序.pdf

    智能小车红外避障智能小车红外避障 c 语言程序语言程序 #include bit RandomFactor = 0 ; bit RandomFactorBuf = 0 ; #include #defi ...

  5. 智能避障小车学习笔记(基于Wemos的避障小车)

    智能避障小车 一.开发环境及硬件 ArduiNo平台 网盘地址:https://pan.baidu.com/s/1w3MHxkCUBOlbqKRxRhlwbQ 提取码:o6gk 硬件 WeMos D1 ...

  6. 树莓派红外避障小车python_基于树莓派的环保“捡垃圾”机器人小车(避障、摄像、红外、WIFI)...

    项目:基于树莓派的环保"捡垃圾"机器人小车控制平台 功能:避障.锁定某个障碍物 概述: 目前这个控制平台能够识别是"垃圾"只是塑料瓶,核心是利用Arduino控 ...

  7. stm32 智能避障小车(二)之sg90

    这一篇我要先写sg90这篇,因为比hsr04简单.总体的介绍思路是:实物讲解.模块原理.代码详解 1.实物讲解 首先我们先来看sg90的样子: 然后再看看它的接线,买过来的sg90舵机模块引出来了三根 ...

  8. 探索者Arduino模拟红外避障小车

    Arduino教程传送门

  9. 基于STM32三路超声波避障小车

    基于STM32的避障小车 最近几天的学习了STM32输入捕获输入捕获的相关知识,为了巩固自己学习的知识特意制作一辆有三个超声波组成的4轮避障小车来加深对输入捕获的理解. 1.输入捕获简介 输入捕获模式 ...

最新文章

  1. 三、Oracle的简单查询
  2. Linux设置SSH登录(SecureCrt)
  3. Windows2003 SQL2005解决系统Administrator密码不知道的问题
  4. python中difflib_python中的difflib
  5. 剑网服务器维护,12月31日服务器例行维护公告
  6. (转)使用IDEA将普通MAVEN项目转为WEB项目
  7. boost_1.47在VS2010下的安装
  8. 虚拟机安装spark配置推荐
  9. 用卷积神经网络识别实际田间条件下茶叶病虫害(自然环境下拍摄的数据集不用太多预处理)
  10. JavaScript使用button提交表单
  11. 2014.12.03 页面控件
  12. iOS:Autolayout自动布局实例
  13. 5款瞬间复活Win7/8/10工具
  14. JAVA调用IBM的Lotus Notes
  15. 【任务二】打卡——by 003-Vamein
  16. MIUI9系统详细刷成开发版启用root权限的教程
  17. arcgis 线段合并
  18. [渝粤教育] 西南科技大学 经济型数控系统设计 在线考试复习资料
  19. Python matplotlib 批量绘图内存不够问题(Out of memory)
  20. 趣图:谁说理工男都穿格子衫?

热门文章

  1. Git 常用命令大全1
  2. 苹果手机突然黑屏_手机突然黑屏该怎么办?别慌张,你可以这样解决!
  3. Http Trunk
  4. 【HDR】曝光融合(Exposure Fusion)
  5. vue跳转外链页面以及跳转html页面超简单方法
  6. 一篇关于电机的深度学习故障预测综述
  7. 为什么员工激励总达不到预期的效果?
  8. 2020-07-23 哪些情况,会导致过不了背景调查那一关?
  9. 商行不良贷款连续四季度双降
  10. JAVA23种设计模式(2)-结构型模式7种