采用一个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