Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | /* * Copyright (c) 2018 Analog Devices Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/zephyr.h> #include <zephyr/device.h> #include <zephyr/drivers/sensor.h> #include <stdio.h> #include <zephyr/sys/__assert.h> #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 */ uint32_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(const struct device *dev, const struct sensor_trigger *trigger) { k_sem_give(&sem); } static int low_ucel; static int high_ucel; static int sensor_set_attribute(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, int value) { struct sensor_value sensor_val; int ret; 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) { printf("sensor_attr_set failed ret %d\n", ret); } 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(const 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(const struct device *dev) { struct sensor_value temp_val; int ret; bool reset_window = false; /* Set update rate to 240 mHz */ sensor_set_attribute(dev, SENSOR_CHAN_AMBIENT_TEMP, SENSOR_ATTR_SAMPLING_FREQUENCY, 240 * 1000); if (IS_ENABLED(CONFIG_ADT7420_TRIGGER)) { struct sensor_trigger trig = { .type = SENSOR_TRIG_THRESHOLD, .chan = SENSOR_CHAN_AMBIENT_TEMP, }; struct sensor_value val = { .val1 = TEMP_INITIAL_CEL, }; 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) { ret = sensor_sample_fetch(dev); if (ret) { printf("sensor_sample_fetch failed ret %d\n", ret); return; } ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp_val); if (ret) { printf("sensor_channel_get failed ret %d\n", ret); return; } 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)) { 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); } } } void main(void) { const struct device *dev = device_get_binding(DT_LABEL(DT_INST(0, adi_adt7420))); if (dev == NULL) { printf("Failed to get device binding\n"); return; } printf("device is %p, name is %s\n", dev, dev->name); process(dev); } |