samples: sensor: thermometer: add trigger support to sample

Add optional trigger support to sample. If the selected temperature
sensor supports triggering using the AMBIENT_TEMP channel, then
temperature thresholds will be set for +0.5 and +1.5 degrees celsius
above ambient temperature. Sample overlays are provided for the
FRDM_K22F board to demonstrate enabling this feature.

Signed-off-by: Daniel DeGrasse <daniel@degrasse.com>
This commit is contained in:
Daniel DeGrasse 2023-05-14 14:13:34 -05:00 committed by Anas Nashif
parent d3828418c0
commit 7993e7d1b0
5 changed files with 140 additions and 18 deletions

View file

@ -39,17 +39,31 @@ alias named ``ambient-temp0`` to link to the node. See the overlay used for the
``nrf52840dk_nrf52840`` board within this sample:
``boards/nrf52840dk_nrf52840.overlay``
Temperature Alert
=================
If the attached sensor supports alerts when the temperature drifts above or
below a threshold, the sample will enable the sensor's trigger functionality.
This will require the sensor's TRIGGER KConfig setting to be enabled. An
example of this setup is provided for the ``frdm_k22f`` board, using
``boards/frdm_k22f.conf``.
Sample Output
=============
.. code-block:: console
*** Booting Zephyr OS build zephyr-v3.3.0-1205-g118f73e12a70 ***
Thermometer Example (arm)
Temperature device is 0x6150, name is mcp9700a
Temperature is 24.0°C
Temperature is 24.1°C
Temperature is 24.2°C
Temperature is 24.1°C
Temperature is 24.0°C
Temperature is 24.1°C
*** Booting Zephyr OS build zephyr-v3.3.0-2354-gb4f4bd1f1c22 ***
Thermometer Example (arm)
Temperature device is 0x525c, name is tcn75a@48
Set temperature lower limit to 25.5°C
Set temperature upper limit to 26.5°C
Enabled sensor threshold triggers
Temperature is 25.0°C
Temperature is 25.0°C
Temperature is 25.0°C
Temperature is 25.0°C
Temperature is 25.5°C
Temperature above threshold: 26.5°C
Temperature is 26.5°C

View file

@ -0,0 +1,2 @@
# Enable trigger support
CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD=y

View file

@ -0,0 +1,24 @@
/*
* Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
aliases {
ambient-temp0 = &temp_sensor;
};
};
/*
* Note- TCN75A is not present on the FRDM-K22F eval board, and must be
* wired to i2c0 and PTC2 externally
*/
&i2c0 {
temp_sensor: tcn75a@48 {
reg = <0x48>;
compatible = "microchip,tcn75a";
alert-gpios = <&gpioc 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
resolution = "10-bit";
};
};

View file

@ -6,4 +6,4 @@ tests:
harness: sensor
integration_platforms:
- nrf52840dk_nrf52840
platform_allow: nrf52840dk_nrf52840
platform_allow: nrf52840dk_nrf52840 frdm_k22f

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2016 ARM Ltd.
* Copyright (c) 2023 FTP Technologies
* Copyright (c) 2023 Daniel DeGrasse <daniel@degrasse.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,11 +10,58 @@
#include <zephyr/drivers/sensor.h>
#include <stdio.h>
static double high_temp;
static double low_temp;
int read_temperature(const struct device *dev, struct sensor_value *val)
{
int ret;
ret = sensor_sample_fetch_chan(dev, SENSOR_CHAN_AMBIENT_TEMP);
if (ret < 0) {
printf("Could not fetch temperature: %d\n", ret);
return ret;
}
ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, val);
if (ret < 0) {
printf("Could not get temperature: %d\n", ret);
}
return ret;
}
void temp_alert_handler(const struct device *dev, const struct sensor_trigger *trig)
{
int ret;
struct sensor_value value;
double temp;
/* Read sensor value */
ret = read_temperature(dev, &value);
if (ret < 0) {
printf("Reading temperature failed: %d\n", ret);
return;
}
temp = sensor_value_to_double(&value);
if (temp <= low_temp) {
printf("Temperature below threshold: %0.1f°C\n", temp);
} else if (temp >= high_temp) {
printf("Temperature above threshold: %0.1f°C\n", temp);
} else {
printf("Error: temperature alert triggered without valid condition\n");
}
}
int main(void)
{
const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(ambient_temp0));
struct sensor_value value;
double temp;
int ret;
const struct sensor_trigger trig = {
.chan = SENSOR_CHAN_AMBIENT_TEMP,
.type = SENSOR_TRIG_THRESHOLD,
};
printf("Thermometer Example (%s)\n", CONFIG_ARCH);
@ -24,16 +72,50 @@ int main(void)
printf("Temperature device is %p, name is %s\n", dev, dev->name);
while (1) {
ret = sensor_sample_fetch(dev);
if (ret != 0) {
printf("Sensor fetch failed: %d\n", ret);
break;
}
/* First, fetch a sensor sample to use for sensor thresholds */
ret = read_temperature(dev, &value);
if (ret != 0) {
printf("Failed to read temperature: %d\n", ret);
return ret;
}
temp = sensor_value_to_double(&value);
ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &value);
/* Set thresholds to +0.5 and +1.5 °C from ambient */
low_temp = temp + 0.5;
ret = sensor_value_from_double(&value, low_temp);
if (ret != 0) {
printf("Failed to convert low threshold to sensor value: %d\n", ret);
return ret;
}
ret = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP,
SENSOR_ATTR_LOWER_THRESH, &value);
if (ret == 0) {
/* This sensor supports threshold triggers */
printf("Set temperature lower limit to %0.1f°C\n", low_temp);
}
high_temp = temp + 1.5;
ret = sensor_value_from_double(&value, high_temp);
if (ret != 0) {
printf("Failed to convert low threshold to sensor value: %d\n", ret);
return ret;
}
ret = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP,
SENSOR_ATTR_UPPER_THRESH, &value);
if (ret == 0) {
/* This sensor supports threshold triggers */
printf("Set temperature upper limit to %0.1f°C\n", high_temp);
}
ret = sensor_trigger_set(dev, &trig, temp_alert_handler);
if (ret == 0) {
printf("Enabled sensor threshold triggers\n");
}
while (1) {
ret = read_temperature(dev, &value);
if (ret != 0) {
printf("Sensor get failed: %d\n", ret);
printf("Failed to read temperature: %d\n", ret);
break;
}