#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 #include #include #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);