Skip to content

Commit aaa774a

Browse files
committed
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 <[email protected]>
1 parent 0072b18 commit aaa774a

File tree

2 files changed

+110
-26
lines changed

2 files changed

+110
-26
lines changed

samples/sensor/adt7420/README.rst

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ Description
88

99
This sample application periodically (1Hz) measures the ambient temperature
1010
in degrees Celsius. The result is written to the console.
11-
Optionally, it also shows how to use the upper and lower threshold triggers.
11+
12+
When configured in trigger mode the update interval is 5 s, and the
13+
sample maintains a |plusminus| 1 |deg| C window around a recent
14+
temperature. As soon as the temperature goes outside the window an
15+
interrupt causes the application to display an event and update the
16+
upper and lower window boundaries.
1217

1318
References
1419
**********
@@ -44,11 +49,12 @@ Sample Output
4449

4550
.. code-block:: console
4651
47-
device is 0x20002b74, name is ADT7420
48-
temperature 24.984375 C
49-
temperature 24.968750 C
50-
temperature 24.968750 C
51-
temperature 24.968750 C
52-
temperature 24.953125 C
52+
*** Booting Zephyr OS build zephyr-v2.1.0-538-g12b2ed2cf7c3 ***
53+
device is 0x2000101c, name is ADT7420
54+
[0:00:00.011]: temperature 21.203125 Cel
55+
[0:00:01.015]: temperature 21.171875 Cel
56+
[0:00:02.019]: temperature 21.171875 Cel
57+
[0:00:03.023]: temperature 21.187500 Cel
58+
[0:00:04.027]: temperature 21.140625 Cel
5359
5460
<repeats endlessly>

samples/sensor/adt7420/src/main.c

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,51 @@
1010
#include <stdio.h>
1111
#include <sys/__assert.h>
1212

13-
K_SEM_DEFINE(sem, 0, 1);
13+
#define DELAY_WITH_TRIGGER K_SECONDS(5)
14+
#define DELAY_WITHOUT_TRIGGER K_SECONDS(1)
15+
16+
#define UCEL_PER_CEL 1000000
17+
#define UCEL_PER_MCEL 1000
18+
#define TEMP_INITIAL_CEL 21
19+
#define TEMP_WINDOW_HALF_UCEL 500000
1420

21+
K_SEM_DEFINE(sem, 0, 1);
22+
static const char *now_str(void)
23+
{
24+
static char buf[16]; /* ...HH:MM:SS.MMM */
25+
u32_t now = k_uptime_get_32();
26+
unsigned int ms = now % MSEC_PER_SEC;
27+
unsigned int s;
28+
unsigned int min;
29+
unsigned int h;
30+
31+
now /= MSEC_PER_SEC;
32+
s = now % 60U;
33+
now /= 60U;
34+
min = now % 60U;
35+
now /= 60U;
36+
h = now;
37+
38+
snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u",
39+
h, min, s, ms);
40+
return buf;
41+
}
1542
static void trigger_handler(struct device *dev, struct sensor_trigger *trigger)
1643
{
1744
k_sem_give(&sem);
1845
}
1946

47+
static int low_ucel;
48+
static int high_ucel;
49+
2050
static int sensor_set_attribute(struct device *dev, enum sensor_channel chan,
2151
enum sensor_attribute attr, int value)
2252
{
2353
struct sensor_value sensor_val;
2454
int ret;
2555

26-
sensor_val.val1 = value / 1000000;
27-
sensor_val.val2 = value % 1000000;
56+
sensor_val.val1 = value / UCEL_PER_CEL;
57+
sensor_val.val2 = value % UCEL_PER_CEL;
2858

2959
ret = sensor_attr_set(dev, chan, attr, &sensor_val);
3060
if (ret) {
@@ -34,10 +64,43 @@ static int sensor_set_attribute(struct device *dev, enum sensor_channel chan,
3464
return ret;
3565
}
3666

67+
static bool temp_in_window(const struct sensor_value *val)
68+
{
69+
int temp_ucel = val->val1 * UCEL_PER_CEL + val->val2;
70+
71+
return (temp_ucel >= low_ucel) && (temp_ucel <= high_ucel);
72+
}
73+
74+
static int sensor_set_window(struct device *dev,
75+
const struct sensor_value *val)
76+
{
77+
int temp_ucel = val->val1 * UCEL_PER_CEL + val->val2;
78+
79+
low_ucel = temp_ucel - TEMP_WINDOW_HALF_UCEL;
80+
high_ucel = temp_ucel + TEMP_WINDOW_HALF_UCEL;
81+
82+
int rc = sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP,
83+
SENSOR_ATTR_UPPER_THRESH, high_ucel);
84+
85+
if (rc == 0) {
86+
sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP,
87+
SENSOR_ATTR_LOWER_THRESH, low_ucel);
88+
}
89+
90+
if (rc == 0) {
91+
printk("Alert on temp outside [%d, %d] mCel\n",
92+
low_ucel / UCEL_PER_MCEL,
93+
high_ucel / UCEL_PER_MCEL);
94+
}
95+
96+
return rc;
97+
}
98+
3799
static void process(struct device *dev)
38100
{
39101
struct sensor_value temp_val;
40102
int ret;
103+
bool reset_window = false;
41104

42105
/* Set upddate rate to 240 mHz */
43106
sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP,
@@ -48,25 +111,21 @@ static void process(struct device *dev)
48111
.type = SENSOR_TRIG_THRESHOLD,
49112
.chan = SENSOR_CHAN_AMBIENT_TEMP,
50113
};
114+
struct sensor_value val = {
115+
.val1 = TEMP_INITIAL_CEL,
116+
};
51117

52-
/* Set lower and upper threshold to 10 and 30 °C */
53-
sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP,
54-
SENSOR_ATTR_UPPER_THRESH, 30 * 1000000);
55-
sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP,
56-
SENSOR_ATTR_LOWER_THRESH, 10 * 1000000);
57-
58-
if (sensor_trigger_set(dev, &trig, trigger_handler)) {
118+
ret = sensor_set_window(dev, &val);
119+
if (ret == 0) {
120+
ret = sensor_trigger_set(dev, &trig, trigger_handler);
121+
}
122+
if (ret != 0) {
59123
printf("Could not set trigger\n");
60124
return;
61125
}
62126
}
63127

64128
while (1) {
65-
if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) {
66-
printf("Waiting for a threshold event\n");
67-
k_sem_take(&sem, K_FOREVER);
68-
}
69-
70129
ret = sensor_sample_fetch(dev);
71130
if (ret) {
72131
printf("sensor_sample_fetch failed ret %d\n", ret);
@@ -80,11 +139,30 @@ static void process(struct device *dev)
80139
return;
81140
}
82141

83-
printf("temperature %.6f C\n",
84-
sensor_value_to_double(&temp_val));
142+
if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) {
143+
reset_window |= !temp_in_window(&temp_val);
144+
}
145+
146+
printf("[%s]: temperature %.6f Cel%s\n", now_str(),
147+
sensor_value_to_double(&temp_val),
148+
reset_window ? ": NEED RESET" : "");
85149

86-
if (!IS_ENABLED(CONFIG_ADT7420_TRIGGER)) {
87-
k_sleep(K_MSEC(1000));
150+
151+
if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) {
152+
if (reset_window) {
153+
ret = sensor_set_window(dev, &temp_val);
154+
}
155+
if (ret) {
156+
printf("Window update failed ret %d\n", ret);
157+
return;
158+
}
159+
160+
printk("Wait for trigger...");
161+
ret = k_sem_take(&sem, DELAY_WITH_TRIGGER);
162+
reset_window = (ret == 0);
163+
printk("%s\n", reset_window ? "ALERTED!" : "timed-out");
164+
} else {
165+
k_sleep(DELAY_WITHOUT_TRIGGER);
88166
}
89167
}
90168
}

0 commit comments

Comments
 (0)