1 /*
2 * Copyright (c) 2019 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/sensor.h>
10 #include <stdio.h>
11 #include <zephyr/sys/util.h>
12
13 #define LUX_ALERT_DELTA 50
14
15 static volatile bool alerted;
16 struct k_sem sem;
17
trigger_handler(const struct device * dev,const struct sensor_trigger * trig)18 static void trigger_handler(const struct device *dev,
19 const struct sensor_trigger *trig)
20 {
21 #ifdef CONFIG_ISL29035_TRIGGER
22 alerted = !alerted;
23 k_sem_give(&sem);
24 #endif /* CONFIG_ISL29035_TRIGGER */
25 }
26
now_str(void)27 static const char *now_str(void)
28 {
29 static char buf[16]; /* ...HH:MM:SS.MMM */
30 uint32_t now = k_uptime_get_32();
31 unsigned int ms = now % MSEC_PER_SEC;
32 unsigned int s;
33 unsigned int min;
34 unsigned int h;
35
36 now /= MSEC_PER_SEC;
37 s = now % 60U;
38 now /= 60U;
39 min = now % 60U;
40 now /= 60U;
41 h = now;
42
43 snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u",
44 h, min, s, ms);
45 return buf;
46 }
47
process_sample(const struct device * dev)48 static void process_sample(const struct device *dev)
49 {
50 static bool last_alerted;
51 struct sensor_value val;
52
53 if (sensor_sample_fetch(dev) < 0) {
54 printf("Sensor sample update error\n");
55 return;
56 }
57
58 if (sensor_channel_get(dev, SENSOR_CHAN_LIGHT, &val) < 0) {
59 printf("Cannot read ISL29035 value\n");
60 return;
61 }
62
63 int lux = val.val1;
64
65 if (IS_ENABLED(CONFIG_ISL29035_TRIGGER)
66 && (alerted != last_alerted)) {
67 static int last_lux;
68 int rc;
69 struct sensor_trigger trig = {
70 .type = SENSOR_TRIG_THRESHOLD,
71 .chan = SENSOR_CHAN_ALL,
72 };
73 struct sensor_value lo_thr = { MAX(lux - LUX_ALERT_DELTA, 0), };
74 struct sensor_value hi_thr = { lux + LUX_ALERT_DELTA };
75
76 printf("ALERT %d lux outside range centered on %d lux."
77 "\nNext alert outside %d .. %d\n",
78 lux, last_lux, lo_thr.val1, hi_thr.val1);
79 last_lux = lux;
80 last_alerted = alerted;
81
82 rc = sensor_attr_set(dev, SENSOR_CHAN_LIGHT,
83 SENSOR_ATTR_LOWER_THRESH, &lo_thr);
84 if (rc == 0) {
85 rc = sensor_attr_set(dev, SENSOR_CHAN_LIGHT,
86 SENSOR_ATTR_UPPER_THRESH, &hi_thr);
87 }
88 if (rc == 0) {
89 rc = sensor_trigger_set(dev, &trig, trigger_handler);
90 }
91 if (rc != 0) {
92 printf("Alert configuration failed: %d\n", rc);
93 }
94 }
95
96 printf("[%s] %s: %g\n", now_str(),
97 IS_ENABLED(CONFIG_ISL29035_MODE_ALS)
98 ? "Ambient light sense"
99 : "IR sense",
100 sensor_value_to_double(&val));
101 }
102
main(void)103 int main(void)
104 {
105 const struct device *const dev = DEVICE_DT_GET_ONE(isil_isl29035);
106
107 if (!device_is_ready(dev)) {
108 printk("sensor: device not ready.\n");
109 return 0;
110 }
111
112 k_sem_init(&sem, 0, 1);
113 alerted = true;
114 while (true) {
115 process_sample(dev);
116
117 if (IS_ENABLED(CONFIG_ISL29035_TRIGGER)) {
118 k_sem_take(&sem, K_SECONDS(10));
119 } else {
120 k_sleep(K_SECONDS(1));
121 }
122 }
123 return 0;
124 }
125