DHT11偶尔湿度反馈错误解决方法

实验需要读取温湿度使用正点原子开发板,发现偶尔会出现读取湿度值与温度值相同的错误,概率比较低。但是还是会出错,因此使用下列方法进行避免。


 
 int main(void)
 {	 
	uint16 t=0;			    
	//u8 temperature;  	    
	//u8 humidity;    	   

     

    //定义温湿度
    int16 temperature;  	    
    int16 humidity;  
    uint32 index = 0;
    
    #define DEF_LvBSize 80

    static int16 wendu[DEF_LvBSize];
    static int16 shidu[DEF_LvBSize];
    static int16 wendutmp[DEF_LvBSize];
    static int16 shidutmp[DEF_LvBSize]; 
    static int16 Tadd;
    static int16 Radd;
    static uint8 i;
    static uint8 j;
    

     
	delay_init();	    	 //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	uart_init(9600);	 	//串口初始化为115200
	LED_Init();		  		//初始化与LED连接的硬件接口
	LCD_Init();			   	//初始化LCD  
 	POINT_COLOR=RED;		//设置字体为红色 
	LCD_ShowString(30,50,200,16,16,"WarShip STM32");	
	LCD_ShowString(30,70,200,16,16,"DHT11 TEST");	
	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,110,200,16,16,"2015/1/16");	
    
    delay_ms(500);    
 	while(DHT11_Init())	//DHT11初始化	
	{
		LCD_ShowString(30,130,200,16,16,"DHT11 Error");
		delay_ms(200);
		LCD_Fill(30,130,239,130+16,WHITE);
 		delay_ms(200);
        printf("DHT11 Error");
        
	}								   
	LCD_ShowString(30,130,200,16,16,"DHT11 OK");
	POINT_COLOR=BLUE;//设置字体为蓝色 
 	LCD_ShowString(30,150,200,16,16,"Temp:  C");	 
 	LCD_ShowString(30,170,200,16,16,"Humi:  %");
    
    //初始化
//    delay_ms(200);
//    DHT11_Read_Data_int16(&temperature,&humidity);
//    for(i=0;i<DEF_LvBSize;i++){
//        wendu[i] = temperature;
//        shidu[i] = humidity;
//    }
//    
	while(1)
	{	    	    
 		if(t%10==0)			//每100ms读取一次
		{									  
			//DHT11_Read_Data(&temperature,&humidity);	//读取温湿度值					    
			DHT11_Read_Data_int16(&temperature,&humidity);
            LCD_ShowNum(30+40,150,temperature,2,16);	//显示温度	   		   
			LCD_ShowNum(30+40,170,humidity,2,16);		//显示湿度	 	

            for(i=0;i<DEF_LvBSize-1;i++){
                wendu[i] = wendu[i+1];
                shidu[i] = shidu[i+1];
            }
            wendu[DEF_LvBSize-1] = temperature;
            shidu[DEF_LvBSize-1] = humidity;
            
//            Tadd = 0;
//            Radd = 0;
//            for(i=0;i<DEF_LvBSize;i++){
//                Tadd += wendu[i];
//                Radd += shidu[i];
//            }
//            Tadd = Tadd / DEF_LvBSize;
//            Radd = Radd / DEF_LvBSize;
//               
            for(i=0;i<DEF_LvBSize;i++){
                wendutmp[i] = wendu[i];
                shidutmp[i] = shidu[i];
            }
            
            for(i=0;i<DEF_LvBSize;i++){
                for( j = i; j <  DEF_LvBSize; j++ ){
                    if( wendutmp[i] < wendutmp[j] ){
                        Tadd = wendutmp[i];
                        wendutmp[i] = wendutmp[j];
                        wendutmp[j] = Tadd;
                    }
                    if( shidutmp[i] < shidutmp[j] ){
                        Radd = shidutmp[i];
                        shidutmp[i] = shidutmp[j];
                        shidutmp[j] = Tadd;
                    }
                }
            }
            Tadd = wendutmp[DEF_LvBSize/2];
            Radd = shidutmp[DEF_LvBSize/2];
            
            LED1=!LED1;
		}				   
	 	delay_ms(10);
		t++;
		if(t==815)
		{
            static int16 oldShiD;
            if( Radd == Tadd ){
                printf("\t\t\t\t\t\t\t湿度err\r\n");
                if( oldShiD + 60 < Radd ||  oldShiD - 60 > Radd ){
                    Radd = oldShiD;
                    printf("\t\t\t\t\t\told:\t%d\t%d\r\n",oldShiD,Tadd);
                }
            }else{
                oldShiD = Radd;
            }
            printf("\t\tIndex:\t%d\t T: \t%d\t R: \t%d\r\n",index++,Tadd,Radd);
            
			t=0;
			LED0=!LED0;
            
		}
	}
}

其中函数
DHT11_Read_Data_int16(&temperature,&humidity);
原型如下:


//从DHT11读取一次数据
//temp:温度值(范围:0~50.0°)
//humi:湿度值(范围:20%~90.0%)
//返回值:0,正常;1,读取失败
uint8 DHT11_Read_Data_int16(int16  *temp,int16  *humi)    
{        
 	uint8 buf[5];
	uint8 i;

	int16 wendu;
	int16 shidu;

	DHT11_Rst();
	
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			//*humi=buf[0];
			//*temp=buf[2];
			shidu = 10*buf[0] + buf[1];
			//wendu = 10*buf[2] + buf[3]; //需要增加零下温度对buf[3]的高8位进行判断
			if( buf[3]<128) //这样处理需要考虑返回值得数据类型
				wendu = 10*buf[2] + buf[3]; 
			else{
				wendu = 0;//-(10*buf[2] + (buf[3]-128)); 
			}
			*humi=shidu;
			*temp=wendu;
		}
	}else return 1;
	return 0;	    
}

这是在正点原子的试验基础上增加了,小数点后的数据,其他没有修改。
为10秒左右发送一条数据,经过一夜的测试获得如下数据

测试数据截图
在这里插入图片描述
在这里插入图片描述

温湿度曲线图
在这里插入图片描述
说明在长时间测试时可以有效避免当前的偶尔数据错误问题。
当然此种解决方法是回拨了问题的发生,在一些特殊场合不能使用,比如间隔时间更长的场合。就无法与上一次的数据进行正负6%的湿度范围极性对比。
而且如果湿度返回与温度十分接近的情况并没有测试。
至于是不是原有驱动程序的原因,暂时不是很清楚。
或者是不是个别传感器的个例也不是很清楚。
大家有什么更好的解决方案请留言。

再次说明一下我的解决思路,
首先对采集的数据进行冒泡排序,取中值,
再对要发送的数据进行记录,当湿度等于温度时,进行湿度检查如果与上一次发送出去的湿度差值在正负6%以上则认为此次湿度采集有问题,使用上一次的湿度代替当前湿度。
如果温湿度不相等,则记录这一次的湿度值。

特此记录以防防止忘记
anlog
2020年7月5日09:33:19

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值