1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Initial import of the updated srf02 driver with general i2c interface

This commit is contained in:
PeterKietzmann 2014-10-15 11:29:41 +02:00
parent eff4f30640
commit f207b114e4
8 changed files with 284 additions and 244 deletions

View File

@ -1,106 +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 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 <zkasmi@inf.fu-berlin.de>
*/
#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_ */

101
drivers/include/srf02.h Normal file
View File

@ -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 <zkasmi@inf.fu-berlin.de>
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
*/
#ifndef SRF02_H_
#define SRF02_H_
#include <stdint.h>
#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_ */

View File

@ -1 +1,3 @@
MODULE = srf02
include $(RIOTBASE)/Makefile.base

View File

@ -1,138 +0,0 @@
/*
* srf02-ultrasonic-sensor.c - Driver for the SRF02 ultrasonic.
*
* 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 SRF02 ultrasonic ranger.
* The connection between the MCU and the SRF08 is based on the
* i2c-interface.
*
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
* @version $Revision: 3856 $
*
* @note $Id: srf02-ultrasonic-sensor.c 3857 2013-09-24 17:39:33 kasmi $
*
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#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!!");
}

87
drivers/srf02/srf02.c Normal file
View File

@ -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 <zkasmi@inf.fu-berlin.de>
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
*
* @}
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#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;
}

View File

@ -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

View File

@ -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.

60
tests/driver_srf02/main.c Normal file
View File

@ -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 <peter.kietzmann@haw-hamburg.de>
*
* @}
*/
#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 <stdio.h>
#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);
}
}
}