diff --git a/drivers/include/srf02-ultrasonic-sensor.h b/drivers/include/srf02-ultrasonic-sensor.h deleted file mode 100644 index b8bf5bab0a..0000000000 --- a/drivers/include/srf02-ultrasonic-sensor.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2013 Zakaria Kasmi - * - * 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 srf02 SRF02 - * @ingroup drivers - * @brief Driver for the SRF02 ultrasonic range sensor - * - * The connection between the MCU and the SRF08 is based on the i2c-interface. - * - * @{ - * - * @file srf02-ultrasonic-sensor.h - * @brief Driver definitions for the SRF02 ultrasonic ranger. - * - * The connection between the SRF02 and the MCU is based on the i2c interface. - * - * @author Zakaria Kasmi - */ - -#ifndef SRF02_ULTRASONIC_SENSOR_I2C_H_ -#define SRF02_ULTRASONIC_SENSOR_I2C_H_ -#include "i2c.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* define the SRF02 registers*/ -#define SRF02_DEFAULT_ADDR 112 -#define SRF02_COMMAND_REG 0x0 -#define SRF02_RANGE_HIGH_BYTE 0x2 -#define SRF02_RANGE_LOW_BYTE 0x3 -#define SRF02_REAL_RANGING_MODE_INCH 0x50 -#define SRF02_REAL_RANGING_MODE_CM 0x51 -#define SRF02_REAL_RANGING_MODE_MICRO_SEC 0x52 -#define SRF02_FAKE_RANGING_MODE_INCH 0x56 -#define SRF02_FAKE_RANGING_MODE_CM 0x57 -#define SRF02_FAKE_RANGING_MODE_MICRO_SEC 0x58 - - -/* Define the used I2C Interface */ -//#define SRF02_I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0 -//#define SRF02_I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1 -//#define SRF02_I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1 -#define SRF02_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2 -#define SRF02_EXIT_MSG 0 -#define SRF02_RANGING_MSG 1 -#define SRF02_SLEEP_MSG 2 -#define SRF02_WEAKUP_MSG 3 - - -/** - * @brief Initialize the SRF02 ultrasonic sensor. - * - * @param[in] i2c_interface the i2c interface, several interfaces can be - * selected: i2c0, i2c1 and i2c2. - * @param[in] baud_rate the baud rate. - * - * @return true if the SRF02 is successfully initialized, otherwise false. - */ -bool srf02_init(uint8_t i2c_interface, uint32_t baud_rate); - - - -/** - * @brief Get the distance measured from the SRF02 ultrasonic sensor. - * The result of a ranging can be returned in inches, - * centimeters or microseconds - * - * @param[in] ranging_mode there are three real ranging modes, which return - * the result in inches, centimeters or microseconds. - * Another set of three fake ranging modes do the same - * but without transmitting the burst. - * - * @return the ranging result in inches, centimeters or microseconds. In the - * case of the fake ranging mode a zero value is returned. UINT32_MAX - * is returned if write/read action from the i2c-interface is failed. - * - */ -uint32_t srf02_get_distance(uint8_t ranging_mode); - -/** - * @brief Start a continuous sampling of the distance measures. - * This function prints the distance values over the rs232 - * interface. - * - * @param[i] ranging_mode there are three real ranging modes, which return - * the result in inches, centimeters or microseconds. - * Another set of three fake ranging modes do the same - * but without transmitting the burst. - * - */ -void srf02_start_ranging(uint16_t ranging_mode); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* SRF02_ULTRASONIC_SENSOR_I2C_H_ */ diff --git a/drivers/include/srf02.h b/drivers/include/srf02.h new file mode 100644 index 0000000000..be2c31b4d8 --- /dev/null +++ b/drivers/include/srf02.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2014 Hamburg University of Applied Sciences + * + * 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 driver_srf02 SRF02 ultrasonic range sensor + * @ingroup drivers + * @brief Driver for the SRF02 ultrasonic range sensor + * + * The connection between the MCU and the SRF02 is based on the i2c-interface. + * + * @{ + * + * @file srf02.h + * @brief Driver definitions for the SRF02 ultrasonic ranger. + * + * The connection between the SRF02 and the MCU is based on the i2c interface. + * + * @author Zakaria Kasmi + * @author Peter Kietzmann + */ + +#ifndef SRF02_H_ +#define SRF02_H_ + + +#include +#include "periph/i2c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* define the SRF02 registers*/ +#define SRF02_DEFAULT_ADDR 112 +#define SRF02_COMMAND_REG 0x0 +#define SRF02_RANGE_HIGH_BYTE 0x2 +#define SRF02_RANGE_LOW_BYTE 0x3 + +/** + * @brief Device descriptor for SRF02 sensors + */ +typedef struct { + i2c_t i2c; + uint8_t addr; +} srf02_t; + +/** + * @brief Possible measurement modes for the SRF02 sensor + */ +typedef enum { + SRF02_MODE_REAL_INCH = 0x50, + SRF02_MODE_REAL_CM = 0x51, + SRF02_REAL_RANGING_MODE_MICRO_SEC = 0x52, + SRF02_FAKE_RANGING_MODE_INCH = 0x56, + SRF02_FAKE_RANGING_MODE_CM = 0x57, + SRF02_FAKE_RANGING_MODE_MICRO_SEC = 0x58 +}srf02_mode_t; + +/** + * @brief Initialize the SRF02 ultrasonic sensor + * + * @param[in] dev device descriptor of an SRF02 sensor + * @param[in] i2c I2C device the sensor is connected to + * @param[in] addr I2C address of the sensor + * @param[in] speed I2C speed mode + * + * @return 0 on successful initialization + * @return -1 on undefined device given + * @return -2 on unsupported speed value + */ +int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr, i2c_speed_t speed); + +/** + * @brief Get the distance measured from the SRF02 ultrasonic sensor + * The result of a ranging can be returned in inches, + * centimeters or microseconds + * @param[in] dev device descriptor of an SRF02 sensor + * @param[in] mode there are three real ranging modes, which return + * the result in inches, centimeters or microseconds. + * Another set of three fake ranging modes do the same + * but without transmitting the burst + * + * @return -1 on undefined device given + * @return the ranging result in inches, centimeters or microseconds. In the + * case of the fake ranging mode a zero value is returned. UINT16_MAX + * is returned if write/read action from the i2c-interface is failed. + * + */ +uint16_t srf02_get_distance(srf02_t *dev, srf02_mode_t mode); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* SRF02_H_ */ diff --git a/drivers/srf02/Makefile b/drivers/srf02/Makefile index 48422e909a..e8d740a6c5 100644 --- a/drivers/srf02/Makefile +++ b/drivers/srf02/Makefile @@ -1 +1,3 @@ +MODULE = srf02 + include $(RIOTBASE)/Makefile.base diff --git a/drivers/srf02/srf02-ultrasonic-sensor.c b/drivers/srf02/srf02-ultrasonic-sensor.c deleted file mode 100644 index 26b718f8ba..0000000000 --- a/drivers/srf02/srf02-ultrasonic-sensor.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * srf02-ultrasonic-sensor.c - Driver for the SRF02 ultrasonic. - * - * Copyright (C) 2013 Zakaria Kasmi - * - * 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. - */ - -/** - * @file - * @internal - * @brief Driver for the SRF02 ultrasonic ranger. - * The connection between the MCU and the SRF08 is based on the - * i2c-interface. - * - * @author Zakaria Kasmi - * @version $Revision: 3856 $ - * - * @note $Id: srf02-ultrasonic-sensor.c 3857 2013-09-24 17:39:33 kasmi $ - * - */ - -#include -#include -#include -#include "msg.h" -#include "vtimer.h" -#include "timex.h" -#include "thread.h" -#include "hwtimer.h" -#include "srf02-ultrasonic-sensor.h" -#include "i2c.h" - -bool srf02_init(uint8_t i2c_interface, uint32_t baud_rate) -{ - if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL) - == false) { /* initialize I2C */ - puts("fatal error happened in i2c_initialize()\n"); - return false; - } - else { - i2c_enable_pull_up_resistor(i2c_interface); - //i2c_disable_pull_up_resistor(i2c_interface); - return true; - } -} - -uint32_t srf02_get_distance(uint8_t ranging_mode) -{ - bool status; - uint8_t reg_size = 1; - uint8_t range_high_byte = 0; - uint8_t range_low_byte = 0; - uint8_t rx_buff[reg_size]; - uint8_t tx_buff[reg_size]; - uint32_t distance = 0; - - tx_buff[0] = ranging_mode; - status = i2c_write(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, - SRF02_COMMAND_REG, tx_buff, reg_size); - - if (!status) { - puts("Write the ranging command to the i2c-interface is failed"); - distance = UINT32_MAX; - return distance; - } - - hwtimer_wait(HWTIMER_TICKS(65000)); - - status = i2c_read(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, - SRF02_RANGE_HIGH_BYTE, rx_buff, reg_size); - - if (!status) { - puts("Read the high echo byte from the i2c-interface is failed"); - distance = UINT32_MAX; - return distance; - } - - range_high_byte = rx_buff[0]; - - status = i2c_read(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, - SRF02_RANGE_LOW_BYTE, rx_buff, reg_size); - - if (!status) { - puts("Read the low echo byte from the i2c-interface is failed"); - distance = UINT32_MAX; - return distance; - } - - range_low_byte = rx_buff[0]; - - distance = (range_high_byte << 8) | range_low_byte; - //printf("%u | %u\n", range_high_byte, range_low_byte); - return distance; -} - -void srf02_start_ranging(uint16_t ranging_mode) -{ - - while (1) { - uint32_t distance = srf02_get_distance(ranging_mode); - - if (distance != UINT32_MAX) { - switch (ranging_mode) { - case SRF02_REAL_RANGING_MODE_CM : - printf("distance = %lu cm\n", distance); - break; - - case SRF02_REAL_RANGING_MODE_INCH : - printf("distance = %lu inch\n", distance); - break; - - case SRF02_REAL_RANGING_MODE_MICRO_SEC: - // dist_m = 0.000172 distance_micro_sec (air) - printf("distance = %lu micro_sec\n", distance); - break; - - case SRF02_FAKE_RANGING_MODE_CM: - case SRF02_FAKE_RANGING_MODE_INCH: - case SRF02_FAKE_RANGING_MODE_MICRO_SEC: - printf("distance fake ranging = %lu \n", distance); - break; - - default: - printf("distance = %lu cm\n", distance); - } - - hwtimer_wait(HWTIMER_TICKS(50000)); - } - else { - break; - } - } - - puts("The SRF02 range sampling is ended!!"); -} diff --git a/drivers/srf02/srf02.c b/drivers/srf02/srf02.c new file mode 100644 index 0000000000..83335f5fb1 --- /dev/null +++ b/drivers/srf02/srf02.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Hamburg University of Applied Sciences + * + * 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 driver_srf02 + * @{ + * + * @file srf02.c + * @brief Driver for the SRF02 ultrasonic ranger. + * The connection between the MCU and the SRF02 is based on the + * i2c-interface. + * + * @author Zakaria Kasmi + * @author Peter Kietzmann + * + * @} + */ + +#include +#include +#include +#include "msg.h" +#include "vtimer.h" +#include "timex.h" +#include "thread.h" +#include "hwtimer.h" +#include "srf02.h" +#include "periph/i2c.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + + +int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr, i2c_speed_t speed) +{ + dev->i2c = i2c; + dev->addr = addr; + + /* initialize i2c interface */ + return i2c_init_master(i2c, speed); +} + +uint16_t srf02_get_distance(srf02_t *dev, srf02_mode_t mode) +{ + int status; + char range_high_byte = 0; + char range_low_byte = 0; + uint16_t distance = 0; + + /* initialize measure mode*/ + status = i2c_write_reg(dev->i2c, dev->addr, SRF02_COMMAND_REG, mode); + + if (status < 0) { + DEBUG("Write the ranging command to the i2c-interface is failed"); + uint16_t distance = UINT16_MAX; + return distance; + } + + hwtimer_wait(70000); + + status = i2c_read_reg(dev->i2c, dev->addr, + SRF02_RANGE_HIGH_BYTE, &range_high_byte); + + if (status < 0) { + DEBUG("Read the high echo byte from the i2c-interface is failed"); + distance = UINT16_MAX; + return distance; + } + + status = i2c_read_reg(dev->i2c, dev->addr, + SRF02_RANGE_LOW_BYTE, &range_low_byte); + + if (status < 0) { + DEBUG("Read the low echo byte from the i2c-interface is failed"); + distance = UINT16_MAX; + return distance; + } + + distance = (range_high_byte << 8) | (range_low_byte); + + return distance; +} diff --git a/tests/driver_srf02/Makefile b/tests/driver_srf02/Makefile new file mode 100644 index 0000000000..7e2a1a3c4b --- /dev/null +++ b/tests/driver_srf02/Makefile @@ -0,0 +1,24 @@ +APPLICATION = driver_srf02 +include ../Makefile.tests_common + +FEATURES_REQUIRED = periph_i2c + +USEMODULE += vtimer +USEMODULE += srf02 + +# Define default settings +export TEST_SRF02_I2C ?= I2C_0 +export TEST_SRF02_SPEED ?= I2C_SPEED_NORMAL +export TEST_MODE ?= SRF02_MODE_REAL_CM + +include $(RIOTBASE)/Makefile.include + +ifneq (,$(TEST_SRF02_I2C)) +export CFLAGS += -DTEST_SRF02_I2C=$(TEST_SRF02_I2C) +endif +ifneq (,$(TEST_SRF02_SPEED)) +export CFLAGS += -DTEST_SRF02_SPEED=$(TEST_SRF02_SPEED) +endif +ifneq (,$(TEST_MODE)) +export CFLAGS += -DTEST_MODE=$(TEST_MODE) +endif diff --git a/tests/driver_srf02/README.md b/tests/driver_srf02/README.md new file mode 100644 index 0000000000..4a4bdeb6f3 --- /dev/null +++ b/tests/driver_srf02/README.md @@ -0,0 +1,10 @@ +# About +This is a manual test application for the SRF02 ultrasonic ranger driver. + +# Usage + + +After initialization, the sensor value is read periodically and printed to the STDOUT. + +To verify the seen value you can focus the sensor against any reflecting object and vary the distance to +see the value changing. diff --git a/tests/driver_srf02/main.c b/tests/driver_srf02/main.c new file mode 100644 index 0000000000..61ac112e97 --- /dev/null +++ b/tests/driver_srf02/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 Hamburg University of Applied Sciences + * + * 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 application for the SRF02 ultrasonic range sensor + * + * @author Peter Kietzmann + * + * @} + */ +#ifndef TEST_SRF02_I2C +#error "TEST_SRF02_I2C not defined" +#endif +#ifndef TEST_SRF02_SPEED +#error "TEST_SRF02_SPEED not defined" +#endif +#ifndef TEST_MODE +#error "TEST_MODE not defined" +#endif + +#include + +#include "vtimer.h" +#include "srf02.h" +#include "periph/i2c.h" + + #define SLEEP (1000 * 1000U) + + static srf02_t srf02_0; + +int main(void) +{ + int res; + puts("SRF02 ultrasonic ranger test application\n"); + printf("Initializing SRF02 sensor at I2C_%i... ", TEST_SRF02_I2C); + res = srf02_init(&srf02_0, TEST_SRF02_I2C, SRF02_DEFAULT_ADDR, TEST_SRF02_SPEED); + + if (res < 0) { + printf("[Failed]"); + return 1; + } + else { + puts("[Ok]\n"); + + while(1) { + uint16_t distance = srf02_get_distance(&srf02_0, TEST_MODE); + printf("distance = %i cm\n", distance); + vtimer_usleep(SLEEP); + } + } +}