采用一个Enddevice采集到多种不同的传感器数据类型,从而对其进行处理,可以减少数据的发送量或者减少Enddevice的个数。以下贴出传感器的代码以及协调器的处理代码。
SHT10.c文件
#include "SHT10.h"
#include "OnBoard.h"
/* xus延迟 */
void delay_nus(uint16 xus)
{
for(uint8 i=0;i0;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;i0;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