mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #9035 from SemjonKerner/driver_sensor_srf04
drivers/srf04: range finder sensor
This commit is contained in:
commit
ef4bd75412
@ -405,6 +405,12 @@ ifneq (,$(filter srf02,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter srf04,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
FEATURES_REQUIRED += periph_gpio_irq
|
||||
endif
|
||||
|
||||
ifneq (,$(filter srf08,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
USEMODULE += xtimer
|
||||
|
@ -222,6 +222,10 @@ ifneq (,$(filter soft_spi,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/soft_spi/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter srf04,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/srf04/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter sx127x,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/sx127x/include
|
||||
endif
|
||||
|
110
drivers/include/srf04.h
Normal file
110
drivers/include/srf04.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_srf04 srf04 ultra sonic range finder
|
||||
* @ingroup drivers_sensors
|
||||
* @brief Device driver for the srf04 ultra sonic range finder
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver for the srf04 ultra sonic range finder
|
||||
*
|
||||
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef SRF04_H
|
||||
#define SRF04_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "periph/gpio.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Status and error return codes
|
||||
*/
|
||||
enum {
|
||||
SRF04_OK = 0, /**< exit without error */
|
||||
SRF04_ERR_INVALID = -1, /**< error no valid measurement available*/
|
||||
SRF04_ERR_MEASURING = -2, /**< error sensor is measuring*/
|
||||
SRF04_ERR_GPIO = -3, /**< error initializing gpio*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief GPIO pins for srf04 device
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_t trigger; /**< GPIO Port the trigger pin is connected to */
|
||||
gpio_t echo; /**< GPIO Port the echo pin is connected to */
|
||||
} srf04_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for srf04 sensor
|
||||
*/
|
||||
typedef struct {
|
||||
srf04_params_t p; /**< GPIO Ports of device */
|
||||
int distance; /**< raw time of flight distance */
|
||||
uint32_t time; /**< timestamp of trigger or echo */
|
||||
} srf04_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize gpio and interrupt
|
||||
*
|
||||
* @param[out] dev device descriptor of sensor to initialize
|
||||
* @param[in] params init param struct holding gpio trigger and echo pins
|
||||
*
|
||||
* @return SRF04_OK on success
|
||||
* @return SRF04_GPIO on gpio init failure
|
||||
*/
|
||||
int srf04_init(srf04_t *dev, const srf04_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Triggers measurement
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*/
|
||||
void srf04_trigger(const srf04_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Returns time of flight in ms
|
||||
*
|
||||
* @note should not be invoked within 50 ms after triggering
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return time of flight in ms
|
||||
* @return SRF04_MEASURING if measurement is in progress
|
||||
* @return SRF04_INVALID if no valid measurement is available
|
||||
*/
|
||||
int srf04_read(const srf04_t* dev);
|
||||
|
||||
/**
|
||||
* @brief Convenience function triggers a measurement and returns distance
|
||||
*
|
||||
* @note This function will return after 50 ms once new data is available
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return time of flight in mm
|
||||
* @return SRF04_MEASURING if measurement is in progress
|
||||
* @return SRF04_INVALID if no valid measurement is available
|
||||
*/
|
||||
int srf04_get_distance(const srf04_t* dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SRF04_H */
|
||||
/** @} */
|
1
drivers/srf04/Makefile
Normal file
1
drivers/srf04/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
62
drivers/srf04/include/srf04_params.h
Normal file
62
drivers/srf04/include/srf04_params.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 Default configuration for srf04 devices
|
||||
*
|
||||
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef SRF04_PARAMS_H
|
||||
#define SRF04_PARAMS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "board.h"
|
||||
#include "srf04.h"
|
||||
|
||||
/**
|
||||
* @name Default configuration parameters for SRF04 device
|
||||
* @{
|
||||
*/
|
||||
#ifndef SRF04_PARAM_TRIGGER
|
||||
#define SRF04_PARAM_TRIGGER GPIO_PIN(0,13)
|
||||
#endif
|
||||
#ifndef SRF04_PARAM_ECHO
|
||||
#define SRF04_PARAM_ECHO GPIO_PIN(0,14)
|
||||
#endif
|
||||
|
||||
#ifndef SRF04_PARAMS
|
||||
#define SRF04_PARAMS \
|
||||
{ .trigger = SRF04_PARAM_TRIGGER, \
|
||||
.echo = SRF04_PARAM_ECHO, \
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SRF04 configuration
|
||||
*/
|
||||
static const srf04_params_t srf04_params[] = {
|
||||
SRF04_PARAMS
|
||||
};
|
||||
|
||||
#define SRF04_NUMOF (sizeof(srf04_params) / sizeof(srf04_params[0]))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SRF04_PARAMS_H */
|
||||
/** @} */
|
95
drivers/srf04/srf04.c
Normal file
95
drivers/srf04/srf04.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 <semjon.kerner@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
9
tests/driver_srf04/Makefile
Normal file
9
tests/driver_srf04/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
BOARD ?= nrf52dk
|
||||
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
USEMODULE += srf04
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
17
tests/driver_srf04/README.md
Normal file
17
tests/driver_srf04/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
tests/driver_srf04
|
||||
================
|
||||
This example shows the usage of an srf04 module.
|
||||
The application uses a timer and two gpio pins.
|
||||
The module is an ultrasonic range finder with a small protocol [1]:
|
||||
- trigger pin is raised high for 10 us by calling trigger function
|
||||
- after a sample period of 50 ms the value can be read out
|
||||
|
||||
[1] www.robot-electronics.co.uk/htm/srf04tech.htm
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Build, flash and start the application:
|
||||
|
||||
export BOARD=your_board
|
||||
make flash term
|
48
tests/driver_srf04/main.c
Normal file
48
tests/driver_srf04/main.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test for srf04 ultra sonic range finder driver
|
||||
*
|
||||
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "srf04_params.h"
|
||||
#include "srf04.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("SRF04 range finder example");
|
||||
|
||||
srf04_t dev;
|
||||
if (srf04_init(&dev, &srf04_params[0]) != SRF04_OK) {
|
||||
puts("Error: initializing");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int distance = srf04_get_distance(&dev);
|
||||
if (distance < SRF04_OK) {
|
||||
puts("Error: no valid data available");
|
||||
} else {
|
||||
printf("D: %d mm\n", distance);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user