1010#include <stdio.h>
1111#include <sys/__assert.h>
1212
13- K_SEM_DEFINE (sem , 0 , 1 );
13+ #define DELAY_WITH_TRIGGER K_SECONDS(5)
14+ #define DELAY_WITHOUT_TRIGGER K_SECONDS(1)
15+
16+ #define UCEL_PER_CEL 1000000
17+ #define UCEL_PER_MCEL 1000
18+ #define TEMP_INITIAL_CEL 21
19+ #define TEMP_WINDOW_HALF_UCEL 500000
1420
21+ K_SEM_DEFINE (sem , 0 , 1 );
22+ static const char * now_str (void )
23+ {
24+ static char buf [16 ]; /* ...HH:MM:SS.MMM */
25+ u32_t now = k_uptime_get_32 ();
26+ unsigned int ms = now % MSEC_PER_SEC ;
27+ unsigned int s ;
28+ unsigned int min ;
29+ unsigned int h ;
30+
31+ now /= MSEC_PER_SEC ;
32+ s = now % 60U ;
33+ now /= 60U ;
34+ min = now % 60U ;
35+ now /= 60U ;
36+ h = now ;
37+
38+ snprintf (buf , sizeof (buf ), "%u:%02u:%02u.%03u" ,
39+ h , min , s , ms );
40+ return buf ;
41+ }
1542static void trigger_handler (struct device * dev , struct sensor_trigger * trigger )
1643{
1744 k_sem_give (& sem );
1845}
1946
47+ static int low_ucel ;
48+ static int high_ucel ;
49+
2050static int sensor_set_attribute (struct device * dev , enum sensor_channel chan ,
2151 enum sensor_attribute attr , int value )
2252{
2353 struct sensor_value sensor_val ;
2454 int ret ;
2555
26- sensor_val .val1 = value / 1000000 ;
27- sensor_val .val2 = value % 1000000 ;
56+ sensor_val .val1 = value / UCEL_PER_CEL ;
57+ sensor_val .val2 = value % UCEL_PER_CEL ;
2858
2959 ret = sensor_attr_set (dev , chan , attr , & sensor_val );
3060 if (ret ) {
@@ -34,10 +64,43 @@ static int sensor_set_attribute(struct device *dev, enum sensor_channel chan,
3464 return ret ;
3565}
3666
67+ static bool temp_in_window (const struct sensor_value * val )
68+ {
69+ int temp_ucel = val -> val1 * UCEL_PER_CEL + val -> val2 ;
70+
71+ return (temp_ucel >= low_ucel ) && (temp_ucel <= high_ucel );
72+ }
73+
74+ static int sensor_set_window (struct device * dev ,
75+ const struct sensor_value * val )
76+ {
77+ int temp_ucel = val -> val1 * UCEL_PER_CEL + val -> val2 ;
78+
79+ low_ucel = temp_ucel - TEMP_WINDOW_HALF_UCEL ;
80+ high_ucel = temp_ucel + TEMP_WINDOW_HALF_UCEL ;
81+
82+ int rc = sensor_set_attribute (dev , SENSOR_CHAN_AMBIENT_TEMP ,
83+ SENSOR_ATTR_UPPER_THRESH , high_ucel );
84+
85+ if (rc == 0 ) {
86+ sensor_set_attribute (dev , SENSOR_CHAN_AMBIENT_TEMP ,
87+ SENSOR_ATTR_LOWER_THRESH , low_ucel );
88+ }
89+
90+ if (rc == 0 ) {
91+ printk ("Alert on temp outside [%d, %d] mCel\n" ,
92+ low_ucel / UCEL_PER_MCEL ,
93+ high_ucel / UCEL_PER_MCEL );
94+ }
95+
96+ return rc ;
97+ }
98+
3799static void process (struct device * dev )
38100{
39101 struct sensor_value temp_val ;
40102 int ret ;
103+ bool reset_window = false;
41104
42105 /* Set upddate rate to 240 mHz */
43106 sensor_set_attribute (dev , SENSOR_CHAN_AMBIENT_TEMP ,
@@ -48,25 +111,21 @@ static void process(struct device *dev)
48111 .type = SENSOR_TRIG_THRESHOLD ,
49112 .chan = SENSOR_CHAN_AMBIENT_TEMP ,
50113 };
114+ struct sensor_value val = {
115+ .val1 = TEMP_INITIAL_CEL ,
116+ };
51117
52- /* Set lower and upper threshold to 10 and 30 °C */
53- sensor_set_attribute (dev , SENSOR_CHAN_AMBIENT_TEMP ,
54- SENSOR_ATTR_UPPER_THRESH , 30 * 1000000 );
55- sensor_set_attribute (dev , SENSOR_CHAN_AMBIENT_TEMP ,
56- SENSOR_ATTR_LOWER_THRESH , 10 * 1000000 );
57-
58- if (sensor_trigger_set (dev , & trig , trigger_handler )) {
118+ ret = sensor_set_window (dev , & val );
119+ if (ret == 0 ) {
120+ ret = sensor_trigger_set (dev , & trig , trigger_handler );
121+ }
122+ if (ret != 0 ) {
59123 printf ("Could not set trigger\n" );
60124 return ;
61125 }
62126 }
63127
64128 while (1 ) {
65- if (IS_ENABLED (CONFIG_ADT7420_TRIGGER )) {
66- printf ("Waiting for a threshold event\n" );
67- k_sem_take (& sem , K_FOREVER );
68- }
69-
70129 ret = sensor_sample_fetch (dev );
71130 if (ret ) {
72131 printf ("sensor_sample_fetch failed ret %d\n" , ret );
@@ -80,11 +139,30 @@ static void process(struct device *dev)
80139 return ;
81140 }
82141
83- printf ("temperature %.6f C\n" ,
84- sensor_value_to_double (& temp_val ));
142+ if (IS_ENABLED (CONFIG_ADT7420_TRIGGER )) {
143+ reset_window |= !temp_in_window (& temp_val );
144+ }
145+
146+ printf ("[%s]: temperature %.6f Cel%s\n" , now_str (),
147+ sensor_value_to_double (& temp_val ),
148+ reset_window ? ": NEED RESET" : "" );
85149
86- if (!IS_ENABLED (CONFIG_ADT7420_TRIGGER )) {
87- k_sleep (K_MSEC (1000 ));
150+
151+ if (IS_ENABLED (CONFIG_ADT7420_TRIGGER )) {
152+ if (reset_window ) {
153+ ret = sensor_set_window (dev , & temp_val );
154+ }
155+ if (ret ) {
156+ printf ("Window update failed ret %d\n" , ret );
157+ return ;
158+ }
159+
160+ printk ("Wait for trigger..." );
161+ ret = k_sem_take (& sem , DELAY_WITH_TRIGGER );
162+ reset_window = (ret == 0 );
163+ printk ("%s\n" , reset_window ? "ALERTED!" : "timed-out" );
164+ } else {
165+ k_sleep (DELAY_WITHOUT_TRIGGER );
88166 }
89167 }
90168}
0 commit comments