/* * @Author : stark1898y 1658608470@qq.com * @Date : 2024-06-18 15:48:01 * @LastEditors: mbw && 1600520629@qq.com * @LastEditTime: 2025-02-21 11:27:34 * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\src\bsp_mq.c * @Description : * * Copyright (c) 2024 by yzy, All Rights Reserved. */ /* * @Author : yzy * @Date : 2023-01-30 15:40:07 * @LastEditors : stark1898y 1658608470@qq.com * @LastEditTime : 2023-09-19 16:25:03 * @FilePath : \JT-DT-YD1F01_RTT_Nano\bsp\src\bsp_mq.c * @Description : * * Copyright (c) 2023 by yzy, All Rights Reserved. */ #include "bsp_mq.h" #include "bsp_adc.h" #include "bsp_flash.h" #include "bsp_rtc.h" #include "user_sys.h" #include "finsh.h" #include "bsp_led.h" #include "at_device_ml307.h" #define LOG_TAG "bsp_mq" // 该模块对应的标签。不定义时,默认:NO_TAG #define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别 #include // 必须在 LOG_TAG 与 LOG_LVL 下面 ALIGN(RT_ALIGN_SIZE) static char sensor_thread_stack[GAS_SNESOR_THREAD_STACK_SIZE]; static struct rt_thread Sensor_Thread; rt_uint8_t alarm_flag = 0, fault_flag = 0; TsSensor_t Sensor_device; uint16_t Get_Gas_VoltageInt1000x(void) { uint16_t voltage = (Get_ADC_Average(kGasAdc) * 3.3 / 4096) * MQ_VOLTAGE_RATIO * 1000; LOG_D("Get_Gas_VoltageInt1000x = %04d", voltage); return voltage; } uint16_t Get_Gas_VoltageAdcInt1000x(void) { rt_uint16_t voltage_adc = (Get_ADC_Average(kGasAdc) * 3.3 / 4096) * 1000; LOG_D("Get_Gas_VoltageAdcInt1000x = %04d", voltage_adc); return voltage_adc; } #ifdef TEST_ENABLE static void TEST_Get_Gas_VoltageInt1000x(void) { LOG_D("Get_Gas_VoltageInt1000x = %04d", Get_Gas_VoltageInt1000x()); } MSH_CMD_EXPORT(TEST_Get_Gas_VoltageInt1000x, TEST_Get_Gas_VoltageInt1000x); #endif static uint8_t Sensor_Count(const rt_uint8_t *buffer, uint8_t value, uint8_t size) { uint8_t count = 0; for (uint8_t i = 0; i < size; i++) { if (buffer[i] == value) { count++; } } return count; } static void Sensor_HandleAlarm(uint8_t count, uint8_t threshold) { if (count >= threshold && alarm_flag == 0) { alarm_flag = 1; Sensor_device.detection_flag = kSensorAlarm; Send_Laser_Alarm_Event(kAlarmEvent); } else if (alarm_flag == 1 && count == 0) { alarm_flag = 0; Sensor_device.detection_flag = kSensorNormal; Send_Laser_Alarm_Event(kAlarmRcyEvent); } } static void Sensor_HandleFault(uint8_t count, uint8_t threshold) { if (count >= threshold && fault_flag != 1) { fault_flag = 1; Sensor_device.detection_flag = kSensorFault; Send_Laser_Alarm_Event(kFaultEvent); } else if (fault_flag == 1 && count == 0) { fault_flag = 0; Sensor_device.detection_flag = kSensorNormal; Send_Laser_Alarm_Event(kFaultRcyEvent); } else if (rt_pin_read(LED_Y_PIN) == PIN_HIGH && (count == 0)) { fault_flag = 0; Sensor_device.detection_flag = kSensorNormal; } } static uint8_t Sensor_CheckData(void) { static rt_uint8_t alarm_count = 0, fault_count = 0; static rt_uint8_t index = 0; static rt_uint8_t alarm_status_buffer[SENSOR_SAMPLING_TIMS] = {0}; static rt_uint8_t fault_buf[SENSOR_SAMPLING_TIMS] = {0}; rt_uint16_t voltage = Get_Gas_VoltageAdcInt1000x(); alarm_status_buffer[index] = ((voltage > Sensor_device.alarm_value) && (voltage < MQ_VOLTAGE_HIGH_LIMIT)) ? kSensorAlarm : kSensorNormal; fault_buf[index] = ((voltage < MQ_VOLTAGE_LOW_LIMIT) || (voltage > MQ_VOLTAGE_HIGH_LIMIT)) ? kSensorFault : kSensorNormal; index++; if (index >= SENSOR_SAMPLING_TIMS) { index = 0; } alarm_count = Sensor_Count(alarm_status_buffer, kSensorAlarm, SENSOR_SAMPLING_TIMS); fault_count = Sensor_Count(fault_buf, kSensorFault, SENSOR_SAMPLING_TIMS); Sensor_HandleAlarm(alarm_count, SENSOR_SAMPLING_TIMS); Sensor_HandleFault(fault_count, SENSOR_SAMPLING_TIMS); return RT_EOK; } // TODO: 寿命检测 uint8_t IS_EndOfLife(void) { if (ntp_flag) // 是否同步网络时间 { ntp_flag = 0; RTC_GetTime(); if ((RtcDateTime.year >= 2030) && (work_duration >= 43800)) // 5年后到期 { if (RTC_GetCounter() >= Sensor_device.expiration_seconds) { Sensor_device.end_of_life = 1; } else { Sensor_device.end_of_life = 0; return 0; } } else { Sensor_device.end_of_life = 0; return 0; } } else { Sensor_device.end_of_life = 0; return 0; } return Sensor_device.end_of_life; } // MQ检测线程函数 static void Sensor_detection_thread_entry(void *param) { uint8_t calibration_flag = 0; while (1)//等待标定 { calibration_flag = Flash_Get_Calibration_State(); if(calibration_flag == 1) break; rt_thread_mdelay(1000); Get_Gas_VoltageAdcInt1000x(); } rt_uint16_t alarm_value = Flash_Get_SysCfg(kAlarmLValueId); // 获取系统报警阈值; if ((alarm_value > 4095)||(alarm_value < 300)) { alarm_value = 1600; } Sensor_device.alarm_value = alarm_value; LOG_D("报警阈值:%d", Sensor_device.alarm_value); while (1) { if (SysControl.status > kPreheatingEvent) { Sensor_CheckData(); } rt_thread_mdelay(500); } } int BSP_MQ_Init(void) { rt_thread_init(&Sensor_Thread, // 可以用定时器做,没必要线程 "sensor_thread", Sensor_detection_thread_entry, RT_NULL, &sensor_thread_stack[0], sizeof(sensor_thread_stack), GAS_SENSOR_THREAD_PRIORITY, GAS_SENSOR_THREAD_TIMESLICE); rt_thread_startup(&Sensor_Thread); return 0; } #ifdef RT_USING_COMPONENTS_INIT // INIT_DEVICE_EXPORT(BSP_MQ_Init); #endif #ifdef TEST_ENABLE void TEST_MQ_EndOfLife(void) { Sensor_device.end_of_life = 1; } // MSH_CMD_EXPORT(TEST_MQ_EndOfLife, TEST_MQ_EndOfLife); #endif