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

tests/drivers_vl6180x: add test app for VL6180X driver

This commit is contained in:
Gunar Schorcht 2021-11-28 12:19:30 +01:00
parent 51bf9d4d7d
commit add625aa84
3 changed files with 326 additions and 0 deletions

View File

@ -0,0 +1,7 @@
include ../Makefile.tests_common
USEMODULE += vl6180x_rng
USEMODULE += vl6180x_als
USEMODULE += ztimer_sec
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,55 @@
# Test application for ST VL6180X Ranging and Ambient Light Sensing (ALS) module
## About
The test application demonstrates the use of different functions of
the ST VL6180X sensor driver depending on used pseudomodules:
Module Name | Functionality used
:------------------|:-------------------------------------------
`vl6180x_rng` | Periodic range measurements enabled
`vl6180x_als` | Periodic ambient light sensing (ALS) enabled
`vl6180x_irq` | Data ready interrupt enabled for range and ALS measurements
`vl6180x_config` | Event interrupt enabled and configured for range measurements
`vl6180x_shutdown` | Power-down and power-up functions used
## Usage
To compile and execute the test application, use command:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make BOARD=... -C tests/driver_vl6180x flash term
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By default, the `vl6180x_rng` and `vl6180x_als` modules are enabled.
This is, the standard variant of the test application performs periodic
range and ALS measurements.
To use data ready interrupts for range and ALS measurements instead of
polling for new data, the `vl6180x_irq` module has to be used:
The MCU GPIO pin connected with the interrupt signal GPIO1 of the sensor
has to be defined by the configuration parameter `VL6180X_PARAM_PIN_INT`,
for example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CFLAGS="-DVL6180X_PARAM_INT_PIN=\(GPIO_PIN\(0,5\)\)" \
USEMODULE=vl6180x_irq \
make BOARD=... -C tests/driver_vl6180x flash term
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the module `vl6180x_config` is used additionally, the event interrupt
is configured and used for range measurements:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CFLAGS="-DVL6180X_PARAM_INT_PIN=\(GPIO_PIN\(0,5\)\)" \
USEMODULE='vl6180x_irq vl6180x_config'\
make BOARD=... -C tests/driver_vl6180x flash term
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To test the power-down and power-up functionality, the `vl6180x_shutdown`
module has to be used. The MCU GPIO pin connected with the signal GPIO0/CE
of the sensor has to be defined by configuration parameter
`VL6180X_PARAM_PIN_SHUTDOWN`, for example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CFLAGS="-VL6180X_PARAM_SHUTDOWN_PIN=\(GPIO_PIN\(0,6\)\)" \
USEMODULE=vl6180x_shutdown \
make BOARD=... -C tests/driver_vl6180x flash term
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

264
tests/driver_vl6180x/main.c Normal file
View File

@ -0,0 +1,264 @@
/*
* Copyright (C) 2021 Gunar Schorcht
*
* 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
* @brief Test application for ST VL6180X Ranging and Ambient Light Sensing (ALS) module
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
*
* ## About
*
* The test application demonstrates the use of different functions of
* the ST VL6180X sensor driver depending on used pseudomodules:
*
* Module Name | Functionality used
* :------------------|:-------------------------------------------
* `vl6180x_rng` | Periodic range measurements enabled
* `vl6180x_als` | Periodic ambient light sensing (ALS) enabled
* `vl6180x_irq` | Data ready interrupt enabled for range and ALS measurements
* `vl6180x_config` | Event interrupt enabled and configured for range measurements
* `vl6180x_shutdown` | Power-down and power-up functions used
*
* ## Usage
*
* To compile and execute the test application, use command:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* make BOARD=... -C tests/driver_vl6180x flash term
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* By default, the `vl6180x_rng` and `vl6180x_als` modules are enabled.
* This is, the standard variant of the test application performs periodic
* range and ALS measurements.
*
* To use data ready interrupts for range and ALS measurements instead of
* polling for new data, the `vl6180x_irq` module has to be used:
*
* The MCU GPIO pin connected with the interrupt signal GPIO1 of the sensor
* has to be defined by the configuration parameter `VL6180X_PARAM_PIN_INT`,
* for example:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* CFLAGS="-DVL6180X_PARAM_INT_PIN=\(GPIO_PIN\(0,5\)\)" \
* USEMODULE=vl6180x_irq \
* make BOARD=... -C tests/driver_vl6180x flash term
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* If the module `vl6180x_config` is used additionally, the event interrupt
* is configured and used for range measurements:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* CFLAGS="-DVL6180X_PARAM_INT_PIN=\(GPIO_PIN\(0,5\)\)" \
* USEMODULE='vl6180x_irq vl6180x_config'\
* make BOARD=... -C tests/driver_vl6180x flash term
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To test the power-down and power-up functionality, the `vl6180x_shutdown`
* module has to be used. The MCU GPIO pin connected with the signal GPIO0/CE
* of the sensor has to be defined by configuration parameter
* `VL6180X_PARAM_PIN_SHUTDOWN`, for example:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* CFLAGS="-VL6180X_PARAM_SHUTDOWN_PIN=\(GPIO_PIN\(0,6\)\)" \
* USEMODULE=vl6180x_shutdown \
* make BOARD=... -C tests/driver_vl6180x flash term
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include "thread.h"
#include "ztimer.h"
#include "vl6180x.h"
#include "vl6180x_params.h"
#if IS_USED(MODULE_VL6180X_IRQ)
#if IS_USED(MODULE_VL6180X_RNG)
static const char *rng_errors[] = {
"No error", /**< VL6180X_RNG_OK */
"VCSEL continuity Test", /**< VL6180X_RNG_VCSEL_CONT_TEST */
"VCSEL watchdog test", /**< VL6180X_RNG_VCSEL_WD_TEST */
"VCSEL watchdog", /**< VL6180X_RNG_VCSEL_WD */
"PLL1 lock", /**< VL6180X_RNG_PLL1_LOCK */
"PLL2 lock", /**< VL6180X_RNG_PLL2_LOCK */
"Early convergence estimate", /**< VL6180X_RNG_EARLY_CONV_EST */
"Maximum convergence time reached", /**< VL6180X_RNG_MAX_CONV */
"No target, ignore", /**< VL6180X_RNG_NO_TARGET */
"Unknown",
"Unknown",
"Maximum SNR reached", /**< VL6180X_RNG_MAX_SNR */
"Raw ranging algorithm underflow", /**< VL6180X_RNG_RAW_ALGO_UNDERFLOW */
"Raw ranging algorithn overflow", /**< VL6180X_RNG_RAW_ALGO_OVERFLOW */
"Ranging algorithm underflow", /**< VL6180X_RNG_ALGO_UNDERFLOW */
"Ranging algorithm overflow", /**< VL6180X_RNG_ALGO_OVERFLOW */
};
#endif
#if IS_USED(MODULE_VL6180X_ALS)
static const char *als_errors[] = {
"No error", /**< VL6180X_ALS_OK */
"ALS measurement overflow", /**< VL6180X_ALS_OVERFLOW */
"ALS measurement underflow", /**< VL6180X_ALS_UNDERFLOW */
};
#endif
#endif /* IS_USED(MODULE_VL6180X_IRQ) */
int main(void)
{
/* Initialize the sensor */
vl6180x_t dev;
#if IS_USED(MODULE_VL6180X_RNG)
uint8_t rng;
#endif
#if IS_USED(MODULE_VL6180X_ALS)
uint16_t als;
uint16_t lux;
#endif
/* initialize the sensor */
puts("VL6180X Time-of-Flight distance sensor\n");
puts("Initializing VL6180X sensor");
if (vl6180x_init(&dev, &vl6180x_params[0]) == VL6180X_OK) {
puts("[OK]");
}
else {
puts("[Failed]");
return 1;
}
#if IS_USED(MODULE_VL6180X_SHUTDOWN)
unsigned count = 0;
#endif
#if IS_USED(MODULE_VL6180X_IRQ) && IS_USED(MODULE_VL6180X_CONFIG)
vl6180x_int_config_t mode;
vl6180x_int_thresh_t thresh;
#if IS_USED(MODULE_VL6180X_RNG)
/* interrupt when distance is less than 30 mm or greater than 100 mm */
mode.rng_int = VL6180X_INT_OUT;
thresh.rng_low = 30;
thresh.rng_high = 100;
#endif /* IS_USED(MODULE_VL6180X_RNG) */
#if IS_USED(MODULE_VL6180X_ALS)
/* interrupts when ALS data are ready */
mode.als_int = VL6180X_INT_DRDY;
#endif /* IS_USED(MODULE_VL6180X_RNG) */
vl6180x_int_config(&dev, thresh);
vl6180x_int_enable(&dev, mode);
#endif /* IS_USED(MODULE_VL6180X_CONFIG) && IS_USED(MODULE_VL6180X_IRQ) */
while (1) {
#if IS_USED(MODULE_VL6180X_IRQ)
vl6180x_int_config_t src;
vl6180x_int_wait(&dev, &src);
#if IS_USED(MODULE_VL6180X_RNG)
if (src.rng_int == VL6180X_INT_DRDY) {
int status = vl6180x_rng_read(&dev, &rng);
switch (status) {
case VL6180X_RNG_OK:
printf("RNG: %u [mm]\n", rng);
break;
case -VL6180X_ERROR_RNG:
printf("RNG: %s\n", rng_errors[vl6180x_rng_status(&dev)]);
break;
default:
printf("RNG: error %d\n", status);
}
puts("+-----------------------------------------+");
}
else if (src.rng_int == VL6180X_INT_OUT) {
puts("RNG: out of window");
}
else if (src.rng_int == VL6180X_INT_RNG_LOW) {
puts("RNG: low level");
}
else if (src.rng_int == VL6180X_INT_RNG_HIGH) {
puts("RNG: high level");
}
#endif /* IS_USED(MODULE_VL6180X_RNG) */
#if IS_USED(MODULE_VL6180X_ALS)
if (src.als_int == VL6180X_INT_DRDY) {
int status = vl6180x_als_read(&dev, &als, &lux);
switch (status) {
case VL6180X_OK:
printf("ALS: %u [cnts], %u [lux]\n", als, lux);
break;
case -VL6180X_ERROR_ALS:
printf("ALS: %s\n", als_errors[vl6180x_als_status(&dev)]);
break;
default:
printf("ALS: error %d\n", status);
}
}
else if (src.als_int == VL6180X_INT_OUT) {
puts("ALS: out of window");
}
else if (src.als_int == VL6180X_INT_LOW) {
puts("ALS: low level");
}
else if (src.als_int == VL6180X_INT_HIGH) {
puts("ALS: high level");
}
#endif /* IS_USED(MODULE_VL6180X_ALS) */
#else /* IS_USED(MODULE_VL6180X_IRQ) */
/* just wait 250 ms if module vl6180x_basic is used */
ztimer_sleep(ZTIMER_MSEC, 250);
#if IS_USED(MODULE_VL6180X_ALS)
if (vl6180x_als_data_ready(&dev) == VL6180X_OK &&
vl6180x_als_read(&dev, &als, &lux) == VL6180X_OK) {
printf("ALS: %u [cnts], %u [lux]\n", als, lux);
}
#endif /* IS_USED(MODULE_VL6180X_ALS) */
#if IS_USED(MODULE_VL6180X_RNG)
if (vl6180x_rng_data_ready(&dev) == VL6180X_OK) {
if (vl6180x_rng_read(&dev, &rng) == VL6180X_OK) {
printf("RNG: %u [mm]\n", rng);
}
else {
puts("RNG: inf");
}
puts("+-----------------------------------------+");
}
#endif /* IS_USED(MODULE_VL6180X_RNG) */
#endif /* IS_USED(MODULE_VL6180X_IRQ) */
#if IS_USED(MODULE_VL6180X_SHUTDOWN)
/*
* if shutdown pin is defined, the sensor is powered down and up
* again after 5 seconds every 50 cycles
*/
count++;
if ((count % 50) == 0) {
vl6180x_power_down(&dev);
puts("Sensor powered down");
ztimer_sleep(ZTIMER_SEC, 5);
vl6180x_power_up(&dev);
puts("Sensor powered up");
}
#endif /* IS_USED(MODULE_VL6180X_SHUTDOWN) */
}
return 0;
}