From 3d2dca98992b77b747803248cf8527f9fdda9645 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Sat, 21 Dec 2019 06:00:57 -0600 Subject: [PATCH 1/3] samples: sensor: adt7420: fix frdm_k64f devicetree overlay The device address can only be 0x48 through 0x1B. C6 is connected to the FXOS870 and is not exposed on a header: switch to Arduino D0. Move this to a boards subdirectory so we can add other overlays without cluttering the root. Signed-off-by: Peter Bigot --- samples/sensor/adt7420/{ => boards}/frdm_k64f.overlay | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename samples/sensor/adt7420/{ => boards}/frdm_k64f.overlay (75%) diff --git a/samples/sensor/adt7420/frdm_k64f.overlay b/samples/sensor/adt7420/boards/frdm_k64f.overlay similarity index 75% rename from samples/sensor/adt7420/frdm_k64f.overlay rename to samples/sensor/adt7420/boards/frdm_k64f.overlay index 1fe8da787582f..f0292229aae12 100644 --- a/samples/sensor/adt7420/frdm_k64f.overlay +++ b/samples/sensor/adt7420/boards/frdm_k64f.overlay @@ -4,13 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -&i2c1 { +&i2c0 { status = "okay"; clock-frequency = ; - adt7420@13 { + adt7420@48 { compatible = "adi,adt7420"; - reg = <0x13>; + reg = <0x48>; label = "ADT7420"; - int-gpios = <&gpioc 6 0>; + int-gpios = <&gpioc 16 0>; }; }; From 0072b185534a5ca4f1b0dc22545e3be67dcc41d4 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Sat, 21 Dec 2019 06:01:46 -0600 Subject: [PATCH 2/3] samples: sensor: adt7420: add nrf52_pca10040 devicetree overlay Expand the set of hardware this can be tested with. Signed-off-by: Peter Bigot --- .../sensor/adt7420/boards/nrf52_pca10040.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 samples/sensor/adt7420/boards/nrf52_pca10040.overlay diff --git a/samples/sensor/adt7420/boards/nrf52_pca10040.overlay b/samples/sensor/adt7420/boards/nrf52_pca10040.overlay new file mode 100644 index 0000000000000..1b96a7227685a --- /dev/null +++ b/samples/sensor/adt7420/boards/nrf52_pca10040.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&i2c0 { /* SDA P0.26, SCL P0.27, ALERT P0.11 */ + status = "okay"; + clock-frequency = ; + adt7420@48 { + compatible = "adi,adt7420"; + reg = <0x48>; + label = "ADT7420"; + int-gpios = <&gpio0 11 0>; + }; +}; From aaa774aa544a9876c7876cb8d3414d5e094776bf Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Sat, 21 Dec 2019 09:26:36 -0600 Subject: [PATCH 3/3] samples: sensor: adt7420: rework for trigger testing When a trigger was enabled the original implementation would do nothing more than print "Waiting for a threshold event", without describing what such an event would look like. Rework to maintain a window of +/- 0.5 Cel around the most recent in-window temperature, and reset that window whenever a trigger occurs or a non-trigger reading is outside the window. Time-out and display the temperature if no event occurs in a reasonable time. Signed-off-by: Peter Bigot --- samples/sensor/adt7420/README.rst | 20 ++++-- samples/sensor/adt7420/src/main.c | 116 +++++++++++++++++++++++++----- 2 files changed, 110 insertions(+), 26 deletions(-) diff --git a/samples/sensor/adt7420/README.rst b/samples/sensor/adt7420/README.rst index 271e2b49aed80..b68be2ad89396 100644 --- a/samples/sensor/adt7420/README.rst +++ b/samples/sensor/adt7420/README.rst @@ -8,7 +8,12 @@ Description This sample application periodically (1Hz) measures the ambient temperature in degrees Celsius. The result is written to the console. -Optionally, it also shows how to use the upper and lower threshold triggers. + +When configured in trigger mode the update interval is 5 s, and the +sample maintains a |plusminus| 1 |deg| C window around a recent +temperature. As soon as the temperature goes outside the window an +interrupt causes the application to display an event and update the +upper and lower window boundaries. References ********** @@ -44,11 +49,12 @@ Sample Output .. code-block:: console - device is 0x20002b74, name is ADT7420 - temperature 24.984375 C - temperature 24.968750 C - temperature 24.968750 C - temperature 24.968750 C - temperature 24.953125 C + *** Booting Zephyr OS build zephyr-v2.1.0-538-g12b2ed2cf7c3 *** + device is 0x2000101c, name is ADT7420 + [0:00:00.011]: temperature 21.203125 Cel + [0:00:01.015]: temperature 21.171875 Cel + [0:00:02.019]: temperature 21.171875 Cel + [0:00:03.023]: temperature 21.187500 Cel + [0:00:04.027]: temperature 21.140625 Cel diff --git a/samples/sensor/adt7420/src/main.c b/samples/sensor/adt7420/src/main.c index 571c5c5745baf..9b6aa54d75287 100644 --- a/samples/sensor/adt7420/src/main.c +++ b/samples/sensor/adt7420/src/main.c @@ -10,21 +10,51 @@ #include #include -K_SEM_DEFINE(sem, 0, 1); +#define DELAY_WITH_TRIGGER K_SECONDS(5) +#define DELAY_WITHOUT_TRIGGER K_SECONDS(1) + +#define UCEL_PER_CEL 1000000 +#define UCEL_PER_MCEL 1000 +#define TEMP_INITIAL_CEL 21 +#define TEMP_WINDOW_HALF_UCEL 500000 +K_SEM_DEFINE(sem, 0, 1); +static const char *now_str(void) +{ + static char buf[16]; /* ...HH:MM:SS.MMM */ + u32_t now = k_uptime_get_32(); + unsigned int ms = now % MSEC_PER_SEC; + unsigned int s; + unsigned int min; + unsigned int h; + + now /= MSEC_PER_SEC; + s = now % 60U; + now /= 60U; + min = now % 60U; + now /= 60U; + h = now; + + snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", + h, min, s, ms); + return buf; +} static void trigger_handler(struct device *dev, struct sensor_trigger *trigger) { k_sem_give(&sem); } +static int low_ucel; +static int high_ucel; + static int sensor_set_attribute(struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, int value) { struct sensor_value sensor_val; int ret; - sensor_val.val1 = value / 1000000; - sensor_val.val2 = value % 1000000; + sensor_val.val1 = value / UCEL_PER_CEL; + sensor_val.val2 = value % UCEL_PER_CEL; ret = sensor_attr_set(dev, chan, attr, &sensor_val); if (ret) { @@ -34,10 +64,43 @@ static int sensor_set_attribute(struct device *dev, enum sensor_channel chan, return ret; } +static bool temp_in_window(const struct sensor_value *val) +{ + int temp_ucel = val->val1 * UCEL_PER_CEL + val->val2; + + return (temp_ucel >= low_ucel) && (temp_ucel <= high_ucel); +} + +static int sensor_set_window(struct device *dev, + const struct sensor_value *val) +{ + int temp_ucel = val->val1 * UCEL_PER_CEL + val->val2; + + low_ucel = temp_ucel - TEMP_WINDOW_HALF_UCEL; + high_ucel = temp_ucel + TEMP_WINDOW_HALF_UCEL; + + int rc = sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP, + SENSOR_ATTR_UPPER_THRESH, high_ucel); + + if (rc == 0) { + sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP, + SENSOR_ATTR_LOWER_THRESH, low_ucel); + } + + if (rc == 0) { + printk("Alert on temp outside [%d, %d] mCel\n", + low_ucel / UCEL_PER_MCEL, + high_ucel / UCEL_PER_MCEL); + } + + return rc; +} + static void process(struct device *dev) { struct sensor_value temp_val; int ret; + bool reset_window = false; /* Set upddate rate to 240 mHz */ sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP, @@ -48,25 +111,21 @@ static void process(struct device *dev) .type = SENSOR_TRIG_THRESHOLD, .chan = SENSOR_CHAN_AMBIENT_TEMP, }; + struct sensor_value val = { + .val1 = TEMP_INITIAL_CEL, + }; - /* Set lower and upper threshold to 10 and 30 °C */ - sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP, - SENSOR_ATTR_UPPER_THRESH, 30 * 1000000); - sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP, - SENSOR_ATTR_LOWER_THRESH, 10 * 1000000); - - if (sensor_trigger_set(dev, &trig, trigger_handler)) { + ret = sensor_set_window(dev, &val); + if (ret == 0) { + ret = sensor_trigger_set(dev, &trig, trigger_handler); + } + if (ret != 0) { printf("Could not set trigger\n"); return; } } while (1) { - if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) { - printf("Waiting for a threshold event\n"); - k_sem_take(&sem, K_FOREVER); - } - ret = sensor_sample_fetch(dev); if (ret) { printf("sensor_sample_fetch failed ret %d\n", ret); @@ -80,11 +139,30 @@ static void process(struct device *dev) return; } - printf("temperature %.6f C\n", - sensor_value_to_double(&temp_val)); + if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) { + reset_window |= !temp_in_window(&temp_val); + } + + printf("[%s]: temperature %.6f Cel%s\n", now_str(), + sensor_value_to_double(&temp_val), + reset_window ? ": NEED RESET" : ""); - if (!IS_ENABLED(CONFIG_ADT7420_TRIGGER)) { - k_sleep(K_MSEC(1000)); + + if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) { + if (reset_window) { + ret = sensor_set_window(dev, &temp_val); + } + if (ret) { + printf("Window update failed ret %d\n", ret); + return; + } + + printk("Wait for trigger..."); + ret = k_sem_take(&sem, DELAY_WITH_TRIGGER); + reset_window = (ret == 0); + printk("%s\n", reset_window ? "ALERTED!" : "timed-out"); + } else { + k_sleep(DELAY_WITHOUT_TRIGGER); } } }