1 /*
2 * Copyright (c) 2023 Ian Morris
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include <zephyr/device.h>
11 #include <zephyr/sys/util_macro.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/drivers/sensor.h>
14 #include <zephyr/drivers/sensor_data_types.h>
15 #include <zephyr/rtio/rtio.h>
16 #include <zephyr/dsp/print_format.h>
17
18 #define DHT_ALIAS(i) DT_ALIAS(_CONCAT(dht, i))
19 #define DHT_DEVICE(i, _) \
20 IF_ENABLED(DT_NODE_EXISTS(DHT_ALIAS(i)), (DEVICE_DT_GET(DHT_ALIAS(i)),))
21
22 /* Support up to 10 temperature/humidity sensors */
23 static const struct device *const sensors[] = {LISTIFY(10, DHT_DEVICE, ())};
24
25 #define DHT_IODEV(i, _) \
26 IF_ENABLED(DT_NODE_EXISTS(DHT_ALIAS(i)), \
27 (SENSOR_DT_READ_IODEV(_CONCAT(dht_iodev, i), DHT_ALIAS(i), \
28 {SENSOR_CHAN_AMBIENT_TEMP, 0}, \
29 {SENSOR_CHAN_HUMIDITY, 0})))
30
31 LISTIFY(10, DHT_IODEV, (;));
32
33 #define DHT_IODEV_REF(i, _) \
34 COND_CODE_1(DT_NODE_EXISTS(DHT_ALIAS(i)), (CONCAT(&dht_iodev, i)), (NULL))
35
36 static struct rtio_iodev *dht_iodev[] = { LISTIFY(10, DHT_IODEV_REF, (,)) };
37
38 RTIO_DEFINE(dht_ctx, 1, 1);
39
main(void)40 int main(void)
41 {
42 int rc;
43
44 for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) {
45 if (!device_is_ready(sensors[i])) {
46 printk("sensor: device %s not ready.\n", sensors[i]->name);
47 return 0;
48 }
49 }
50
51 while (1) {
52 for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) {
53 struct device *dev = (struct device *) sensors[i];
54
55 uint8_t buf[128];
56
57 rc = sensor_read(dht_iodev[i], &dht_ctx, buf, 128);
58
59 if (rc != 0) {
60 printk("%s: sensor_read() failed: %d\n", dev->name, rc);
61 return rc;
62 }
63
64 const struct sensor_decoder_api *decoder;
65
66 rc = sensor_get_decoder(dev, &decoder);
67
68 if (rc != 0) {
69 printk("%s: sensor_get_decode() failed: %d\n", dev->name, rc);
70 return rc;
71 }
72
73 uint32_t temp_fit = 0;
74 struct sensor_q31_data temp_data = {0};
75
76 decoder->decode(buf,
77 (struct sensor_chan_spec) {SENSOR_CHAN_AMBIENT_TEMP, 0},
78 &temp_fit, 1, &temp_data);
79
80 uint32_t hum_fit = 0;
81 struct sensor_q31_data hum_data = {0};
82
83 decoder->decode(buf,
84 (struct sensor_chan_spec) {SENSOR_CHAN_HUMIDITY, 0},
85 &hum_fit, 1, &hum_data);
86
87 printk("%16s: temp is %s%d.%d °C humidity is %s%d.%d %%RH\n", dev->name,
88 PRIq_arg(temp_data.readings[0].temperature, 2, temp_data.shift),
89 PRIq_arg(hum_data.readings[0].humidity, 2, hum_data.shift));
90 }
91 k_msleep(1000);
92 }
93 return 0;
94 }
95