mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 04:52:59 +01:00
drivers/srf08: initial import of the updated ultrasonic driver
This commit is contained in:
parent
2feb6423a7
commit
46fdcf64c1
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
|
||||||
*
|
|
||||||
* 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 srf08 SRF08
|
|
||||||
* @ingroup drivers
|
|
||||||
* @brief Driver for the SRF08 ultrasonic range sensor
|
|
||||||
*
|
|
||||||
* The connection between the MCU and the SRF08 is based on the i2c-interface.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file
|
|
||||||
* @internal
|
|
||||||
* @brief Driver definitions for the SRF08 ultrasonic.
|
|
||||||
*
|
|
||||||
* The communication between the MCU and SRF08 is via the i2c interface.
|
|
||||||
*
|
|
||||||
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SRF08_ULTRASONIC_SENSOR_I2C_H_
|
|
||||||
#define SRF08_ULTRASONIC_SENSOR_I2C_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @brief The sensors default I2C address */
|
|
||||||
#define SRF08_DEFAULT_ADDR 112
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief The sensors command register (write) */
|
|
||||||
#define SRF08_COMMAND_REG 0x0
|
|
||||||
|
|
||||||
/** @brief Max. gain register (write) */
|
|
||||||
#define SRF08_GAIN_REG 0x1
|
|
||||||
|
|
||||||
/** @brief The sensors range register (write) */
|
|
||||||
#define SRF08_RANGE_REG 0x2
|
|
||||||
|
|
||||||
/** @brief The upper measurement byte (read) */
|
|
||||||
#define SRF08_RANGE_HIGH_BYTE 0x2
|
|
||||||
|
|
||||||
/** @brief The lower measurement byte (read)*/
|
|
||||||
#define SRF08_RANGE_LOW_BYTE 0x3
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief Measure in inch mode */
|
|
||||||
#define SRF08_REAL_RANGING_MODE_CM 0x50
|
|
||||||
|
|
||||||
/** @brief Measure in cm mode */
|
|
||||||
#define SRF08_REAL_RANGING_MODE_CM 0x51
|
|
||||||
|
|
||||||
/** @brief Measure in micro-seconds mode */
|
|
||||||
#define SRF08_REAL_RANGING_MODE_CM 0x52
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief Number of highest register */
|
|
||||||
#define SRF08_MAX_REGISTER_NUMBER 35
|
|
||||||
|
|
||||||
/** @brief Maximum number of echos from more distant objects */
|
|
||||||
#define SRF08_MAX_ECHO_NUMBER 17
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief Define the used I2C Interface */
|
|
||||||
#define SRF08_I2C_INTERFACE I2C2 /* P0.10 SDA2, P0.11 SCL2 */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the SRF08 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 SRF08 is successfully initialized, otherwise false.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool srf08_init(uint8_t i2c_interface, uint32_t baud_rate);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Start a continuous distance ranging with the SRF08 ultrasonic
|
|
||||||
* range-finder.
|
|
||||||
* The ranging results are given over the RS232-Interface.
|
|
||||||
*
|
|
||||||
* @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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void srf08_start_ranging(uint8_t ranging_mode);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the maximum range of the SRF08.
|
|
||||||
*
|
|
||||||
* @param[in] max_range the adjusted maximal range is:
|
|
||||||
* max_range = (max_rangex43mm) + 43mm.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void srf08_set_range(uint8_t max_range);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the maximum of the analog stages.
|
|
||||||
*
|
|
||||||
* @param[in] max_gain the maximal gain value.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void srf08_set_gain(uint8_t max_gain);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the maximal range.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return the maximal range value.
|
|
||||||
*/
|
|
||||||
uint8_t srf08_get_range(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the maximal analog gain.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return the maximal gain value.
|
|
||||||
*/
|
|
||||||
uint8_t srf08_get_gain(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get all distances measured from the SRF08 ultrasonic sensor.
|
|
||||||
* The results of a ranging can be returned in inches, centimeters
|
|
||||||
* or microseconds. The SRF08 can detect up to targets.
|
|
||||||
* This function prints the distance values over the rs232
|
|
||||||
* interface
|
|
||||||
*
|
|
||||||
* @param[in] range_array a pointer to a buffer holding the ranging results.
|
|
||||||
* @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 -1 if the write/read action from the i2c-interface is failed,
|
|
||||||
* otherwise the number of the detected targets is delivered.
|
|
||||||
*/
|
|
||||||
int32_t srf08_get_distances(uint32_t *range_array, uint8_t ranging_mode);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
#endif /* SRF08_ULTRASONIC_SENSOR_I2C_H_ */
|
|
164
drivers/include/srf08.h
Normal file
164
drivers/include/srf08.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||||
|
*
|
||||||
|
* 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_srf08 SRF08 ultrasonic range sensor
|
||||||
|
* @ingroup drivers
|
||||||
|
* @brief Driver for the SRF08 ultrasonic range sensor
|
||||||
|
*
|
||||||
|
* The connection between the MCU and the SRF08 is based on the i2c-interface.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file srf08.h
|
||||||
|
* @brief Driver definitions for the SRF02 ultrasonic ranger.
|
||||||
|
*
|
||||||
|
* The connection between the SRF08 and the MCU is based on the i2c interface.
|
||||||
|
*
|
||||||
|
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||||
|
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRF08_H_
|
||||||
|
#define SRF08_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "periph/i2c.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @brief The sensors default I2C address */
|
||||||
|
#define SRF08_DEFAULT_ADDR 112
|
||||||
|
|
||||||
|
/** @brief The sensors command register (write) */
|
||||||
|
#define SRF08_COMMAND_REG 0x0
|
||||||
|
|
||||||
|
/** @brief Max. gain register (write) */
|
||||||
|
#define SRF08_GAIN_REG 0x1
|
||||||
|
|
||||||
|
/** @brief The sensors range register (write) */
|
||||||
|
#define SRF08_RANGE_REG 0x2
|
||||||
|
|
||||||
|
/** @brief The upper measurement byte (read) */
|
||||||
|
#define SRF08_RANGE_HIGH_BYTE 0x2
|
||||||
|
|
||||||
|
/** @brief The lower measurement byte (read)*/
|
||||||
|
#define SRF08_RANGE_LOW_BYTE 0x3
|
||||||
|
|
||||||
|
/** @brief Number of highest register */
|
||||||
|
#define SRF08_MAX_REGISTER_NUMBER 35
|
||||||
|
|
||||||
|
/** @brief Maximum number of echos from more distant objects */
|
||||||
|
#define SRF08_MAX_ECHO_NUMBER 17
|
||||||
|
|
||||||
|
/** @brief Maximum range the sensor can measure (6m) */
|
||||||
|
#define SRF08_MAX_RANGE_6M 0x8C
|
||||||
|
|
||||||
|
/** @brief Maximum gain of the sensor (1025)*/
|
||||||
|
#define SRF08_MAX_GAIN 0x25
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Device descriptor for SRF08 sensors
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
i2c_t i2c; /**< I2C device the sensor is connected to */
|
||||||
|
uint8_t addr; /**< I2C bus address of the sensor */
|
||||||
|
} srf08_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Possible measurement modes for the SRF08 sensor
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
SRF08_MODE_INCH = 0x50, /**< result in inches */
|
||||||
|
SRF08_MODE_CM = 0x51, /**< result in centimeters */
|
||||||
|
SRF08_MODE_MICRO_SEC = 0x52, /**< result in centimeters */
|
||||||
|
SRF08_ANN_MODE_INCH = 0x53, /**< synchronous measurement in inches */
|
||||||
|
SRF08_ANN_MODE_CM = 0x54, /**< synchronous measurement in centimeters */
|
||||||
|
SRF08_ANN_MODE_MICRO_SEC = 0x55 /**< synchronous measurement in microseconds */
|
||||||
|
}srf08_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the SRF08 ultrasonic sensor
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor of an SRF08 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
|
||||||
|
* @return -3 on max. range error
|
||||||
|
* @return -4 on max. gain error
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int srf08_init(srf08_t *dev, i2c_t i2c, uint8_t addr, i2c_speed_t speed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the maximum range of the SRF08.
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor of an SRF08 sensor
|
||||||
|
* @param[in] max_range the adjusted maximal range is:
|
||||||
|
* max_range = (max_range x 43mm) + 43mm.
|
||||||
|
* The hardware limit is 6m.
|
||||||
|
*
|
||||||
|
* @return 1 on success
|
||||||
|
* @return -1 on undefined device given
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int srf08_set_max_range(srf08_t *dev, uint8_t max_range);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the maximum of the analog stages.
|
||||||
|
*
|
||||||
|
* @ note
|
||||||
|
* This value is just a limitation of the maximum amplification and not the actual.
|
||||||
|
* While measuing, this value starts at its minimum and increases approx. each 75 us
|
||||||
|
* until the maximum value is reached.
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor of an SRF08 sensor
|
||||||
|
* @param[in] max_gain the maximal gain value.
|
||||||
|
*
|
||||||
|
* @return 1 on success
|
||||||
|
* @return -1 on undefined device given
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int srf08_set_max_gain(srf08_t *dev, uint8_t max_gain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all distances measured from the SRF08 ultrasonic sensor.
|
||||||
|
* The results of a ranging can be returned in inches, centimeters
|
||||||
|
* or microseconds. The SRF08 can detect up to 17 targets.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor of an SRF08 sensor
|
||||||
|
* @param[in] range_array a pointer to a buffer holding the ranging results.
|
||||||
|
* @param[in] num_echos number of stored measurements (echos)
|
||||||
|
* @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 number of measured echos on success
|
||||||
|
* @return -1 on ranging mode errors
|
||||||
|
* @return -2 if num_echos exceeds the max. number of
|
||||||
|
possible measurements
|
||||||
|
* @return -3 if i2c read high byte failed
|
||||||
|
* @return -4 if i2c read low byte failed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int srf08_get_distances(srf08_t *dev, uint16_t *range_array, int num_echos, srf08_mode_t ranging_mode);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
#endif /* SRF08_H_ */
|
@ -1 +1,3 @@
|
|||||||
|
MODULE = srf08
|
||||||
|
|
||||||
include $(RIOTBASE)/Makefile.base
|
include $(RIOTBASE)/Makefile.base
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* srf08-ultrasonic-sensor.c - Driver for the SRF08 ultrasonic ranger via the
|
|
||||||
* i2c interface.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
|
||||||
*
|
|
||||||
* 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 SRF08 ultrasonic ranger using the i2c interface.
|
|
||||||
*
|
|
||||||
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
|
||||||
* @version $Revision: 3857 $
|
|
||||||
*
|
|
||||||
* @note $Id: srf08-ultrasonic-sensor.c 3857 2013-09-05 14:45:13 kasmi $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "hwtimer.h"
|
|
||||||
#include "srf08-ultrasonic-sensor.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
|
|
||||||
bool srf08_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void srf08_set_range(uint8_t max_range)
|
|
||||||
{
|
|
||||||
uint8_t tx_buff[1];
|
|
||||||
|
|
||||||
tx_buff[0] = max_range;
|
|
||||||
i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_RANGE_REG, tx_buff,
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void srf08_set_gain(uint8_t gain)
|
|
||||||
{
|
|
||||||
uint8_t tx_buff[1];
|
|
||||||
|
|
||||||
tx_buff[0] = gain;
|
|
||||||
i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_GAIN_REG, tx_buff,
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t srf08_get_range(void)
|
|
||||||
{
|
|
||||||
uint8_t rx_buff[1];
|
|
||||||
|
|
||||||
i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_RANGE_REG, rx_buff,
|
|
||||||
1);
|
|
||||||
return rx_buff[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t srf08_get_gain(void)
|
|
||||||
{
|
|
||||||
uint8_t rx_buff[1];
|
|
||||||
|
|
||||||
i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_GAIN_REG, rx_buff,
|
|
||||||
1);
|
|
||||||
return rx_buff[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32_t srf08_get_distances(uint32_t *range_array, uint8_t ranging_mode)
|
|
||||||
{
|
|
||||||
bool status;
|
|
||||||
uint8_t reg_size = 1;
|
|
||||||
uint8_t rx_buff[reg_size];
|
|
||||||
uint8_t tx_buff[reg_size];
|
|
||||||
uint8_t register_location;
|
|
||||||
uint8_t echo_number = 0;
|
|
||||||
|
|
||||||
tx_buff[0] = ranging_mode;
|
|
||||||
status = i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR,
|
|
||||||
SRF08_COMMAND_REG, tx_buff, reg_size);
|
|
||||||
if (!status) {
|
|
||||||
puts("Write the ranging command to the i2c-interface is failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hwtimer_wait(HWTIMER_TICKS(70000));
|
|
||||||
|
|
||||||
// Read all echo buffers
|
|
||||||
for (register_location = 2; register_location < SRF08_MAX_REGISTER_NUMBER;
|
|
||||||
register_location += 2) {
|
|
||||||
//read the high echo byte
|
|
||||||
status = i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR,
|
|
||||||
register_location, rx_buff, reg_size);
|
|
||||||
if (!status) {
|
|
||||||
puts("Read the high echo byte from the i2c-interface is failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uint8_t range_high_byte = rx_buff[0];
|
|
||||||
//read the low echo byte
|
|
||||||
status = i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR,
|
|
||||||
register_location + 1, rx_buff, reg_size);
|
|
||||||
if (!status) {
|
|
||||||
puts("Read the low echo byte from the i2c-interface is failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uint8_t range_low_byte = rx_buff[0];
|
|
||||||
if ((range_high_byte == 0) && (range_low_byte == 0)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uint32_t distance = (range_high_byte << 8) | range_low_byte;
|
|
||||||
range_array[(register_location - 2) / 2] = distance;
|
|
||||||
echo_number++;
|
|
||||||
printf("distance = %4lu cm , echo%d\n",
|
|
||||||
distance, register_location / 2);
|
|
||||||
}
|
|
||||||
hwtimer_wait(HWTIMER_TICKS(500000));
|
|
||||||
}
|
|
||||||
puts("--------------------------------------------");
|
|
||||||
return echo_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
void srf08_start_ranging(uint8_t ranging_mode)
|
|
||||||
{
|
|
||||||
uint32_t range_array[SRF08_MAX_ECHO_NUMBER];
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
puts("Ultrasonic SRF08 engine is started");
|
|
||||||
//wait due to calibration
|
|
||||||
hwtimer_wait(HWTIMER_TICKS(700000));
|
|
||||||
printf("Actual range = %d\n", srf08_get_range());
|
|
||||||
printf("Actual gain = %d\n", srf08_get_gain());
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
puts("--------------------------------------------");
|
|
||||||
uint8_t echo_number = srf08_get_distances(range_array, ranging_mode);
|
|
||||||
if (echo_number > 0) {
|
|
||||||
for (i = 0; i < echo_number; i++) {
|
|
||||||
printf("stored distance = %4lu cm , echo%d\n", range_array[i], i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
117
drivers/srf08/srf08.c
Normal file
117
drivers/srf08/srf08.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||||
|
*
|
||||||
|
* 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_srf08
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file srf08.c
|
||||||
|
* @brief Driver for the SRF08 ultrasonic ranger.
|
||||||
|
* The connection between the MCU and the SRF08 is based on the
|
||||||
|
* i2c-interface.
|
||||||
|
*
|
||||||
|
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||||
|
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "hwtimer.h"
|
||||||
|
#include "srf08.h"
|
||||||
|
#include "periph/i2c.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
int srf08_init(srf08_t *dev, i2c_t i2c, uint8_t addr, i2c_speed_t speed)
|
||||||
|
{
|
||||||
|
dev->i2c = i2c;
|
||||||
|
dev->addr = addr;
|
||||||
|
|
||||||
|
/* initialize i2c interface */
|
||||||
|
if(i2c_init_master(i2c, speed) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* set the maximum range */
|
||||||
|
if (srf08_set_max_range(dev, SRF08_MAX_RANGE_6M) < 0) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
/* set the maximum gain */
|
||||||
|
if (srf08_set_max_gain(dev, SRF08_MAX_GAIN) < 0) {
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int srf08_set_max_range(srf08_t *dev, uint8_t max_range)
|
||||||
|
{
|
||||||
|
return i2c_write_reg(dev->i2c, dev->addr, SRF08_RANGE_REG, max_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int srf08_set_max_gain(srf08_t *dev, uint8_t gain)
|
||||||
|
{
|
||||||
|
return i2c_write_reg(dev->i2c, dev->addr, SRF08_GAIN_REG, gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int srf08_get_distances(srf08_t *dev, uint16_t *range_array, int num_echos, srf08_mode_t ranging_mode)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int echo_number = 0;
|
||||||
|
char range_bytes[sizeof(uint16_t)];
|
||||||
|
char register_location;
|
||||||
|
char max_reg_no_read = (num_echos * sizeof(range_bytes)) +1;
|
||||||
|
|
||||||
|
/* set ranging mode */
|
||||||
|
status = i2c_write_reg(dev->i2c, dev->addr, SRF08_COMMAND_REG, ranging_mode);
|
||||||
|
|
||||||
|
if (!status) {
|
||||||
|
DEBUG("Write the ranging command to the i2c-interface is failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(max_reg_no_read > SRF08_MAX_REGISTER_NUMBER) {
|
||||||
|
DEBUG("Too many echos requested. Max. is 17");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwtimer_wait(HWTIMER_TICKS(70000));
|
||||||
|
|
||||||
|
/* read all echo buffers */
|
||||||
|
for (register_location = 2; register_location < max_reg_no_read;
|
||||||
|
register_location += sizeof(range_bytes)) {
|
||||||
|
|
||||||
|
/* read the echo bytes */
|
||||||
|
status = i2c_read_regs(dev->i2c, dev->addr, register_location, range_bytes, sizeof(range_bytes));
|
||||||
|
|
||||||
|
if (!status) {
|
||||||
|
DEBUG("Read the echo bytes from the i2c-interface is failed");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range_bytes == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
uint16_t distance = (range_bytes[0] << 8) | range_bytes[1];
|
||||||
|
range_array[(register_location - 2) / 2] = distance;
|
||||||
|
echo_number++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return echo_number;
|
||||||
|
}
|
28
tests/driver_srf08/Makefile
Normal file
28
tests/driver_srf08/Makefile
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
APPLICATION = driver_srf08
|
||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
FEATURES_REQUIRED = periph_i2c
|
||||||
|
|
||||||
|
USEMODULE += vtimer
|
||||||
|
USEMODULE += srf08
|
||||||
|
|
||||||
|
# Define default settings
|
||||||
|
export TEST_SRF08_I2C ?= I2C_0
|
||||||
|
export TEST_SRF08_SPEED ?= I2C_SPEED_NORMAL
|
||||||
|
export TEST_MODE ?= SRF08_MODE_CM
|
||||||
|
export TEST_NUM_ECHOS?= 3
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
|
||||||
|
ifneq (,$(TEST_SRF08_I2C))
|
||||||
|
export CFLAGS += -DTEST_SRF08_I2C=$(TEST_SRF08_I2C)
|
||||||
|
endif
|
||||||
|
ifneq (,$(TEST_SRF08_SPEED))
|
||||||
|
export CFLAGS += -DTEST_SRF08_SPEED=$(TEST_SRF08_SPEED)
|
||||||
|
endif
|
||||||
|
ifneq (,$(TEST_MODE))
|
||||||
|
export CFLAGS += -DTEST_MODE=$(TEST_MODE)
|
||||||
|
endif
|
||||||
|
ifneq (,$(TEST_NUM_ECHOS))
|
||||||
|
export CFLAGS += -DTEST_NUM_ECHOS=$(TEST_NUM_ECHOS)
|
||||||
|
endif
|
10
tests/driver_srf08/README.md
Normal file
10
tests/driver_srf08/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# About
|
||||||
|
This is a manual test application for the SRF08 ultrasonic ranger driver.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
|
||||||
|
After initialization, the sensor values are read periodically and printed to the STDOUT. Here, three echos are stored.
|
||||||
|
|
||||||
|
To verify the seen values you can focus the sensor against any reflecting object and vary the distance to
|
||||||
|
see especially the first measured value changing.
|
78
tests/driver_srf08/main.c
Normal file
78
tests/driver_srf08/main.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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 SRF08 ultrasonic range sensor
|
||||||
|
*
|
||||||
|
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#ifndef TEST_SRF08_I2C
|
||||||
|
#error "TEST_SRF08_I2C not defined"
|
||||||
|
#endif
|
||||||
|
#ifndef TEST_SRF08_SPEED
|
||||||
|
#error "TEST_SRF08_SPEED not defined"
|
||||||
|
#endif
|
||||||
|
#ifndef TEST_MODE
|
||||||
|
#error "TEST_MODE not defined"
|
||||||
|
#endif
|
||||||
|
#ifndef TEST_NUM_ECHOS
|
||||||
|
#error "TEST_NUM_ECHOS not defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "vtimer.h"
|
||||||
|
#include "srf08.h"
|
||||||
|
#include "periph/i2c.h"
|
||||||
|
|
||||||
|
#define SLEEP (1000 * 1000U)
|
||||||
|
|
||||||
|
static srf08_t srf08_0;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
puts("SRF08 ultrasonic ranger test application\n");
|
||||||
|
printf("Initializing SRF08 sensor at I2C_%i... ", TEST_SRF08_I2C);
|
||||||
|
|
||||||
|
int res;
|
||||||
|
uint16_t range_array[TEST_NUM_ECHOS];
|
||||||
|
|
||||||
|
res = srf08_init(&srf08_0, TEST_SRF08_I2C, SRF08_DEFAULT_ADDR, TEST_SRF08_SPEED);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
printf("[Failed]");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
puts("[Ok]\n");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
int echo_number = srf08_get_distances(&srf08_0, range_array, TEST_NUM_ECHOS, TEST_MODE);
|
||||||
|
|
||||||
|
if (echo_number > 0) {
|
||||||
|
for (int i = 0; i < echo_number; i++) {
|
||||||
|
printf("stored distance = %i cm , echo%i\n", range_array[i], i + 1);
|
||||||
|
}
|
||||||
|
puts("--------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
puts("An error occured");
|
||||||
|
}
|
||||||
|
vtimer_usleep(SLEEP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user