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 | /* * Copyright (c) 2019 Peter Bigot Consulting, LLC * Copyright (c) 2016 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/zephyr.h> #include <zephyr/device.h> #include <zephyr/drivers/sensor.h> #include <stdio.h> #define UCEL_PER_CEL 1000000 #define UCEL_PER_MCEL 1000 #define TEMP_INITIAL_CEL 25 #define TEMP_WINDOW_HALF_UCEL 500000 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; } #ifdef CONFIG_MCP9808_TRIGGER static struct sensor_trigger trig; static int set_window(const struct device *dev, const struct sensor_value *temp) { const int temp_ucel = temp->val1 * UCEL_PER_CEL + temp->val2; const int low_ucel = temp_ucel - TEMP_WINDOW_HALF_UCEL; const int high_ucel = temp_ucel + TEMP_WINDOW_HALF_UCEL; struct sensor_value val = { .val1 = low_ucel / UCEL_PER_CEL, .val2 = low_ucel % UCEL_PER_CEL, }; int rc = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP, SENSOR_ATTR_LOWER_THRESH, &val); if (rc == 0) { val.val1 = high_ucel / UCEL_PER_CEL, val.val2 = high_ucel % UCEL_PER_CEL, rc = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP, SENSOR_ATTR_UPPER_THRESH, &val); } if (rc == 0) { printf("Alert on temp outside [%d, %d] milli-Celsius\n", low_ucel / UCEL_PER_MCEL, high_ucel / UCEL_PER_MCEL); } return rc; } static inline int set_window_ucel(const struct device *dev, int temp_ucel) { struct sensor_value val = { .val1 = temp_ucel / UCEL_PER_CEL, .val2 = temp_ucel % UCEL_PER_CEL, }; return set_window(dev, &val); } static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig) { struct sensor_value temp; static size_t cnt; int rc; ++cnt; rc = sensor_sample_fetch(dev); if (rc != 0) { printf("sensor_sample_fetch error: %d\n", rc); return; } rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); if (rc != 0) { printf("sensor_channel_get error: %d\n", rc); return; } printf("trigger fired %u, temp %g deg C\n", cnt, sensor_value_to_double(&temp)); set_window(dev, &temp); } #endif void main(void) { const struct device *dev = DEVICE_DT_GET_ANY(microchip_mcp9808); int rc; if (dev == NULL) { printf("Device not found.\n"); return; } if (!device_is_ready(dev)) { printf("Device %s is not ready.\n", dev->name); return; } #ifdef CONFIG_MCP9808_TRIGGER rc = set_window_ucel(dev, TEMP_INITIAL_CEL * UCEL_PER_CEL); if (rc == 0) { trig.type = SENSOR_TRIG_THRESHOLD; trig.chan = SENSOR_CHAN_AMBIENT_TEMP; rc = sensor_trigger_set(dev, &trig, trigger_handler); } if (rc != 0) { printf("Trigger set failed: %d\n", rc); return; } printk("Trigger set got %d\n", rc); #endif while (1) { struct sensor_value temp; rc = sensor_sample_fetch(dev); if (rc != 0) { printf("sensor_sample_fetch error: %d\n", rc); break; } rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); if (rc != 0) { printf("sensor_channel_get error: %d\n", rc); break; } printf("%s: %g C\n", now_str(), sensor_value_to_double(&temp)); k_sleep(K_SECONDS(2)); } } |