Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions samples/sensor/adt7420/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
**********
Expand Down Expand Up @@ -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

<repeats endlessly>
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

&i2c1 {
&i2c0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace with arduino_i2c

status = "okay";
clock-frequency = <I2C_BITRATE_STANDARD>;
adt7420@13 {
adt7420@48 {
compatible = "adi,adt7420";
reg = <0x13>;
reg = <0x48>;
label = "ADT7420";
int-gpios = <&gpioc 6 0>;
int-gpios = <&gpioc 16 0>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace with <&arduino_header 6 0> /* D0 */.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, but this propagated from the original conversion to devicetree, and isn't specific to this sample: there are at least twelve samples that bypass the Ardunio alias and nexus map for this platform, probably more that do it for other platforms.

Can we do this in a separate PR that fixes it for all samples at once, after the dust settles on topic-gpio and it won't create conflicts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

};
};
16 changes: 16 additions & 0 deletions samples/sensor/adt7420/boards/nrf52_pca10040.overlay
Original file line number Diff line number Diff line change
@@ -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 = <I2C_BITRATE_STANDARD>;
adt7420@48 {
compatible = "adi,adt7420";
reg = <0x48>;
label = "ADT7420";
int-gpios = <&gpio0 11 0>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use arduino here too

};
};
116 changes: 97 additions & 19 deletions samples/sensor/adt7420/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,51 @@
#include <stdio.h>
#include <sys/__assert.h>

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) {
Expand All @@ -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,
Expand All @@ -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);
Expand All @@ -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);
}
}
}
Expand Down