基于DragonBoard 410c的红外障碍物检测

     本博客给大家介绍一下如何用DragonBoard 410c开发板实现红外检测障碍物.选择的红外传感模块如图1所示:

基于DragonBoard 410c的红外障碍物检测

图1

        该传感模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物时,红外线反射回来被接收管接收,经过比较器电路处理之后,输出显示灯会亮起,同时信号输出接口输出一个低电平信号,可以通过电位器旋钮调节检测距离,有效距离范围2~30cm,工作电压为3.3V~5V.

         本设计选择GPIO_13为输入脚,用于接收红外模块的信号(用中断方式实现),选择GPIO_69作为输出脚,用于控制RGB灯的亮灭.当检测到有障碍物时,RGB灯亮起,无障碍物时,RGB灯熄灭.实物连接如图2所示:

基于DragonBoard 410c的红外障碍物检测

图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");