在智能车、机器人和自动化等领域避障技术是确保安全和高效运行的关键。红外避障模块作为一种常见的避障解决方案,因其非接触、响应速度快和抗干扰能力强等优点而备受青睐。本文将详细介绍红外避障模块的特点、工作原理、以及应用案例,帮助您更好地了解这一技术。
我们在之前的教程中还介绍了红外避障模块的“兄弟”——循迹模块,两者相似,大家可以一起看看【循迹模块连接】
本文首发 良许嵌入式网 :https://www.lxlinux.net/e/ ,欢迎关注!
本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):
https://www.lxlinux.net/e/stm32/ia-tutorial.html
如果你是嵌入式开发小白,那么建议你先读读下面几篇文章。
往期教程,有兴趣的小伙伴可以看看。
作者简介 |
---|
大家好,我是良许,博客里所有的文章皆为我的原创。 下面是我的一些个人介绍,欢迎交个朋友: · 211工科硕士,国家奖学金获得者; · 深耕嵌入式11年,前世界500强外企高级嵌入式工程师; · 书籍《速学Linux作者》,机械工业出版社专家委员会成员; · 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万; · 靠自媒体连续年入百万,靠自己买房买车。 |
我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:
电子书链接:https://www.lxlinux.net/1024.html
红外避障模块不断发射红外信号,当红外信号:
红外避障模块常见用途:
红外避障模块工作参数:
模块中蓝色的电位器用于调节灵敏度,顺时针旋转,灵敏度变高,检测距离变长;逆时针越小,灵敏度变低,检测距离变短。
上电后电源指示灯(绿灯)亮。
当红外反射回来,OUT 输出低电平,输出指示灯(绿灯)亮。
接线如下:
红外避障模块 | STM32 | 备注 |
---|---|---|
VCC | 3.3/5V | 电源正极 |
GND | GND | 电源负极 |
OUT | 任意 GPIO 口 | 数字输出 |
红外避障模块上的一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物时,红外线反射回来被接收管接收,经过比较器(LM393)电路处理之后,信号输出接口输出低电平信号,同时绿色指示灯会亮起。
因为黑色能够吸收红外线(红外线不反射),而白色不行(红外线反射),所以除了避障外可用作黑白线循迹、光电开关等等。
实现目标:我们有一个三色 LED 灯,当模块面前出现障碍物时,红灯亮,绿灯灭;没有障碍物时,红灯灭,绿灯亮。
这个小案例的应用场景可以应用在工业自动化,当物体或人在禁止区域或危险区域时,红灯亮起以提醒离开此区域。
本教程使用的硬件如下:
接线如下:
红外避障模块 | STM32 |
---|---|
VCC | 5V |
GND | G |
OUT | A4 |
烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法:https://www.lxlinux.net/e/stm32/five-ways-to-flash-program-to-stm32.html】。
ST-Link V2 | STM32 |
---|---|
SWCLK | SWCLK |
SWDIO | SWDIO |
GND | GND |
3.3V | 3V3 |
接好如下图:
开发板使用的是我们自绘的板子。大家也可以用自己的板子,只要是 STM32F103C8T6 主控芯片就行。
LED 灯,我们的老朋友了,不多介绍了。
void led_init(void) { GPIO_InitTypeDef gpio_init_struct; LED1_GPIO_CLK_ENABLE(); /* LED1时钟使能 */ LED3_GPIO_CLK_ENABLE(); /* LED3时钟使能 */ gpio_init_struct.Pin = LED1_GPIO_PIN; /* LED1引脚 */ gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */ HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct); /* 初始化LED1引脚 */ gpio_init_struct.Pin = LED3_GPIO_PIN; /* LED3引脚 */ HAL_GPIO_Init(LED3_GPIO_PORT, &gpio_init_struct); /* 初始化LED3引脚 */ LED1(0); /* 关闭 LED1 */ LED3(0); /* 关闭 LED3 */ }
LED 的 .h文件:
#ifndef _LED_H #define _LED_H #include "sys.h" /******************************************************************************************/ /* 引脚 定义 */ #define LED1_GPIO_PORT GPIOA #define LED1_GPIO_PIN GPIO_PIN_5 #define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */ #define LED3_GPIO_PORT GPIOA #define LED3_GPIO_PIN GPIO_PIN_7 #define LED3_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */ /******************************************************************************************/ /* LED端口定义 */ #define LED1(x) do{ x ? \ HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \ HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \ }while(0) #define LED3(x) do{ x ? \ HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_SET) : \ HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_RESET); \ }while(0) /* LED取反定义 */ #define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0) /* 翻转LED1 */ #define LED3_TOGGLE() do{ HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_GPIO_PIN); }while(0) /* 翻转LED3 */ /******************************************************************************************/ /* 外部接口函数*/ void led_init(void); /* LED初始化 */ #endif
初始化一下循迹模块的 OUT 引脚。
我们采用中断的方式亮灯,需要初始化和使能一下 EXTI。
void ia_init(void) { GPIO_InitTypeDef gpio_initstruct; IA_CLK(); /* IO口时钟使能 */ gpio_initstruct.Pin = IA_PIN; /* OUT引脚 */ gpio_initstruct.Mode = GPIO_MODE_IT_RISING_FALLING; /* 中断沿触发 */ gpio_initstruct.Pull = GPIO_NOPULL; /* 无电阻 */ HAL_GPIO_Init(IA_GPIO, &gpio_initstruct); /* 初始化OUT引脚 */ HAL_NVIC_SetPriority(EXTI4_IRQn,2,0); /* 抢占优先级2,响应优先级0 */ HAL_NVIC_EnableIRQ(EXTI4_IRQn); /* 使能EXTI4 */ }
复写「HAL_GPIO_EXTI_Callback」函数,检测中断沿,下降沿表示循迹模块感受到有障碍,「iaflag」置1;上降沿表示循迹模块感受到无障碍,「iaflag」置0。
uint16_t iaflag; uint16_t get_iaflag(void) { return iaflag; } void set_iaflag(uint16_t value) { iaflag = value; } void EXTI4_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); /* 调用中断处理公用函数 清除中断线 的中断标志位 */ __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4); /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */ } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == IA_PIN){ if(HAL_GPIO_ReadPin(IA_GPIO, IA_PIN) == GPIO_PIN_SET) //如果无障碍 { set_iaflag(0); } if(HAL_GPIO_ReadPin(IA_GPIO, IA_PIN) == GPIO_PIN_RESET) //如果有障碍 { set_iaflag(1); } } }
主函数如下:
依据「iaflag」,为1时表示有障碍,红灯亮,绿灯灭;为0时表示无障碍,绿灯亮,红灯灭。
int main(void) { HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */ led_init(); /* LED初始化 */ ia_init(); /* 红外模块初始化 */ while(1) { if (get_iaflag()) //有障碍时,红灯亮,绿灯灭 { HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_RESET); }else{ //无障碍时,绿灯亮,红灯灭 HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); } } }
当模块面前没有障碍物时,红灯灭,绿灯亮。
出现障碍物时,红灯亮,绿灯灭。
另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。
刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!
推荐阅读:
欢迎关注我的博客:良许嵌入式教程网,满满都是干货!