|
11 | 11 | LOG_MODULE_REGISTER(sensor_module, CONFIG_SENSOR_MODULE_LOG_LEVEL); |
12 | 12 |
|
13 | 13 | /* Macro for type-safe sensor state object initialization */ |
14 | | -#define SENSOR_STATE_OBJECT_INIT() \ |
15 | | - { \ |
16 | | - .ctx = {0}, .current_state = SENSOR_MODULE_STATE_INIT, .current_data = {0}, \ |
17 | | - .error_count = 0, .max_retries = 0, .last_read_time = 0, .read_timeout_ms = 0 \ |
| 14 | +#define SENSOR_STATE_OBJECT_INIT() \ |
| 15 | + { \ |
| 16 | + .ctx = {0}, .current_state = SENSOR_MODULE_STATE_INIT, .current_data = {0}, \ |
| 17 | + .error_count = 0, .max_retries = 0, .last_read_time = 0, .read_timeout_ms = 0, \ |
| 18 | + IF_ENABLED(CONFIG_SENSOR_MODULE_WARMUP_ENABLE, \ |
| 19 | + (.sensor_init_time = 0, .sensor_warmup_complete = {false},)) \ |
18 | 20 | } |
19 | 21 |
|
20 | 22 | /* ZBUS subscriber for sensor requests */ |
@@ -56,6 +58,12 @@ struct sensor_state_object { |
56 | 58 | /* Timing */ |
57 | 59 | int64_t last_read_time; |
58 | 60 | int64_t read_timeout_ms; |
| 61 | + |
| 62 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 63 | + /* Sensor warmup tracking */ |
| 64 | + int64_t sensor_init_time; |
| 65 | + bool sensor_warmup_complete[SENSOR_TYPE_COUNT]; |
| 66 | +#endif |
59 | 67 | }; |
60 | 68 |
|
61 | 69 | /* Forward declarations for state functions */ |
@@ -115,6 +123,11 @@ static void update_sensor_health(struct sensor_health *health, bool success); |
115 | 123 | static const char *get_sensor_name(enum sensor_type type); |
116 | 124 | static void sensor_set_state(struct sensor_state_object *ctx, enum sensor_module_state new_state); |
117 | 125 |
|
| 126 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 127 | +static bool is_sensor_warmup_complete(enum sensor_type type); |
| 128 | +static int64_t get_sensor_warmup_time(enum sensor_type type); |
| 129 | +#endif |
| 130 | + |
118 | 131 | #ifdef CONFIG_CCS811_ENV_COMPENSATION |
119 | 132 | static int update_ccs811_env_data(const struct sensor_value *temp, const struct sensor_value *hum); |
120 | 133 | static void handle_ccs811_env_compensation(const struct sensor_value *temp, |
@@ -246,6 +259,14 @@ static void sensor_state_init_run(void *obj) |
246 | 259 | return; |
247 | 260 | } |
248 | 261 |
|
| 262 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 263 | + /* Initialize warmup timing */ |
| 264 | + ctx->sensor_init_time = k_uptime_get(); |
| 265 | + for (int i = 0; i < SENSOR_TYPE_COUNT; i++) { |
| 266 | + ctx->sensor_warmup_complete[i] = false; |
| 267 | + } |
| 268 | +#endif |
| 269 | + |
249 | 270 | /* Initialize context with configured values */ |
250 | 271 | ctx->error_count = 0; |
251 | 272 | ctx->max_retries = sensor_state_obj.max_retries; |
@@ -292,6 +313,15 @@ static void sensor_state_reading_run(void *obj) |
292 | 313 | continue; |
293 | 314 | } |
294 | 315 |
|
| 316 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 317 | + /* Check if sensor warmup is complete */ |
| 318 | + if (!is_sensor_warmup_complete(i)) { |
| 319 | + LOG_DBG("Sensor SM: %s warmup not complete, skipping read", |
| 320 | + get_sensor_name(i)); |
| 321 | + continue; |
| 322 | + } |
| 323 | +#endif |
| 324 | + |
295 | 325 | int ret = read_sensor_data(i, &ctx->current_data); |
296 | 326 | if (ret == 0) { |
297 | 327 | successful_reads++; |
@@ -319,18 +349,43 @@ static void sensor_state_reading_run(void *obj) |
319 | 349 | } |
320 | 350 | } |
321 | 351 |
|
322 | | - /* Count enabled sensors */ |
| 352 | + /* Count enabled sensors that have completed warmup */ |
323 | 353 | int enabled_sensor_count = 0; |
324 | 354 | for (int i = 0; i < SENSOR_TYPE_COUNT; i++) { |
325 | 355 | if (sensors[i].enabled) { |
| 356 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 357 | + if (is_sensor_warmup_complete(i)) { |
| 358 | + enabled_sensor_count++; |
| 359 | + } |
| 360 | +#else |
326 | 361 | enabled_sensor_count++; |
| 362 | +#endif |
327 | 363 | } |
328 | 364 | } |
329 | 365 |
|
330 | 366 | /* Only publish data if at least one sensor read successfully */ |
331 | 367 | if (successful_reads == 0) { |
| 368 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 369 | + /* Check if any sensors are still warming up */ |
| 370 | + bool any_warming = false; |
| 371 | + for (int i = 0; i < SENSOR_TYPE_COUNT; i++) { |
| 372 | + if (sensors[i].enabled && !is_sensor_warmup_complete(i)) { |
| 373 | + any_warming = true; |
| 374 | + break; |
| 375 | + } |
| 376 | + } |
| 377 | + |
| 378 | + if (any_warming) { |
| 379 | + LOG_DBG("Sensor SM: No readings yet - sensors still warming up"); |
| 380 | + sensor_set_state(ctx, SENSOR_MODULE_STATE_IDLE); |
| 381 | + } else { |
| 382 | + LOG_ERR("Sensor SM: All sensors failed, entering error state"); |
| 383 | + sensor_set_state(ctx, SENSOR_MODULE_STATE_ERROR); |
| 384 | + } |
| 385 | +#else |
332 | 386 | LOG_ERR("Sensor SM: All sensors failed, entering error state"); |
333 | 387 | sensor_set_state(ctx, SENSOR_MODULE_STATE_ERROR); |
| 388 | +#endif |
334 | 389 | } else if (successful_reads < enabled_sensor_count) { |
335 | 390 | LOG_WRN("Sensor SM: Partial sensor failure (%d/%d successful), but publishing " |
336 | 391 | "available data", |
@@ -703,3 +758,47 @@ static void sensor_set_state(struct sensor_state_object *ctx, enum sensor_module |
703 | 758 | ctx->current_state = new_state; |
704 | 759 | smf_set_state(SMF_CTX(ctx), &sensor_states[new_state]); |
705 | 760 | } |
| 761 | + |
| 762 | +#ifdef CONFIG_SENSOR_MODULE_WARMUP_ENABLE |
| 763 | +/* Helper function to get warmup time for a sensor type */ |
| 764 | +static int64_t get_sensor_warmup_time(enum sensor_type type) |
| 765 | +{ |
| 766 | + switch (type) { |
| 767 | + case SENSOR_TYPE_BME280: |
| 768 | + return CONFIG_SENSOR_MODULE_BME280_WARMUP_MS; |
| 769 | + case SENSOR_TYPE_CCS811: |
| 770 | + return CONFIG_SENSOR_MODULE_CCS811_WARMUP_MS; |
| 771 | + case SENSOR_TYPE_HM3301: |
| 772 | + return CONFIG_SENSOR_MODULE_HM3301_WARMUP_MS; |
| 773 | + default: |
| 774 | + return 0; |
| 775 | + } |
| 776 | +} |
| 777 | + |
| 778 | +/* Helper function to check if sensor warmup is complete */ |
| 779 | +static bool is_sensor_warmup_complete(enum sensor_type type) |
| 780 | +{ |
| 781 | + if (type >= SENSOR_TYPE_COUNT) { |
| 782 | + return false; |
| 783 | + } |
| 784 | + |
| 785 | + /* Check if already marked as complete */ |
| 786 | + if (sensor_state_obj.sensor_warmup_complete[type]) { |
| 787 | + return true; |
| 788 | + } |
| 789 | + |
| 790 | + /* Check if warmup time has elapsed */ |
| 791 | + int64_t elapsed_time = k_uptime_get() - sensor_state_obj.sensor_init_time; |
| 792 | + int64_t warmup_time = get_sensor_warmup_time(type); |
| 793 | + |
| 794 | + if (elapsed_time >= warmup_time) { |
| 795 | + /* Mark as complete and log */ |
| 796 | + sensor_state_obj.sensor_warmup_complete[type] = true; |
| 797 | + LOG_INF("Sensor SM: %s warmup complete after %lld ms", get_sensor_name(type), |
| 798 | + elapsed_time); |
| 799 | + return true; |
| 800 | + } |
| 801 | + |
| 802 | + return false; |
| 803 | +} |
| 804 | +#endif /* CONFIG_SENSOR_MODULE_WARMUP_ENABLE */ |
0 commit comments