数据融合__1(采集温湿度sht10和光照强度BH1750为例)

  采用一个Enddevice采集到多种不同的传感器数据类型,从而对其进行处理,可以减少数据的发送量或者减少Enddevice的个数。以下贴出传感器的代码以及协调器的处理代码。

  SHT10.c文件

 
 
#include "SHT10.h"
#include "OnBoard.h"

/*  xus延迟  */
void delay_nus(uint16 xus)    
{         
  for(uint8 i=0;i<xus;i++)
  {
    MicroWait (1);
  }
}


/*  xms延时  */
void delay_nms(unsigned int xms)	
{						
   uint8 i,j;
   for(j=xms;j>0;j--)
   {
     for(i=0;i<100;i++)
     {
      delay_nus(10);
     }
   }					
}

void I2CStart (void)
{
  P0DIR |= 0x10;
  CLK = 1;                      //拉高时钟线
  delay_nus(1);                 //延时
  DATA = 0;                     //产生下降沿
  delay_nus(1);                 //延时
  CLK = 0;                      //拉低时钟线
  delay_nus(1);
  CLK = 1;
  delay_nus(1);
  DATA = 1;
  delay_nus(1);
  CLK = 0;                      //拉低时钟线
  delay_nus(1);
}


void I2CStop (void)
{
  P0DIR |= 0x10;
  DATA = 0;                     //拉低数据线
  CLK = 1;                      //拉高时钟线
  delay_nus(1);                 //延时
  DATA = 1;                     //产生上升沿
  delay_nus(1);                 //延时
  CLK = 1;                      //拉低时钟线
  delay_nus(1);
  CLK = 0;
  DATA = 0;
  delay_nus(1);
}

void I2CReset (void)
{
  P0DIR |= 0x10;
  
  for(uint8 i=0;i<10;i++)
  {
    DATA = 1;
    CLK = 1;
    delay_nus(1);
    CLK = 0;
    delay_nus(1);
  }
  DATA = 1;
  delay_nus(1);
  CLK = 0;
}
  

void I2CSendACK (void)
{
  P0DIR |= 0x10;
  DATA = ACK;
  CLK = 1;
  delay_nus(1);
  CLK = 0;
  delay_nus(1);
  DATA = 1;
}

void WriteCmd (uint8 Cmd)
{
  P0DIR |= 0x10;
  I2CStart();
  for(uint8 i=0;i<8;i++)
  {
    if(Cmd & 0x80)
      DATA = 1;
    else
      DATA = 0;
    delay_nus(1);
    CLK = 1;
    delay_nus(1);
    CLK = 0;
    delay_nus(1);
    Cmd <<= 1;
  }
  I2CSendACK();
}


uint16 ReadData (void)
{
  uint8 data[2] = {0};
  uint16 date_u16 = 0;
  uint8 i;
  P0DIR &= ~0x10;
  while(DATA);
  //delay_nus(5);
  for(i=0;i<8;i++)
  {
    data[0] <<= 1;
    CLK = 1;
    delay_nus(1);
    if(DATA)
      data[0] |= 0x01;
    CLK = 0;
    delay_nus(1);
  }
  
  I2CSendACK();
  P0DIR &= ~0x10;  
  
  for(i=0;i<8;i++)
  {
    data[1] <<= 1;
    CLK = 1;
    delay_nus(1);
    if(DATA)
      data[1] |= 0x01;
    CLK = 0;
    delay_nus(1);
    
  }
  DATA = 1;
  
  date_u16 = ((uint16)(((data[1]) & 0x00FF) + (((data[0]) & 0x00FF) << 8)));
  return date_u16;
}

void I2CInit (void)
{
  P0INP |= 0x30;
  P0SEL &= ~0X30;
  P0DIR |= 0X20;
}

uint16 MeasureHuim (void)
{
  uint16 Huim_u16;
  I2CReset();
  WriteCmd(HUIM_CMD);
  Huim_u16 = ReadData();
  Huim_Compensate(&Huim_u16);
  return Huim_u16;
}


int MeasureTemp (void)
{
  int Temp_u16;
  I2CReset();
  WriteCmd(TEMP_CMD);
  Temp_u16 = (int)ReadData();
  Temp_Compensate(&Temp_u16);
  return Temp_u16;
}



void Temp_Compensate(int* temp )
{
  *temp &= 0x3FFF;
  *temp = (int)(((0.01 * (*temp)) - 39.66)*100);
}


void Huim_Compensate( uint16* huim )
{
  *huim &= 0x0FFF;
  *huim = (uint16)(((0.0405 * (*huim)) -  (2.8/1000000 * (*huim )* (*huim)) - 4) * 100);
}


以下为BH1750.c文件

 
 
#include "bh1750.h"


static void delay_nus(void)
{        
  int i;
  int n=100;
  for(i=0;i<n;i++)
  {
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
  }
}

static void delay_nms(int n)
{
  while(n--)
  {
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");
  }
}


/****************************
*****************************/

static void start_i2c(void)
{
  SDA_W() ;
     //LIGHT_SCK_0() ;
     //delay_nus(20);
  LIGHT_DTA_1();//
  LIGHT_SCK_1() ;//
  delay_nus() ;
  LIGHT_DTA_0() ;
  delay_nus()  ;
  LIGHT_SCK_0() ;
  delay_nus()  ;
  //delay()  ;
}


/********************************

缁撴潫I2C

鏁版嵁鍦ㄦ椂閽熼珮鐢靛钩鐨勬椂鍊欎粠浣庡線楂樿穬鍙?********************************/

static void stop_i2c(void)
{
  SDA_W() ;
  LIGHT_DTA_0() ;
  delay_nus();
  LIGHT_SCK_1() ;
  delay_nus();
  LIGHT_DTA_1() ;
  delay_nus();
  LIGHT_SCK_0() ;
  delay_nus();  
}

/******************************
鍙戦€佸瓧鑺傚苟涓斿垽鏂槸鍚︽敹鍒癆CK
褰撴敹鍒癆CK杩斿洖涓?锛屽惁鍒欒繑鍥炰负1

******************************/
static char i2c_send(unsigned char val)                 
{
        int i;
        char error=0;
        SDA_W();
        for(i=0x80;i>0;i/=2)
		{
			if(val&i)
				LIGHT_DTA_1();
			else
				LIGHT_DTA_0();
			delay_nus();
			LIGHT_SCK_1() ; 
			delay_nus();
			LIGHT_SCK_0() ;
			delay_nus();					
		}
        LIGHT_DTA_1();
        SDA_R();
        //delay_nus();
        LIGHT_SCK_1() ; 
        delay_nus();
        if(LIGHT_DTA())
            error=1;
        delay_nus();
        LIGHT_SCK_0() ;
        return error;
        
}

/***************************
璇诲彇I2C鐨勫瓧鑺傦紝骞朵笖鍙戦€丄CK
褰撳弬鏁颁负1鐨勬椂鍊欏彂閫佷竴涓狝CK(浣庣數骞?
**************************/
static char i2c_read(char ack)
{
        int i;
        char val=0;
        LIGHT_DTA_1();
        //SDA_R();
        for(i=0x80;i>0;i/=2)
                {
                        
                        LIGHT_SCK_1() ;
                        delay_nus();
                        SDA_R();
                        //SDA_W();
                        //LIGHT_DTA_0();
                        //LIGHT_DTA_0() ;
                        
                        //delay_nus();
                        if(LIGHT_DTA())
                                val=(val|i);
                        delay_nus();
                        //SDA_R();
                        LIGHT_SCK_0() ;
                        delay_nus();
                        
                        
                }
        SDA_W();
        if(ack)
                LIGHT_DTA_0();
        else
                LIGHT_DTA_1();
        delay_nus();
        LIGHT_SCK_1() ;
        delay_nus();
        LIGHT_SCK_0() ;
        LIGHT_DTA_1();
        return val;
        
}

/**************************
娴嬮噺鍏夊紶寮哄害
***************************/
unsigned short get_light(void)
{        
        unsigned char ack1=1;
        unsigned char ack2=1;
        unsigned char ack3=1;
        unsigned char ack4=1;
        unsigned char ack5=1;
        unsigned char ack6=1;
        unsigned char ack7=1;
        
        unsigned char t0;
        unsigned char t1;
        unsigned short t;

        P0DIR |= (1 << 1);
        delay_nms(200);

		start_i2c();
		ack1=i2c_send(0x46);
		if(ack1)
				return 255;
		ack2=i2c_send(0x01);
		if(ack2)
				return 254;
		stop_i2c();           //init
		start_i2c();
		ack3=i2c_send(0x46);
		if(ack3)
				return 253;
		ack4=i2c_send(0x01);
		if(ack4)
				return 252;
		stop_i2c();//power
		start_i2c();
		ack5=i2c_send(0x46);
		if(ack5)
				return 251;
		ack6=i2c_send(0x10);
		if(ack6)
				return 250;
		stop_i2c();                     
        delay_nms(1500);
        start_i2c();
        
		ack7=i2c_send(0x47);
		if(ack7)
				return 249;
                        
        t0 = i2c_read(1);
        t1 = i2c_read(0);
        stop_i2c();
        t =  ((short)t0)<<8;
        t |= t1;
        return t;
}


最后为协调器的数据处理代码:

void SampleApp_SendPointToPointMessage( uint8* Data )
{
  //if(1 == SENSOR)
  
    int temp;
    uint16 huim; 
    //uint8 lightdata[20];
    unsigned long light;
    light=get_light();
    huim = MeasureHuim();
    temp = MeasureTemp();
    
    Data[0] = huim/1000 + '0';
    Data[1] = huim%1000/100 + '0';
    Data[2] = '.';
    Data[3] = huim%100/10 + '0';
    Data[4] = huim%10 + '0';
    Data[5] = '%';
    
    if(temp >= 0)
    {
      Data[6] = temp/1000 + '0';
      Data[7] = temp%1000/100 + '0';
      Data[8] = '.';
      Data[9] = temp%100/10 + '0';
      Data[10] = temp%10 + '0';
      Data[11] = 'C';
      Data[12] = ' ';
    }
    else
    {
      temp &= ~0x1000;
      Data[6] = '-';
      Data[7] = temp/1000 + '0';
      Data[8] = temp%1000/100 + '0';
      Data[9] = '.';
      Data[10] = temp%100/10 + '0';
      Data[11] = temp%10 + '0';
      Data[12] = 'C';
      
    }
  
    Data[13]=light/10000+'0';
    Data[14]=light%10000/1000+'0';
    Data[15]=light%1000/100+'0';
    Data[16]=light%100/10+'0';
    Data[17]=light%10+'0';
    
      if ( AF_DataRequest( &Point_To_Point_DstAddr,
                       &SampleApp_epDesc,
                       SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
                       18,
                       Data,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE,
                       AF_DEFAULT_RADIUS ) == afStatus_SUCCESS );
  }

    可以实现单结点对多传感器的采集以及上传至协调器。最后效果如下图所示:


PS:期间遇到一个小问题就是光照强度一直显示255,原因肯定是代码有问题。

      1.之前另外一位同学出现这种情况是因为只定义了一个字节的变量,因此最大只能显示255。(如果小于255勒克斯能正常显示,大于则显示255)

     2.如果一直显示255的话,十之有八九是IO的配置还有I2C的时序有可能出问题了。当然还有数据的处理显示均需要仔细排查下。上述几部分代码均已贴出。下方为整个Zstack工程的代码。

最后附上代码链接:https://download.csdn.net/download/wearlee/10413871

猜你喜欢

转载自blog.csdn.net/wearlee/article/details/80313667