Skip to content

Commit

Permalink
samples: sensor: thermometer: add trigger support to sample
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
danieldegrasse authored and nashif committed Jun 17, 2023
1 parent d382841 commit 7993e7d
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 18 deletions.
32 changes: 23 additions & 9 deletions samples/sensor/thermometer/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions samples/sensor/thermometer/boards/frdm_k22f.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Enable trigger support
CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD=y
24 changes: 24 additions & 0 deletions samples/sensor/thermometer/boards/frdm_k22f.overlay
Original file line number Diff line number Diff line change
@@ -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";
};
};
2 changes: 1 addition & 1 deletion samples/sensor/thermometer/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ tests:
harness: sensor
integration_platforms:
- nrf52840dk_nrf52840
platform_allow: nrf52840dk_nrf52840
platform_allow: nrf52840dk_nrf52840 frdm_k22f
98 changes: 90 additions & 8 deletions samples/sensor/thermometer/src/main.c
Original file line number Diff line number Diff line change
@@ -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
*/
Expand All @@ -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);

Expand All @@ -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;
}

Expand Down

0 comments on commit 7993e7d

Please sign in to comment.