mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #4804 from haukepetersen/opt_srf02_impltrigger
driver/srf02: expose trigger and read to API
This commit is contained in:
commit
ad149dcd68
@ -34,7 +34,12 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* @brief Default I2C address of SRF02 sensors
|
* @brief Default I2C address of SRF02 sensors
|
||||||
*/
|
*/
|
||||||
#define SRF02_DEFAULT_ADDR (0xe0)
|
#define SRF02_DEFAULT_ADDR (0xe0) /* 224 decimal */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The datasheet tells us, that ranging takes 70ms
|
||||||
|
*/
|
||||||
|
#define SRF02_RANGE_DELAY (70000U)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device descriptor for SRF02 sensors
|
* @brief Device descriptor for SRF02 sensors
|
||||||
@ -69,11 +74,38 @@ typedef enum {
|
|||||||
int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr);
|
int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the distance measured from the SRF02 ultrasonic sensor
|
* @brief Trigger a new measurement
|
||||||
|
*
|
||||||
|
* This function triggers a new ranging operation. After triggering this
|
||||||
|
* operation, you have to wait at least 70ms for the result to be ready.
|
||||||
*
|
*
|
||||||
* The result of the ranging operation is returned in inches, centimeters or
|
* The result of the ranging operation is returned in inches, centimeters or
|
||||||
* microseconds - depending on the given @p mode parameter.
|
* microseconds - depending on the given @p mode parameter.
|
||||||
*
|
*
|
||||||
|
* @param[in] dev device to trigger
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
void srf02_trigger(srf02_t *dev, srf02_mode_t mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the results of the last ranging operation
|
||||||
|
*
|
||||||
|
* @param[in] dev device to read from
|
||||||
|
*
|
||||||
|
* @return result of the last ranging operation, meaning depends on the mode
|
||||||
|
* parameter given to the srf02_trigger function
|
||||||
|
*/
|
||||||
|
uint16_t srf02_read(srf02_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the distance measured from the SRF02 ultrasonic sensor
|
||||||
|
*
|
||||||
|
* This function combines the srf02_trigger and the srf02_read functions for
|
||||||
|
* simplified usage in simple (single sensor) setups.
|
||||||
|
*
|
||||||
* @param[in] dev device descriptor of an SRF02 sensor
|
* @param[in] dev device descriptor of an SRF02 sensor
|
||||||
* @param[in] mode there are three real ranging modes, which return
|
* @param[in] mode there are three real ranging modes, which return
|
||||||
* the result in inches, centimeters or microseconds.
|
* the result in inches, centimeters or microseconds.
|
||||||
|
@ -31,11 +31,6 @@
|
|||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The datasheet tells us, that ranging takes 70ms
|
|
||||||
*/
|
|
||||||
#define RANGE_DELAY (70000U)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Per default use normal speed on the I2C bus
|
* @brief Per default use normal speed on the I2C bus
|
||||||
*/
|
*/
|
||||||
@ -78,6 +73,7 @@ int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr)
|
|||||||
/* try to read the software revision (read the CMD reg) from the device */
|
/* try to read the software revision (read the CMD reg) from the device */
|
||||||
i2c_read_reg(i2c, dev->addr, REG_CMD, &rev);
|
i2c_read_reg(i2c, dev->addr, REG_CMD, &rev);
|
||||||
if (rev == 0 || rev == 255) {
|
if (rev == 0 || rev == 255) {
|
||||||
|
i2c_release(dev->i2c);
|
||||||
DEBUG("[srf02] error reading the devices software revision\n");
|
DEBUG("[srf02] error reading the devices software revision\n");
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@ -90,18 +86,18 @@ int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t srf02_get_distance(srf02_t *dev, srf02_mode_t mode)
|
void srf02_trigger(srf02_t *dev, srf02_mode_t mode)
|
||||||
{
|
{
|
||||||
char res[2];
|
|
||||||
|
|
||||||
/* trigger a new measurement by writing the mode to the CMD register */
|
/* trigger a new measurement by writing the mode to the CMD register */
|
||||||
DEBUG("[srf02] trigger new reading\n");
|
DEBUG("[srf02] trigger new reading\n");
|
||||||
i2c_acquire(dev->i2c);
|
i2c_acquire(dev->i2c);
|
||||||
i2c_write_reg(dev->i2c, dev->addr, REG_CMD, mode);
|
i2c_write_reg(dev->i2c, dev->addr, REG_CMD, mode);
|
||||||
i2c_release(dev->i2c);
|
i2c_release(dev->i2c);
|
||||||
|
}
|
||||||
|
|
||||||
/* give the sensor the required time for sampling */
|
uint16_t srf02_read(srf02_t *dev)
|
||||||
xtimer_usleep(RANGE_DELAY);
|
{
|
||||||
|
char res[2];
|
||||||
|
|
||||||
/* read the results */
|
/* read the results */
|
||||||
i2c_acquire(dev->i2c);
|
i2c_acquire(dev->i2c);
|
||||||
@ -113,6 +109,16 @@ uint16_t srf02_get_distance(srf02_t *dev, srf02_mode_t mode)
|
|||||||
return ((((uint16_t)res[0]) << 8) | (res[1] & 0xff));
|
return ((((uint16_t)res[0]) << 8) | (res[1] & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t srf02_get_distance(srf02_t *dev, srf02_mode_t mode)
|
||||||
|
{
|
||||||
|
/* trigger a new reading */
|
||||||
|
srf02_trigger(dev, mode);
|
||||||
|
/* give the sensor the required time for sampling */
|
||||||
|
xtimer_usleep(SRF02_RANGE_DELAY);
|
||||||
|
/* get the results */
|
||||||
|
return srf02_read(dev);
|
||||||
|
}
|
||||||
|
|
||||||
void srf02_set_addr(srf02_t *dev, uint8_t new_addr)
|
void srf02_set_addr(srf02_t *dev, uint8_t new_addr)
|
||||||
{
|
{
|
||||||
/* get access to the bus */
|
/* get access to the bus */
|
||||||
|
@ -2,9 +2,50 @@
|
|||||||
This is a manual test application for the SRF02 ultrasonic ranger driver.
|
This is a manual test application for the SRF02 ultrasonic ranger driver.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
First you always need to initialize the sensor using the `init` shell command
|
||||||
|
and the devices address in right-aligned, decimal format (as specified in the
|
||||||
|
reference manual), e.g.: `init 224`.
|
||||||
|
|
||||||
|
If successful (the shell will tell you...), you can sample distance data from
|
||||||
|
the device, either once (`shoot`) or continuously every second (`sample`).
|
||||||
|
|
||||||
After initialization, the sensor value is read periodically and printed to the STDOUT.
|
This test application also allows to re-program the I2C address of SRF02
|
||||||
|
devices. For this initialize the device with its current address and then change
|
||||||
|
to the new address using the `addr` shell command (e.g. `addr 228`). After
|
||||||
|
calling the `addr` command, this application will automatically re-initialize
|
||||||
|
the device with the new address, so it is usable right away. Refer to the
|
||||||
|
datasheet for more information on usable addresses.
|
||||||
|
|
||||||
To verify the seen value you can focus the sensor against any reflecting object and vary the distance to
|
The following sequence shows how to re-program a device. The initial address is
|
||||||
see the value changing.
|
`224`, the new address after the sequence is `228`:
|
||||||
|
|
||||||
|
```
|
||||||
|
2016-03-21 15:53:34,049 - INFO # > init 224
|
||||||
|
2016-03-21 15:53:34,054 - INFO # Initializing SRF02 sensor at I2C_DEV(0), address is 224
|
||||||
|
2016-03-21 15:53:34,079 - INFO # ... [Ok]
|
||||||
|
2016-03-21 15:53:34,079 - INFO #
|
||||||
|
shoot
|
||||||
|
2016-03-21 15:53:37,339 - INFO # > shoot
|
||||||
|
2016-03-21 15:53:37,411 - INFO # distance = 94 cm
|
||||||
|
addr 228
|
||||||
|
2016-03-21 15:53:41,468 - INFO # > addr 228
|
||||||
|
2016-03-21 15:53:41,472 - INFO # Set address to 228
|
||||||
|
shoot
|
||||||
|
2016-03-21 15:53:42,454 - INFO # > shoot
|
||||||
|
2016-03-21 15:53:42,527 - INFO # distance = 94 cm
|
||||||
|
init 224
|
||||||
|
2016-03-21 15:53:48,933 - INFO # > init 224
|
||||||
|
2016-03-21 15:53:48,938 - INFO # Initializing SRF02 sensor at I2C_DEV(0), address is 224
|
||||||
|
2016-03-21 15:53:48,962 - INFO # ... [Failed]
|
||||||
|
shoot
|
||||||
|
2016-03-21 15:53:50,568 - INFO # > shoot
|
||||||
|
2016-03-21 15:53:50,641 - INFO # distance = 29703 cm
|
||||||
|
init 228
|
||||||
|
2016-03-21 15:53:53,084 - INFO # > init 228
|
||||||
|
2016-03-21 15:53:53,089 - INFO # Initializing SRF02 sensor at I2C_DEV(0), address is 228
|
||||||
|
2016-03-21 15:53:53,113 - INFO # ... [Ok]
|
||||||
|
2016-03-21 15:53:53,113 - INFO #
|
||||||
|
shoot
|
||||||
|
2016-03-21 15:53:54,201 - INFO # > shoot
|
||||||
|
2016-03-21 15:53:54,274 - INFO # distance = 94 cm
|
||||||
|
```
|
||||||
|
@ -40,15 +40,10 @@
|
|||||||
|
|
||||||
static srf02_t dev;
|
static srf02_t dev;
|
||||||
|
|
||||||
static void sample_loop(void)
|
static void sample(void)
|
||||||
{
|
{
|
||||||
uint32_t wakeup = xtimer_now();
|
uint16_t distance = srf02_get_distance(&dev, TEST_MODE);
|
||||||
|
printf("distance = %3i cm\n", distance);
|
||||||
while(1) {
|
|
||||||
uint16_t distance = srf02_get_distance(&dev, TEST_MODE);
|
|
||||||
printf("distance = %3i cm\n", distance);
|
|
||||||
xtimer_usleep_until(&wakeup, SAMPLE_PERIOD);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_init(int argc, char **argv)
|
static int cmd_init(int argc, char **argv)
|
||||||
@ -62,7 +57,7 @@ static int cmd_init(int argc, char **argv)
|
|||||||
|
|
||||||
uint8_t addr = (uint8_t)atoi(argv[1]);
|
uint8_t addr = (uint8_t)atoi(argv[1]);
|
||||||
|
|
||||||
printf("Initializing SRF02 sensor at I2C_DEV(%i), address is 0x%02x\n... ",
|
printf("Initializing SRF02 sensor at I2C_DEV(%i), address is %i\n... ",
|
||||||
TEST_SRF02_I2C, (int)addr);
|
TEST_SRF02_I2C, (int)addr);
|
||||||
res = srf02_init(&dev, TEST_SRF02_I2C, addr);
|
res = srf02_init(&dev, TEST_SRF02_I2C, addr);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
@ -79,8 +74,22 @@ static int cmd_sample(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
sample_loop();
|
uint32_t wakeup = xtimer_now();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
sample();
|
||||||
|
xtimer_usleep_until(&wakeup, SAMPLE_PERIOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_shoot(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
sample();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,13 +104,14 @@ static int cmd_set_addr(int argc, char **argv)
|
|||||||
|
|
||||||
new_addr = (uint8_t)atoi(argv[1]);
|
new_addr = (uint8_t)atoi(argv[1]);
|
||||||
srf02_set_addr(&dev, new_addr);
|
srf02_set_addr(&dev, new_addr);
|
||||||
printf("Set address to %i (0x%02x)\n", (int)new_addr, (int)new_addr);
|
printf("Set address to %i\n", (int)new_addr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const shell_command_t shell_commands[] = {
|
static const shell_command_t shell_commands[] = {
|
||||||
{ "init", "initialize a device", cmd_init },
|
{ "init", "initialize a device", cmd_init },
|
||||||
{ "sample", "start sampling", cmd_sample },
|
{ "sample", "start sampling", cmd_sample },
|
||||||
|
{ "shoot", "get a single sample", cmd_shoot },
|
||||||
{ "addr", "reprogram the devices address", cmd_set_addr },
|
{ "addr", "reprogram the devices address", cmd_set_addr },
|
||||||
{ NULL, NULL, NULL }
|
{ NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
@ -109,8 +119,15 @@ static const shell_command_t shell_commands[] = {
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
puts("\nSRF02 Ultrasonic Range Sensor Test\n");
|
puts("\nSRF02 Ultrasonic Range Sensor Test\n");
|
||||||
puts("This test will sample the sensor once per second and display the\n"
|
puts("Use the following flow to test your device/setup. First you need to\n"
|
||||||
"result\n");
|
"initialize your device (e.g. 'init 224'). Next you can sample your \n"
|
||||||
|
"device continuously ('sample'), or get one value ('shoot').\n\n"
|
||||||
|
"This application let's you also reprogram your device's I2C"
|
||||||
|
"address:\n"
|
||||||
|
" 1. initialize your device -> e.g. 'init 224'\n"
|
||||||
|
" 2. specify the new address -> e.g.'addr 228'\n"
|
||||||
|
"The device will be programmed with the new address and it is\n"
|
||||||
|
"re-initialized with the new address, so you can use it right away\n");
|
||||||
|
|
||||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
Loading…
Reference in New Issue
Block a user