1 /*
2  * Copyright (c) 2019-2024 Vestas Wind Systems A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/adc.h>
10 #include <stdio.h>
11 #include <math.h>
12 
13 #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(main);
16 
17 /* Nominal RTD (PT100) resistance in ohms */
18 #define RTD_NOMINAL_RESISTANCE 100
19 
20 /* ADC maximum value (taking sign bit into consideration) */
21 #define ADC_MAX(resolution) BIT_MASK(resolution - 1)
22 
23 /* Bottom resistor value in ohms */
24 #define BOTTOM_RESISTANCE 2000
25 
rtd_temperature(int nom,double resistance)26 static double rtd_temperature(int nom, double resistance)
27 {
28 	const double a0 =  3.90802E-3;
29 	const double b0 = -0.58020E-6;
30 	double temp;
31 
32 	temp = -nom * a0;
33 	temp += sqrt((nom * nom) * (a0 * a0) - 4.0 * nom * b0 *
34 		     (nom - resistance));
35 	temp /= 2.0 * nom * b0;
36 
37 	return temp;
38 }
39 
main(void)40 int main(void)
41 {
42 	const struct adc_dt_spec ch_cfg = ADC_DT_SPEC_GET(DT_PATH(zephyr_user));
43 	double adc_max = ADC_MAX(ch_cfg.resolution);
44 	double resistance;
45 	int32_t buffer;
46 	int err;
47 	struct adc_sequence seq = {
48 		.buffer = &buffer,
49 		.buffer_size = sizeof(buffer),
50 	};
51 
52 	if (!adc_is_ready_dt(&ch_cfg)) {
53 		LOG_ERR("LMP90100 device not ready");
54 		return 0;
55 	}
56 
57 	err = adc_channel_setup_dt(&ch_cfg);
58 	if (err != 0) {
59 		LOG_ERR("failed to setup ADC channel (err %d)", err);
60 		return 0;
61 	}
62 
63 	err = adc_sequence_init_dt(&ch_cfg, &seq);
64 	if (err != 0) {
65 		LOG_ERR("failed to initialize ADC sequence (err %d)", err);
66 		return 0;
67 	}
68 
69 	while (true) {
70 		err = adc_read_dt(&ch_cfg, &seq);
71 		if (err != 0) {
72 			LOG_ERR("failed to read ADC (err %d)", err);
73 		} else {
74 			resistance = (buffer / adc_max) * BOTTOM_RESISTANCE;
75 			printf("R: %.02f ohm\n", resistance);
76 			printf("T: %.02f degC\n",
77 				rtd_temperature(RTD_NOMINAL_RESISTANCE,
78 						resistance));
79 		}
80 
81 		k_sleep(K_MSEC(1000));
82 	}
83 	return 0;
84 }
85