1 /*
2  * Copyright (c) 2016 ARM Ltd.
3  * Copyright (c) 2023 FTP Technologies
4  * Copyright (c) 2023 Daniel DeGrasse <daniel@degrasse.com>
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <stdio.h>
12 
13 static double high_temp;
14 static double low_temp;
15 
read_temperature(const struct device * dev,struct sensor_value * val)16 int read_temperature(const struct device *dev, struct sensor_value *val)
17 {
18 	int ret;
19 
20 	ret = sensor_sample_fetch_chan(dev, SENSOR_CHAN_AMBIENT_TEMP);
21 	if (ret < 0) {
22 		printf("Could not fetch temperature: %d\n", ret);
23 		return ret;
24 	}
25 
26 	ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, val);
27 	if (ret < 0) {
28 		printf("Could not get temperature: %d\n", ret);
29 	}
30 	return ret;
31 }
32 
temp_alert_handler(const struct device * dev,const struct sensor_trigger * trig)33 void temp_alert_handler(const struct device *dev, const struct sensor_trigger *trig)
34 {
35 	int ret;
36 	struct sensor_value value;
37 	double temp;
38 
39 	/* Read sensor value */
40 	ret = read_temperature(dev, &value);
41 	if (ret < 0) {
42 		printf("Reading temperature failed: %d\n", ret);
43 		return;
44 	}
45 	temp = sensor_value_to_double(&value);
46 	if (temp <= low_temp) {
47 		printf("Temperature below threshold: %0.1f°C\n", temp);
48 	} else if (temp >= high_temp) {
49 		printf("Temperature above threshold: %0.1f°C\n", temp);
50 	} else {
51 		printf("Error: temperature alert triggered without valid condition\n");
52 	}
53 }
54 
main(void)55 int main(void)
56 {
57 	const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(ambient_temp0));
58 	struct sensor_value value;
59 	double temp;
60 	int ret;
61 	const struct sensor_trigger trig = {
62 		.chan = SENSOR_CHAN_AMBIENT_TEMP,
63 		.type = SENSOR_TRIG_THRESHOLD,
64 	};
65 
66 	printf("Thermometer Example (%s)\n", CONFIG_ARCH);
67 
68 	if (!device_is_ready(dev)) {
69 		printf("Device %s is not ready\n", dev->name);
70 		return 0;
71 	}
72 
73 	printf("Temperature device is %p, name is %s\n", dev, dev->name);
74 
75 	/* First, fetch a sensor sample to use for sensor thresholds */
76 	ret = read_temperature(dev, &value);
77 	if (ret != 0) {
78 		printf("Failed to read temperature: %d\n", ret);
79 		return ret;
80 	}
81 	temp = sensor_value_to_double(&value);
82 
83 	/* Set thresholds to +0.5 and +1.5 °C from ambient */
84 	low_temp = temp + 0.5;
85 	ret = sensor_value_from_double(&value, low_temp);
86 	if (ret != 0) {
87 		printf("Failed to convert low threshold to sensor value: %d\n", ret);
88 		return ret;
89 	}
90 	ret = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP,
91 			      SENSOR_ATTR_LOWER_THRESH, &value);
92 	if (ret == 0) {
93 		/* This sensor supports threshold triggers */
94 		printf("Set temperature lower limit to %0.1f°C\n", low_temp);
95 	}
96 
97 	high_temp = temp + 1.5;
98 	ret = sensor_value_from_double(&value, high_temp);
99 	if (ret != 0) {
100 		printf("Failed to convert low threshold to sensor value: %d\n", ret);
101 		return ret;
102 	}
103 	ret = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP,
104 			      SENSOR_ATTR_UPPER_THRESH, &value);
105 	if (ret == 0) {
106 		/* This sensor supports threshold triggers */
107 		printf("Set temperature upper limit to %0.1f°C\n", high_temp);
108 	}
109 
110 	ret = sensor_trigger_set(dev, &trig, temp_alert_handler);
111 	if (ret == 0) {
112 		printf("Enabled sensor threshold triggers\n");
113 	}
114 
115 	while (1) {
116 		ret = read_temperature(dev, &value);
117 		if (ret != 0) {
118 			printf("Failed to read temperature: %d\n", ret);
119 			break;
120 		}
121 
122 		printf("Temperature is %0.1lf°C\n", sensor_value_to_double(&value));
123 
124 		k_sleep(K_MSEC(1000));
125 	}
126 	return 0;
127 }
128