BLE_TYQ_BJQ_CH32V303/bsp/src/bsp_mq.c

228 lines
6.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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 <ulog.h> // 必须在 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