Browse Source

Merge pull request #4804 from haukepetersen/opt_srf02_impltrigger

driver/srf02: expose trigger and read to API
pr/gpio
Peter Kietzmann 7 years ago
parent
commit
ad149dcd68
  1. 36
      drivers/include/srf02.h
  2. 26
      drivers/srf02/srf02.c
  3. 47
      tests/driver_srf02/README.md
  4. 43
      tests/driver_srf02/main.c

36
drivers/include/srf02.h

@ -34,7 +34,12 @@ extern "C" {
/**
* @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
@ -69,11 +74,38 @@ typedef enum {
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
* 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] mode there are three real ranging modes, which return
* the result in inches, centimeters or microseconds.

26
drivers/srf02/srf02.c

@ -31,11 +31,6 @@
#define ENABLE_DEBUG (0)
#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
*/
@ -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 */
i2c_read_reg(i2c, dev->addr, REG_CMD, &rev);
if (rev == 0 || rev == 255) {
i2c_release(dev->i2c);
DEBUG("[srf02] error reading the devices software revision\n");
return -1;
} else {
@ -90,18 +86,18 @@ int srf02_init(srf02_t *dev, i2c_t i2c, uint8_t addr)
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 */
DEBUG("[srf02] trigger new reading\n");
i2c_acquire(dev->i2c);
i2c_write_reg(dev->i2c, dev->addr, REG_CMD, mode);
i2c_release(dev->i2c);
}
/* give the sensor the required time for sampling */
xtimer_usleep(RANGE_DELAY);
uint16_t srf02_read(srf02_t *dev)
{
char res[2];
/* read the results */
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));
}
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)
{
/* get access to the bus */

47
tests/driver_srf02/README.md

@ -2,9 +2,50 @@
This is a manual test application for the SRF02 ultrasonic ranger driver.
# 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
see the value changing.
The following sequence shows how to re-program a device. The initial address is
`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
```

43
tests/driver_srf02/main.c

@ -40,15 +40,10 @@
static srf02_t dev;
static void sample_loop(void)
static void sample(void)
{
uint32_t wakeup = xtimer_now();
while(1) {
uint16_t distance = srf02_get_distance(&dev, TEST_MODE);
printf("distance = %3i cm\n", distance);
xtimer_usleep_until(&wakeup, SAMPLE_PERIOD);
}
uint16_t distance = srf02_get_distance(&dev, TEST_MODE);
printf("distance = %3i cm\n", distance);
}
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]);
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);
res = srf02_init(&dev, TEST_SRF02_I2C, addr);
if (res < 0) {
@ -79,8 +74,22 @@ static int cmd_sample(int argc, char **argv)
{
(void)argc;
(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;
}
@ -95,13 +104,14 @@ static int cmd_set_addr(int argc, char **argv)
new_addr = (uint8_t)atoi(argv[1]);
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;
}
static const shell_command_t shell_commands[] = {
{ "init", "initialize a device", cmd_init },
{ "sample", "start sampling", cmd_sample },
{ "shoot", "get a single sample", cmd_shoot },
{ "addr", "reprogram the devices address", cmd_set_addr },
{ NULL, NULL, NULL }
};
@ -109,8 +119,15 @@ static const shell_command_t shell_commands[] = {
int main(void)
{
puts("\nSRF02 Ultrasonic Range Sensor Test\n");
puts("This test will sample the sensor once per second and display the\n"
"result\n");
puts("Use the following flow to test your device/setup. First you need to\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];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);

Loading…
Cancel
Save