/* * Copyright (C) 2018 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup drivers_srf04 * @{ * * @file * @brief driver for srf04 ultra sonic range finder * * @author Semjon Kerner * * @} */ #include "srf04.h" #include "srf04_params.h" #define ENABLE_DEBUG 0 #include "debug.h" #define SRF04_DISTANCE (584U) #define SRF04_SAMPLE_PERIOD (50U * US_PER_MS) static void _cb(void *arg) { uint32_t t = xtimer_now_usec(); srf04_t *dev = (srf04_t *)arg; if (dev->distance > SRF04_ERR_MEASURING) { dev->distance = SRF04_ERR_MEASURING; dev->time = t; } else { gpio_irq_disable(dev->p.echo); dev->distance = (t - dev->time); } } int srf04_init(srf04_t *dev, const srf04_params_t *params) { dev->p = *params; dev->distance = SRF04_ERR_INVALID; dev->time = 0; if (gpio_init(dev->p.trigger, GPIO_OUT) != 0) { DEBUG("[srf04] Error: could not initialize GPIO trigger pin\n"); return SRF04_ERR_GPIO; } if (gpio_init_int(dev->p.echo, GPIO_IN, GPIO_BOTH, _cb, (void *)dev) != 0) { DEBUG("[srf04] Error: could not initialize GPIO echo pin\n"); return SRF04_ERR_GPIO; } gpio_irq_disable(dev->p.echo); return SRF04_OK; } void srf04_trigger(const srf04_t *dev) { if (dev->distance == SRF04_ERR_MEASURING) { return; } gpio_irq_enable(dev->p.echo); gpio_set(dev->p.trigger); xtimer_usleep(10); gpio_clear(dev->p.trigger); } int srf04_read(const srf04_t *dev) { return dev->distance; } int srf04_get_distance(const srf04_t *dev) { /* Trigger new reading */ srf04_trigger(dev); /* Give the sensor the required time for sampling */ xtimer_usleep(SRF04_SAMPLE_PERIOD); /* Get the result */ if (dev->distance >= SRF04_OK) { return ((dev->distance * 100) / SRF04_DISTANCE); } return dev->distance; }