基于DragonBoard 410c的红外障碍物检测
本博客给大家介绍一下如何用DragonBoard 410c开发板实现红外检测障碍物.选择的红外传感模块如图1所示:
图1
该传感模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物时,红外线反射回来被接收管接收,经过比较器电路处理之后,输出显示灯会亮起,同时信号输出接口输出一个低电平信号,可以通过电位器旋钮调节检测距离,有效距离范围2~30cm,工作电压为3.3V~5V.
本设计选择GPIO_13为输入脚,用于接收红外模块的信号(用中断方式实现),选择GPIO_69作为输出脚,用于控制RGB灯的亮灭.当检测到有障碍物时,RGB灯亮起,无障碍物时,RGB灯熄灭.实物连接如图2所示:
图2
代码实现如下:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/irq.h>
#include <linux/of_gpio.h>
#include <asm/uaccess.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
struct infrared_led_data {
struct platform_device *pdev;
int infrared_gpio;
int led_gpio;
int irq;
};
static irqreturn_t infrared_interrupt_handler(int irq, void *ptr)
{
struct infrared_led_data* data = (struct infrared_led_data*)ptr;
if(!gpio_get_value(data->infrared_gpio)){
gpio_set_value(data->led_gpio, 0);
} else {
gpio_set_value(data->led_gpio, 1);
}
return IRQ_HANDLED;
}
static int infrared_probe(struct platform_device *pdev)
{
int result;
struct infrared_led_data* data = NULL;
struct device_node* node = pdev->dev.of_node;
data = devm_kzalloc(&pdev->dev, sizeof(data),GFP_KERNEL);
if(!data){
pr_err("%s kzalloc error\n",__FUNCTION__);
return -ENOMEM;
}
dev_set_drvdata(&pdev->dev,data);
data->infrared_gpio = of_get_named_gpio(node,"thundersoft,infrared_gpio",0);
if (!gpio_is_valid(data->infrared_gpio)) {
pr_err("gpio not specified\n");
goto err1;
} else {
result = gpio_request(data->infrared_gpio, "infrared_gpio");
if(result<0){
pr_err("Unable to request infrared gpio\n");
goto err1;
}else {
printk("request gpio 36 success\n");
gpio_direction_input(data->infrared_gpio);
}
}
data->led_gpio = of_get_named_gpio(node,"thundersoft,led_gpio",0);
if (!gpio_is_valid(data->led_gpio)) {
pr_err("gpio not specified\n");
goto err2;
} else {
result = gpio_request(data->led_gpio, "infrared_gpio");
if(result<0){
pr_err("Unable to request led gpio\n");
goto err2;
} else {
gpio_direction_output(data->led_gpio, 0);
}
}
data->irq = gpio_to_irq(data->infrared_gpio);
result = request_irq(data->irq,infrared_interrupt_handler,
IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"infrared_led_intr",data);
if(result<0){
pr_err("Unable to request irq\n");
goto err3;
}
printk("infrared probe success\n");
return 0;
err3:
gpio_free(data->led_gpio);
err2:
gpio_free(data->infrared_gpio);
err1:
kfree(data);
printk("infrared probe failed\n");
return -EINVAL;
}
static int infrared_remove(struct platform_device *pdev)
{
struct infrared_led_data* data = dev_get_drvdata(&pdev->dev);
gpio_free(data->led_gpio);
gpio_free(data->infrared_gpio);
kfree(data);
return 0;
}
static struct of_device_id infrared_match_table[] = {
{ .compatible = "thundersoft,infrared",},
{ },
};
static struct platform_driver infrared_driver = {
.probe = infrared_probe,
.remove = infrared_remove,
.driver = {
.owner = THIS_MODULE,
.name = "infrared",
.of_match_table = infrared_match_table,
},
};
module_platform_driver(infrared_driver);
MODULE_AUTHOR("[email protected]");
MODULE_LICENSE("GPL v2");