44 */
55
66#include <zephyr/kernel.h>
7- #include <zephyr/drivers/sensor.h>
8- #include <zephyr/drivers/i2c.h>
97#include <zephyr/logging/log.h>
10- #include <zephyr/drivers/sensor/ccs811 .h>
8+ #include <zephyr/zbus/zbus .h>
119
1210#include <app/drivers/blink.h>
13-
1411#include <app_version.h>
1512
13+ #include <modules/sensor/sensor_module.h>
14+
1615LOG_MODULE_REGISTER (main , CONFIG_APP_LOG_LEVEL );
1716
1817#define BLINK_PERIOD_MS_STEP 100U
@@ -21,54 +20,16 @@ LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL);
2120#define SENSORS_WARMUP_DELAY_MS 5000U
2221#define SENSOR_READ_INTERVAL_MS 1000U
2322
24- /* CCS811 environmental compensation configuration */
25- #define SENSOR_VALUE_TO_MICRO (val ) ((val)->val1 * 1000000UL + (val)->val2)
26- #define CCS811_TEMP_THRESHOLD_MICRO 500000 /* 0.5°C in microseconds */
27- #define CCS811_HUM_THRESHOLD_MICRO 500000 /* 0.5% RH in microseconds */
23+ /* ZBUS observer for sensor messages */
24+ static void sensor_response_callback (const struct zbus_channel * chan );
25+ ZBUS_LISTENER_DEFINE (sensor_response_listener , sensor_response_callback );
2826
2927/* Function prototypes */
30- static int init_sensors (const struct device * * bme280 , const struct device * * ccs811 ,
31- const struct device * * hm3301 , const struct device * * blink );
32- static int read_bme280_data (const struct device * sensor , struct sensor_value * temp ,
33- struct sensor_value * press , struct sensor_value * hum );
34- static int read_ccs811_data (const struct device * sensor , struct sensor_value * co2 ,
35- struct sensor_value * voc );
36- static int read_hm3301_data (const struct device * sensor , struct sensor_value * pm1 ,
37- struct sensor_value * pm25 , struct sensor_value * pm10 );
38-
39- #ifdef CONFIG_CCS811_ENV_COMPENSATION
40- static int update_ccs811_env_data (const struct device * ccs811_sensor ,
41- const struct sensor_value * temp , const struct sensor_value * hum );
42- static void handle_ccs811_env_compensation (const struct device * ccs811_sensor ,
43- const struct sensor_value * temp ,
44- const struct sensor_value * hum );
45- static void handle_ccs811_fallback_compensation (const struct device * ccs811_sensor );
46- #endif
28+ static int init_blink_led (const struct device * * blink );
29+ static void log_sensor_data (const struct sensor_msg * msg );
4730
48- static int init_sensors (const struct device * * bme280 , const struct device * * ccs811 ,
49- const struct device * * hm3301 , const struct device * * blink )
31+ static int init_blink_led (const struct device * * blink )
5032{
51- /* Initialize BME280 sensor */
52- * bme280 = DEVICE_DT_GET (DT_NODELABEL (bme280 ));
53- if (!device_is_ready (* bme280 )) {
54- LOG_ERR ("BME280 sensor not ready" );
55- return - ENODEV ;
56- }
57-
58- /* Initialize CCS811 sensor */
59- * ccs811 = DEVICE_DT_GET (DT_NODELABEL (ccs811 ));
60- if (!device_is_ready (* ccs811 )) {
61- LOG_ERR ("CCS811 sensor not ready" );
62- return - ENODEV ;
63- }
64-
65- /* Initialize HM3301 sensor */
66- * hm3301 = DEVICE_DT_GET (DT_NODELABEL (hm3301 ));
67- if (!device_is_ready (* hm3301 )) {
68- LOG_ERR ("HM3301 sensor not ready" );
69- return - ENODEV ;
70- }
71-
7233 * blink = DEVICE_DT_GET (DT_NODELABEL (blink_led ));
7334 if (!device_is_ready (* blink )) {
7435 LOG_ERR ("Blink LED not ready" );
@@ -81,222 +42,70 @@ static int init_sensors(const struct device **bme280, const struct device **ccs8
8142 return ret ;
8243 }
8344
84- LOG_INF ("All sensors initialized successfully" );
45+ LOG_INF ("Blink LED initialized successfully" );
8546 return 0 ;
8647}
8748
88- static int read_bme280_data (const struct device * sensor , struct sensor_value * temp ,
89- struct sensor_value * press , struct sensor_value * hum )
49+ static void log_sensor_data (const struct sensor_msg * msg )
9050{
91- int ret = sensor_sample_fetch (sensor );
92- if (ret < 0 ) {
93- LOG_ERR ("Could not fetch BME280 sample (%d)" , ret );
94- return ret ;
95- }
51+ /* Log BME280 data */
52+ LOG_INF ("BME280: Temp: %d.%06d C, Press: %d.%06d kPa, Hum: %d.%06d %%" ,
53+ msg -> temperature .val1 , msg -> temperature .val2 , msg -> pressure .val1 ,
54+ msg -> pressure .val2 , msg -> humidity .val1 , msg -> humidity .val2 );
9655
97- ret = sensor_channel_get (sensor , SENSOR_CHAN_AMBIENT_TEMP , temp );
98- if (ret < 0 ) {
99- LOG_ERR ("Could not get temperature (%d)" , ret );
100- return ret ;
101- }
56+ /* Log CCS811 data */
57+ LOG_INF ("CCS811: CO2: %d ppm, VOC: %d ppb" , msg -> co2 .val1 , msg -> voc .val1 );
10258
103- ret = sensor_channel_get (sensor , SENSOR_CHAN_PRESS , press );
104- if (ret < 0 ) {
105- LOG_ERR ("Could not get pressure (%d)" , ret );
106- return ret ;
107- }
59+ /* Log HM3301 data */
60+ LOG_INF ("HM3301: PM1.0: %d ug/m3, PM2.5: %d ug/m3, PM10: %d ug/m3" , msg -> pm1_0 .val1 ,
61+ msg -> pm2_5 .val1 , msg -> pm10 .val1 );
10862
109- ret = sensor_channel_get (sensor , SENSOR_CHAN_HUMIDITY , hum );
110- if (ret < 0 ) {
111- LOG_ERR ("Could not get humidity (%d)" , ret );
112- return ret ;
113- }
114-
115- return 0 ;
63+ LOG_INF ("Sensor data timestamp: %lld ms" , msg -> timestamp );
11664}
11765
118- static int read_ccs811_data (const struct device * sensor , struct sensor_value * co2 ,
119- struct sensor_value * voc )
66+ static void sensor_response_callback (const struct zbus_channel * chan )
12067{
121- int ret = sensor_sample_fetch (sensor );
122- if (ret < 0 ) {
123- LOG_ERR ("Could not fetch CCS811 sample (%d)" , ret );
124- return ret ;
125- }
126-
127- ret = sensor_channel_get (sensor , SENSOR_CHAN_CO2 , co2 );
128- if (ret < 0 ) {
129- LOG_ERR ("Could not get CO2 (%d)" , ret );
130- return ret ;
131- }
68+ const struct sensor_msg * msg ;
13269
133- ret = sensor_channel_get (sensor , SENSOR_CHAN_VOC , voc );
134- if (ret < 0 ) {
135- LOG_ERR ("Could not get VOC (%d)" , ret );
136- return ret ;
137- }
138-
139- return 0 ;
140- }
141-
142- static int read_hm3301_data (const struct device * sensor , struct sensor_value * pm1 ,
143- struct sensor_value * pm25 , struct sensor_value * pm10 )
144- {
145- int ret = sensor_sample_fetch (sensor );
146- if (ret < 0 ) {
147- LOG_ERR ("Could not fetch HM3301 sample (%d)" , ret );
148- return ret ;
149- }
150-
151- ret = sensor_channel_get (sensor , SENSOR_CHAN_PM_1_0 , pm1 );
152- if (ret < 0 ) {
153- LOG_ERR ("Could not get PM1.0 (%d)" , ret );
154- return ret ;
155- }
156-
157- ret = sensor_channel_get (sensor , SENSOR_CHAN_PM_2_5 , pm25 );
158- if (ret < 0 ) {
159- LOG_ERR ("Could not get PM2.5 (%d)" , ret );
160- return ret ;
161- }
162-
163- ret = sensor_channel_get (sensor , SENSOR_CHAN_PM_10 , pm10 );
164- if (ret < 0 ) {
165- LOG_ERR ("Could not get PM10 (%d)" , ret );
166- return ret ;
167- }
168-
169- return 0 ;
170- }
171-
172- #ifdef CONFIG_CCS811_ENV_COMPENSATION
173- static int update_ccs811_env_data (const struct device * ccs811_sensor ,
174- const struct sensor_value * temp , const struct sensor_value * hum )
175- {
176- /* Previous environmental values for smart updates */
177- static struct sensor_value prev_temp = {0 , 0 };
178- static struct sensor_value prev_hum = {0 , 0 };
179- static bool env_data_initialized = false;
180-
181- bool should_update = false;
182-
183- /* Check if this is the first update */
184- if (!env_data_initialized ) {
185- should_update = true;
186- env_data_initialized = true;
187- LOG_INF ("Initializing CCS811 environmental data" );
188- } else {
189- /* Check for significant changes (0.5°C or 0.5% RH threshold) */
190- int32_t temp_diff =
191- abs (SENSOR_VALUE_TO_MICRO (temp ) - SENSOR_VALUE_TO_MICRO (& prev_temp ));
192- int32_t hum_diff =
193- abs (SENSOR_VALUE_TO_MICRO (hum ) - SENSOR_VALUE_TO_MICRO (& prev_hum ));
194-
195- /* Update if temperature or humidity changed beyond thresholds */
196- if (temp_diff >= CCS811_TEMP_THRESHOLD_MICRO ||
197- hum_diff >= CCS811_HUM_THRESHOLD_MICRO ) {
198- should_update = true;
199- LOG_DBG ("Environmental change detected - updating CCS811" );
70+ if (chan == & sensor_chan ) {
71+ msg = & MSG_TO_SENSOR_MSG (zbus_chan_const_msg (chan ));
72+ if (msg != NULL && msg -> type == SENSOR_SAMPLE_RESPONSE ) {
73+ LOG_DBG ("Received sensor response" );
74+ log_sensor_data (msg );
20075 }
20176 }
202-
203- if (should_update ) {
204- int ret = ccs811_envdata_update (ccs811_sensor , temp , hum );
205- if (ret < 0 ) {
206- LOG_ERR ("Could not update CCS811 environmental data (%d)" , ret );
207- return ret ;
208- }
209-
210- LOG_INF ("CCS811 env data updated: T=%d.%06d°C, H=%d.%06d%%" , temp -> val1 , temp -> val2 ,
211- hum -> val1 , hum -> val2 );
212-
213- /* Store current values for next comparison */
214- prev_temp = * temp ;
215- prev_hum = * hum ;
216- }
217-
218- return 0 ;
219- }
220-
221- static void handle_ccs811_env_compensation (const struct device * ccs811_sensor ,
222- const struct sensor_value * temp ,
223- const struct sensor_value * hum )
224- {
225- int env_ret = update_ccs811_env_data (ccs811_sensor , temp , hum );
226- if (env_ret < 0 ) {
227- LOG_ERR ("Failed to update CCS811 environmental data" );
228- }
229- }
230-
231- static void handle_ccs811_fallback_compensation (const struct device * ccs811_sensor )
232- {
233- /* Use default environmental data when BME280 fails */
234- struct sensor_value default_temp = {.val1 = CONFIG_CCS811_DEFAULT_TEMPERATURE , .val2 = 0 };
235- struct sensor_value default_hum = {.val1 = CONFIG_CCS811_DEFAULT_HUMIDITY , .val2 = 0 };
236-
237- LOG_WRN ("Using default environmental data: T=%d°C, H=%d%%RH" ,
238- CONFIG_CCS811_DEFAULT_TEMPERATURE , CONFIG_CCS811_DEFAULT_HUMIDITY );
239-
240- int env_ret = update_ccs811_env_data (ccs811_sensor , & default_temp , & default_hum );
241- if (env_ret < 0 ) {
242- LOG_ERR ("Failed to update CCS811 environmental data with defaults" );
243- }
24477}
245- #endif /* CONFIG_CCS811_ENV_COMPENSATION */
24678
24779int main (void )
24880{
24981 int ret ;
250- const struct device * bme280_sensor , * ccs811_sensor , * hm3301_sensor , * blink ;
251- struct sensor_value temp , press , hum , co2 , voc , pm1 , pm25 , pm10 ;
82+ const struct device * blink ;
25283
25384 LOG_INF ("Zephyr Fire Detection System %s" , APP_VERSION_STRING );
25485
25586 /* Wait for sensors to stabilize */
25687 k_sleep (K_MSEC (SENSORS_WARMUP_DELAY_MS ));
25788
258- /* Initialize all sensors */
259- ret = init_sensors ( & bme280_sensor , & ccs811_sensor , & hm3301_sensor , & blink );
89+ /* Initialize blink LED */
90+ ret = init_blink_led ( & blink );
26091 if (ret < 0 ) {
261- LOG_ERR ("Sensor initialization failed" );
92+ LOG_ERR ("Blink LED initialization failed" );
26293 return 0 ;
26394 }
26495
265- while (1 ) {
266- /* Read BME280 data (temperature, pressure, humidity) */
267- ret = read_bme280_data (bme280_sensor , & temp , & press , & hum );
268- if (ret == 0 ) {
269- LOG_INF ("BME280: Temp: %d.%06d C, Press: %d.%06d kPa, Hum: %d.%06d %%" ,
270- temp .val1 , temp .val2 , press .val1 , press .val2 , hum .val1 , hum .val2 );
271-
272- #ifdef CONFIG_CCS811_ENV_COMPENSATION
273- /* Use BME280 data if reading was successful */
274- handle_ccs811_env_compensation (ccs811_sensor , & temp , & hum );
275- #endif /* CONFIG_CCS811_ENV_COMPENSATION */
276- } else {
277- LOG_ERR ("Failed to read BME280 data" );
278-
279- #ifdef CONFIG_CCS811_ENV_COMPENSATION
280- /* Use fallback environmental data when BME280 fails */
281- handle_ccs811_fallback_compensation (ccs811_sensor );
282- #endif /* CONFIG_CCS811_ENV_COMPENSATION */
283- }
284-
285- /* Read CCS811 data (CO2 and VOC) */
286- ret = read_ccs811_data (ccs811_sensor , & co2 , & voc );
287- if (ret == 0 ) {
288- LOG_INF ("CCS811: CO2: %d ppm, VOC: %d ppb" , co2 .val1 , voc .val1 );
289- } else {
290- LOG_ERR ("Failed to read CCS811 data" );
291- }
96+ /* Initialize sensor module */
97+ ret = sensor_module_init ();
98+ if (ret < 0 ) {
99+ LOG_ERR ("Sensor module initialization failed" );
100+ return 0 ;
101+ }
292102
293- /* Read HM3301 data (PM1.0, PM2.5, PM10) */
294- ret = read_hm3301_data (hm3301_sensor , & pm1 , & pm25 , & pm10 );
295- if (ret == 0 ) {
296- LOG_INF ("HM3301: PM1.0: %d ug/m3, PM2.5: %d ug/m3, PM10: %d ug/m3" ,
297- pm1 .val1 , pm25 .val1 , pm10 .val1 );
298- } else {
299- LOG_ERR ("Failed to read HM3301 data" );
103+ while (1 ) {
104+ /* Request sensor data */
105+ LOG_DBG ("Requesting sensor data" );
106+ ret = sensor_module_request_data ();
107+ if (ret < 0 ) {
108+ LOG_ERR ("Failed to request sensor data (%d)" , ret );
300109 }
301110
302111 k_sleep (K_MSEC (SENSOR_READ_INTERVAL_MS ));
0 commit comments