198 lines
5.1 KiB
C
198 lines
5.1 KiB
C
#define ADC_DEV_NAME "adc1" /* ADC 设备名称 */
|
|
#define ADC_CHANNEL_AIR 5 /* ADC 通道 */
|
|
#define ADC_CHANNEL_PM25 1 /* ADC 通道 */
|
|
#define ADC_CHANNEL_PRESS 6 /* ADC 通道 */
|
|
#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
|
|
#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */
|
|
#include <rtthread.h>
|
|
#include <rtdevice.h>
|
|
#include <drv_gpio.h>
|
|
#include "status.h"
|
|
#include "math.h"
|
|
#include "my_func.h"
|
|
|
|
rt_thread_t Sensor_Thread = RT_NULL;
|
|
|
|
#define THREAD_PRIORITY 25
|
|
#define THREAD_STACK_SIZE 4096
|
|
#define THREAD_TIMESLICE 5
|
|
|
|
#define PM25_READ_TIMES 20
|
|
#define GPIO_PIN GET_PIN(G, 5)
|
|
|
|
#define LOG_TAG "sensor"
|
|
#define DBG_LVL DBG_LOG
|
|
// #define DBG_LVL DBG_INFO
|
|
|
|
#define USE_LOG1
|
|
#define USE_LOG2
|
|
#define USE_LOG3
|
|
// #define USE_LOG4
|
|
#define USE_LOG5
|
|
// #define USE_LOG6
|
|
// #define USE_LOG_D
|
|
#include "logn.h"
|
|
|
|
float ADC_air;
|
|
float ADC_PM25;
|
|
float ADC_pressure;
|
|
|
|
#define MQ2_READ_TIMES 10
|
|
float Air_Read()
|
|
{
|
|
rt_adc_device_t adc_dev; /* ADC 设备句柄 */
|
|
rt_uint32_t value, vol;
|
|
/* 查找设备 */
|
|
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
|
|
/* 使能设备 */
|
|
rt_adc_enable(adc_dev, ADC_CHANNEL_AIR);
|
|
/* 读取采样值 */
|
|
value = rt_adc_read(adc_dev, ADC_CHANNEL_AIR);
|
|
|
|
return value;
|
|
}
|
|
float MQ2_GetData_PPM(void)
|
|
{
|
|
|
|
float tempData = 0;
|
|
|
|
for (uint8_t i = 0; i < MQ2_READ_TIMES; i++)
|
|
{
|
|
tempData += Air_Read();
|
|
;
|
|
rt_thread_mdelay(5);
|
|
;
|
|
}
|
|
tempData /= MQ2_READ_TIMES;
|
|
|
|
float Vol = (tempData * 5 / 4096);
|
|
float RS = (5 - Vol) / (Vol * 0.5);
|
|
float R0 = 6.64;
|
|
|
|
float ppm = pow(11.5428 * R0 / RS, 0.6549f);
|
|
|
|
return ppm;
|
|
}
|
|
float PM25_Read()
|
|
{
|
|
rt_adc_device_t adc_dev; /* ADC 设备句柄 */
|
|
rt_uint32_t value, vol;
|
|
/* 查找设备 */
|
|
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
|
|
/* 使能设备 */
|
|
rt_adc_enable(adc_dev, ADC_CHANNEL_PM25);
|
|
/* 读取采样值 */
|
|
value = rt_adc_read(adc_dev, ADC_CHANNEL_PM25);
|
|
|
|
return value;
|
|
}
|
|
float Pressure_Read()
|
|
{
|
|
rt_adc_device_t adc_dev; /* ADC 设备句柄 */
|
|
rt_uint32_t value, vol;
|
|
/* 查找设备 */
|
|
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
|
|
/* 使能设备 */
|
|
rt_adc_enable(adc_dev, ADC_CHANNEL_PRESS);
|
|
/* 读取采样值 */
|
|
value = rt_adc_read(adc_dev, ADC_CHANNEL_PRESS);
|
|
|
|
return value;
|
|
}
|
|
float PM25_GetData(void)
|
|
{
|
|
int ADCVal;
|
|
int dustVal = 0;
|
|
float Voltage;
|
|
|
|
rt_pin_write(GPIO_PIN, PIN_HIGH); // 置1 开启内部LED
|
|
|
|
rt_hw_us_delay(280);
|
|
ADCVal = PM25_Read();
|
|
rt_hw_us_delay(25);
|
|
rt_pin_write(GPIO_PIN, PIN_LOW); // 置0 关闭内部LED
|
|
rt_hw_us_delay(9680); // 需要脉宽比0.32ms/10ms的PWM信号驱动传感器中的LED
|
|
|
|
Voltage = 3.3f * ADCVal / 4096.f * 2; // 获得AO输出口的电压值
|
|
|
|
dustVal = (0.17 * Voltage - 0.1) * 1000; // 乘以1000单位换成ug/m3//
|
|
|
|
if (dustVal < 0)
|
|
dustVal = 0; // 限位//
|
|
|
|
if (dustVal > 500)
|
|
dustVal = 500;
|
|
|
|
return dustVal;
|
|
}
|
|
|
|
/**
|
|
* @brief 平均值滤波法
|
|
* @param 无
|
|
* @retval 返回滤波后的数据
|
|
*/
|
|
float Get_PM25_Average_Data(void)
|
|
{
|
|
float temp_val = 0;
|
|
float t;
|
|
for (t = 0; t < PM25_READ_TIMES; t++) // #define PM25_READ_TIMES 20 定义读取次数,读这么多次,然后取平均值
|
|
|
|
{
|
|
temp_val += PM25_GetData(); // 读取ADC值
|
|
rt_thread_mdelay(5);
|
|
}
|
|
temp_val /= PM25_READ_TIMES; // 得到平均值
|
|
return temp_val; // 返回算出的ADC平均值
|
|
}
|
|
|
|
int warning_range(char *str, float value, float min, float max)
|
|
{
|
|
if (value < min)
|
|
{
|
|
LOG5("%s's value:%f is too low\n", str, value);
|
|
danger_status();
|
|
return 1;
|
|
}
|
|
else if (value > max)
|
|
{
|
|
LOG5("%s's value:%f is too high\n", str, value);
|
|
danger_status();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int cnt_warning = 0;
|
|
static void sensor_thread(void *parameter)
|
|
{
|
|
while (1)
|
|
{
|
|
ADC_air = MQ2_GetData_PPM(); // 空气质量传感器数值 0-4095 表示从差到优秀
|
|
ADC_PM25 = Get_PM25_Average_Data(); // PM2.5传感器数值0-500 表示从优秀到查差
|
|
ADC_pressure = Pressure_Read(); // 压力传感器数值 0-4095 表示从差到优秀
|
|
// LOG5("ADC_air:%f,ADC_PM25:%f,ADC_pressure:%f", ADC_air, ADC_PM25, ADC_pressure);
|
|
cnt_warning = 0;
|
|
cnt_warning += warning_range("air", ADC_air, 0, 4095);
|
|
cnt_warning += warning_range("PM25", ADC_PM25, 0, 500);
|
|
cnt_warning += warning_range("pressure", ADC_pressure, 3500, 4095);
|
|
cnt_warning+= warning_range("temperature", Temp, 0, 50);
|
|
if (cnt_warning == 0)
|
|
{
|
|
normal_status();
|
|
}
|
|
rt_thread_mdelay(500);
|
|
}
|
|
}
|
|
void sensor_init(void)
|
|
{
|
|
Sensor_Thread = rt_thread_create("sensor", sensor_thread, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
|
|
|
|
if (Sensor_Thread != RT_NULL)
|
|
{
|
|
rt_thread_startup(Sensor_Thread);
|
|
}
|
|
else
|
|
{
|
|
rt_kprintf("Sensor_Thread Create Failed!\n");
|
|
}
|
|
}
|
|
// MSH_CMD_EXPORT_ALIAS(sensor_init, sensor, run my sensors);
|