/* * 文件: components/fire_sensor/fire_sensor.c * 角色: 火焰传感器 ADC 采样与危险判定 * 说明: * - 本文件用于实现当前模块的核心功能或接口定义。 * - 修改前请先确认该模块与其它任务/外设之间的数据流关系。 * - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。 */ #include "fire_sensor.h" #include "MQ-2.h" #include "esp_adc/adc_oneshot.h" #include "esp_check.h" #define FIRE_ADC_UNIT ADC_UNIT_1 #define FIRE_ADC_CHANNEL ADC_CHANNEL_2 #define FIRE_SAMPLE_COUNT 8 static const char *TAG = "fire_sensor"; static adc_oneshot_unit_handle_t s_adc_handle = NULL; static bool s_inited = false; /* 函数: fire_sensor_init * 作用: 执行模块内与函数名对应的业务逻辑。 * 重点: 关注输入合法性、返回码与并发安全。 */ esp_err_t fire_sensor_init(void) { if (s_inited) { return ESP_OK; } // Reuse ADC1 oneshot unit created by MQ-2 to avoid "adc1 is already in use". ESP_RETURN_ON_ERROR(mq2_init(), TAG, "mq2 init failed"); s_adc_handle = mq2_get_adc_handle(); ESP_RETURN_ON_FALSE(s_adc_handle != NULL, ESP_ERR_INVALID_STATE, TAG, "shared adc handle is null"); adc_oneshot_chan_cfg_t chan_cfg = { .atten = ADC_ATTEN_DB_12, .bitwidth = ADC_BITWIDTH_DEFAULT, }; ESP_RETURN_ON_ERROR(adc_oneshot_config_channel(s_adc_handle, FIRE_ADC_CHANNEL, &chan_cfg), TAG, "adc channel config failed"); s_inited = true; return ESP_OK; } /* 函数: fire_sensor_read_raw * 作用: 执行模块内与函数名对应的业务逻辑。 * 重点: 关注输入合法性、返回码与并发安全。 */ esp_err_t fire_sensor_read_raw(int *raw_out) { ESP_RETURN_ON_FALSE(raw_out != NULL, ESP_ERR_INVALID_ARG, TAG, "raw_out is null"); ESP_RETURN_ON_FALSE(s_inited, ESP_ERR_INVALID_STATE, TAG, "fire sensor not initialized"); int sum = 0; for (int i = 0; i < FIRE_SAMPLE_COUNT; ++i) { int sample = 0; ESP_RETURN_ON_ERROR(adc_oneshot_read(s_adc_handle, FIRE_ADC_CHANNEL, &sample), TAG, "adc read failed"); sum += sample; } *raw_out = sum / FIRE_SAMPLE_COUNT; return ESP_OK; } /* 函数: fire_sensor_read_percent * 作用: 执行模块内与函数名对应的业务逻辑。 * 重点: 关注输入合法性、返回码与并发安全。 */ esp_err_t fire_sensor_read_percent(float *percent_out) { ESP_RETURN_ON_FALSE(percent_out != NULL, ESP_ERR_INVALID_ARG, TAG, "percent_out is null"); int raw = 0; ESP_RETURN_ON_ERROR(fire_sensor_read_raw(&raw), TAG, "read raw failed"); // Most flame modules output lower voltage when flame is stronger. // Map raw inversely to "danger percent": // raw=4095 -> 0%, raw=0 -> 100% *percent_out = ((4095.0f - (float)raw) * 100.0f) / 4095.0f; if (*percent_out < 0.0f) { *percent_out = 0.0f; } else if (*percent_out > 100.0f) { *percent_out = 100.0f; } return ESP_OK; } /* 函数: fire_sensor_is_danger * 作用: 执行模块内与函数名对应的业务逻辑。 * 重点: 关注输入合法性、返回码与并发安全。 */ bool fire_sensor_is_danger(float percent, float threshold_percent) { return percent >= threshold_percent; }