samples: sensor: Add VCNL4040 sample

Add sample to show usage of VCNL4040 sensor driver

Signed-off-by: Richard Osterloh <richard.osterloh@gmail.com>
This commit is contained in:
Richard Osterloh 2020-08-27 15:22:35 +01:00 committed by Maureen Helm
commit e917c6c0bc
6 changed files with 248 additions and 0 deletions

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
project(vcnl4040)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,57 @@
.. _vcnl4040_sample:
VCNL4040: proximity and ambient light sensor
############################################
Overview
********
This sample periodically measures proximity and light for
5 sec in the interval of 300msec in polling mode. Then threshold trigger mode
is enabled with the high threshold value of 127 and data is fetched based
on interrupt. The result is displayed on the console.
Requirements
************
This sample uses the VCNL4040 sensor controlled using the I2C interface.
Connect sensor INT for interrupt to Feather D5 pin on the Adafruit STM32F405 Feather.
References
**********
- VCNL4040: https://www.vishay.com/docs/84274/vcnl4040.pdf
Building and Running
********************
This project outputs sensor data to the console. It requires a VCNL4040
sensor to be connected to the desired board.
.. zephyr-app-commands::
:app: samples/sensor/vcnl4040/
:goals: build flash
Sample Output
=============
.. code-block:: console
get device vcnl4040
Testing the polling mode.
Proximity: 31
Light (lux): 288
<repeats for 5sec every 300ms>
Polling mode test finished.
Testing the trigger mode.
Testing proximity trigger.
...
Triggered.
Proximity: 122
<repeats whenever triggered for 5sec>
Threshold trigger test finished.
Trigger mode test finished.

View file

@ -0,0 +1,19 @@
/*
* Copyright (c) 2020, Richard Osterloh
*
* SPDX-License-Identifier: Apache-2.0
*/
&feather_i2c {
vcnl4040@60 {
compatible = "vishay,vcnl4040";
reg = <0x60>;
label = "VCNL4040";
int-gpios = <&feather_header 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
led-current = <200>;
led-duty-cycle = <320>;
proximity-it = "8";
proximity-trigger = "close";
als-it = <640>;
};
};

View file

@ -0,0 +1,7 @@
CONFIG_PRINTK=y
CONFIG_GPIO=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_VCNL4040=y
CONFIG_VCNL4040_TRIGGER_GLOBAL_THREAD=y
CONFIG_VCNL4040_ENABLE_ALS=y

View file

@ -0,0 +1,9 @@
sample:
name: VCNL4040 Sensor Sample
tests:
sample.sensor.vcnl4040:
harness: sensor
platform_allow: adafruit_feather_stm32f405
tags: sensors
depends_on: i2c gpio
filter: dt_compat_enabled("vishay,vcnl4040")

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2020 Richard Osterloh
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <sys/printk.h>
#include <sys_clock.h>
#include <stdio.h>
#include <device.h>
#include <drivers/sensor.h>
#include <drivers/i2c.h>
#define MAX_TEST_TIME 5000
#define SLEEPTIME 300
static void print_proxy_data(const struct device *dev)
{
struct sensor_value pdata;
if (sensor_channel_get(dev, SENSOR_CHAN_PROX, &pdata) < 0) {
printf("Cannot read proximity data.\n");
return;
}
printf("Proximity: %d\n", (uint16_t) pdata.val1);
}
#if defined(CONFIG_VCNL4040_ENABLE_ALS)
static void print_als_data(const struct device *dev)
{
struct sensor_value val;
if (sensor_channel_get(dev, SENSOR_CHAN_LIGHT, &val) < 0) {
printf("ALS read error.\n");
return;
}
printf("Light (lux): %d\n", (uint16_t) val.val1);
}
#endif
static void test_polling_mode(const struct device *dev)
{
int32_t remaining_test_time = MAX_TEST_TIME;
do {
if (sensor_sample_fetch(dev) < 0) {
printf("sample update error.\n");
} else {
print_proxy_data(dev);
#if defined(CONFIG_VCNL4040_ENABLE_ALS)
print_als_data(dev);
#endif
}
/* wait a while */
k_sleep(K_MSEC(SLEEPTIME));
remaining_test_time -= SLEEPTIME;
} while (remaining_test_time > 0);
}
#if defined(CONFIG_VCNL4040_TRIGGER)
static void trigger_handler(const struct device *dev,
struct sensor_trigger *trig)
{
switch (trig->type) {
case SENSOR_TRIG_THRESHOLD:
printf("Triggered.\n");
if (sensor_sample_fetch(dev) < 0) {
printf("sample update error.\n");
} else {
print_proxy_data(dev);
}
return;
default:
printf("trigger handler: unknown trigger type.\n");
return;
}
}
#endif
static void test_trigger_mode(const struct device *dev)
{
#if defined(CONFIG_VCNL4040_TRIGGER)
struct sensor_trigger trig;
struct sensor_value attr;
printf("Testing proximity trigger.\n");
attr.val1 = 127;
attr.val2 = 0;
if (sensor_attr_set(dev, SENSOR_CHAN_PROX,
SENSOR_ATTR_UPPER_THRESH, &attr) < 0) {
printf("cannot set proximity high threshold.\n");
return;
}
attr.val1 = 122;
if (sensor_attr_set(dev, SENSOR_CHAN_PROX,
SENSOR_ATTR_LOWER_THRESH, &attr) < 0) {
printf("cannot set proximity low threshold.\n");
return;
}
trig.type = SENSOR_TRIG_THRESHOLD;
trig.chan = SENSOR_CHAN_PROX;
if (sensor_trigger_set(dev, &trig, trigger_handler) < 0) {
printf("cannot set trigger.\n");
return;
}
k_sleep(K_MSEC(MAX_TEST_TIME));
if (sensor_trigger_set(dev, &trig, NULL) < 0) {
printf("cannot clear trigger.\n");
return;
}
printf("Threshold trigger test finished.\n");
#endif
}
void main(void)
{
const struct device *vcnl;
printf("get device vcnl4040\n");
vcnl = device_get_binding(DT_LABEL(DT_INST(0, vishay_vcnl4040)));
if (!vcnl) {
printf("Device not found.\n");
return;
}
printf("Testing the polling mode.\n");
test_polling_mode(vcnl);
printf("Polling mode test finished.\n");
printf("Testing the trigger mode.\n");
test_trigger_mode(vcnl);
printf("Trigger mode test finished.\n");
}