| project/lightd/etc/lightd.conf | ●●●●● patch | view | raw | blame | history | |
| project/lightd/hal/tsl2561.c | ●●●●● patch | view | raw | blame | history | |
| project/lightd/hal/tsl2561.h | ●●●●● patch | view | raw | blame | history | |
| project/modules/tsl2561.c | ●●●●● patch | view | raw | blame | history | |
| project/modules/tsl2561.h | ●●●●● patch | view | raw | blame | history | |
| utils/tsl2561.c | ●●●●● patch | view | raw | blame | history |
project/lightd/etc/lightd.conf
@@ -11,20 +11,16 @@ tsl2561=1 # TSL2561 光强传感器光强阈值 lux_threshold=0.10 lux_threshold=0.005 # 红外传感器(有人时输出高电平), 格式: {名称:BCM编码:控制电平} # Indoor(#16)<->(black/gray) Hallway(#12)<->(yellow/red) # 测试延时: while true; do gpioget gpiochip0 18; sleep 1; done gpio_inpin={infrared_indoor:23:1},{infrared_hallway:18:1} gpio_inpin={infrared_indoor:24:1},{infrared_hallway:23:1} # 继电器GPIO输出控制, 格式: {名称:BCM编码:控制电平} # Relay(1) <-> #35 Relay(2) <-> #37 gpio_outpin={light_indoor:19:1},{light_hallway:26:1} gpio_outpin={light_indoor:26:1},{light_hallway:19:1} # 红外探测到人后,继电器控制灯亮的时长 light_intval=15 [logger] @@ -65,7 +61,7 @@ pubQos=0 # Publisher上报传感器数据的周期,单位是秒 interval=60 interval=300 [subsciber] project/lightd/hal/tsl2561.c
@@ -147,11 +147,11 @@ int i, fd; int rv = 0; char *dev = TSL2561_I2CDEV; float div = 0.0; unsigned char reg_data[REG_COUNT]; int chn0_data = 0; int chn1_data = 0; int ch0_data = 0; int ch1_data = 0; float ratio = 0.0; if( !lux ) { @@ -174,39 +174,52 @@ { rv = tsl2561_readreg(fd, regs_addr[i], ®_data[i]); if( rv < 0) goto failed; { log_error("TSL2561 read register failed\n"); goto cleanup; } } chn0_data = reg_data[1]*256 + reg_data[0]; /* Channel0 = DATA0HIGH<<8 + DATA0LOW */ chn1_data = reg_data[3]*256 + reg_data[2]; /* channel1 = DATA1HIGH<<8 + DATA1LOW */ rv = 0; ch0_data = (reg_data[1]<<8) + reg_data[0]; /* 通道0:可见光+红外 */ ch1_data = (reg_data[3]<<8) + reg_data[2]; /* 通道1:仅红外 */ if( chn0_data<=0 || chn1_data<0 ) { rv = -2; /* 根据datasheet,饱和时光照强度很大 */ if (ch0_data == 0xFFFF || ch1_data == 0xFFFF) { *lux = 50000.0; goto cleanup; } div = (float)chn1_data / (float)chn0_data; if( div>0 && div<=0.5 ) *lux = 0.304*chn0_data-0.062*chn0_data*pow(div,1.4); else if( div>0.5 && div<=0.61 ) *lux = 0.0224*chn0_data-0.031*chn1_data; else if( div>0.61 && div<=0.8 ) *lux = 0.0128*chn0_data-0.0153*chn1_data; else if( div>0.8 && div<=1.3 ) *lux = 0.00146*chn0_data-0.00112*chn1_data; else if( div>1.3 ) if (ch0_data == 0) { /* 无光照 */ *lux = 0.0; goto cleanup; } ratio = (float)ch1_data / (float)ch0_data; if (ratio >= 0 && ratio <= 0.50) { *lux = 0.0304f * ch0_data - 0.062f * ch0_data * powf(ratio, 1.4f); } else if (ratio <= 0.61) { *lux = 0.0224f * ch0_data - 0.031f * ch1_data; } else if (ratio <= 0.80) { *lux = 0.0128f * ch0_data - 0.0153f * ch1_data; } else if (ratio <= 1.30) { *lux = 0.00146f * ch0_data - 0.00112f * ch1_data; } else { /* 超出有效范围 */ *lux = 0.0; } if (*lux < 0) { /* 确保结果非负 */ *lux = 0.0; } cleanup: tsl2561_power(fd, OFF); failed: close(fd); return rv; } project/lightd/hal/tsl2561.h
@@ -24,7 +24,7 @@ #ifndef _TSL2561_H_ #define _TSL2561_H_ #define TSL2561_I2CDEV "/dev/i2c-0" #define TSL2561_I2CDEV "/dev/i2c-1" #define TSL2561_I2CADDR 0x39 extern int tsl2561_get_lux(float *lux); project/modules/tsl2561.c
@@ -37,8 +37,8 @@ #include <sys/types.h> #include <sys/stat.h> #include "utils.h" #include "logger.h" #include "utils.h" #include "tsl2561.h" @@ -147,11 +147,11 @@ int i, fd; int rv = 0; char *dev = TSL2561_I2CDEV; float div = 0.0; unsigned char reg_data[REG_COUNT]; int chn0_data = 0; int chn1_data = 0; int ch0_data = 0; int ch1_data = 0; float ratio = 0.0; if( !lux ) { @@ -174,39 +174,52 @@ { rv = tsl2561_readreg(fd, regs_addr[i], ®_data[i]); if( rv < 0) goto failed; { log_error("TSL2561 read register failed\n"); goto cleanup; } } chn0_data = reg_data[1]*256 + reg_data[0]; /* Channel0 = DATA0HIGH<<8 + DATA0LOW */ chn1_data = reg_data[3]*256 + reg_data[2]; /* channel1 = DATA1HIGH<<8 + DATA1LOW */ rv = 0; ch0_data = (reg_data[1]<<8) + reg_data[0]; /* 通道0:可见光+红外 */ ch1_data = (reg_data[3]<<8) + reg_data[2]; /* 通道1:仅红外 */ if( chn0_data<=0 || chn1_data<0 ) { rv = -2; /* 根据datasheet,饱和时光照强度很大 */ if (ch0_data == 0xFFFF || ch1_data == 0xFFFF) { *lux = 50000.0; goto cleanup; } div = (float)chn1_data / (float)chn0_data; if( div>0 && div<=0.5 ) *lux = 0.304*chn0_data-0.062*chn0_data*pow(div,1.4); else if( div>0.5 && div<=0.61 ) *lux = 0.0224*chn0_data-0.031*chn1_data; else if( div>0.61 && div<=0.8 ) *lux = 0.0128*chn0_data-0.0153*chn1_data; else if( div>0.8 && div<=1.3 ) *lux = 0.00146*chn0_data-0.00112*chn1_data; else if( div>1.3 ) if (ch0_data == 0) { /* 无光照 */ *lux = 0.0; goto cleanup; } ratio = (float)ch1_data / (float)ch0_data; if (ratio >= 0 && ratio <= 0.50) { *lux = 0.0304f * ch0_data - 0.062f * ch0_data * powf(ratio, 1.4f); } else if (ratio <= 0.61) { *lux = 0.0224f * ch0_data - 0.031f * ch1_data; } else if (ratio <= 0.80) { *lux = 0.0128f * ch0_data - 0.0153f * ch1_data; } else if (ratio <= 1.30) { *lux = 0.00146f * ch0_data - 0.00112f * ch1_data; } else { /* 超出有效范围 */ *lux = 0.0; } if (*lux < 0) { /* 确保结果非负 */ *lux = 0.0; } cleanup: tsl2561_power(fd, OFF); failed: close(fd); return rv; } project/modules/tsl2561.h
@@ -24,7 +24,7 @@ #ifndef _TSL2561_H_ #define _TSL2561_H_ #define TSL2561_I2CDEV "/dev/i2c-0" #define TSL2561_I2CDEV "/dev/i2c-1" #define TSL2561_I2CADDR 0x39 extern int tsl2561_get_lux(float *lux); utils/tsl2561.c
@@ -63,7 +63,7 @@ static const int regs_addr[REG_COUNT]={DATA0LOW, DATA0HIGH, DATA1LOW, DATA1HIGH}; float tsl2561_get_lux(int fd); int tsl2561_get_lux(char *dev, float *lux); static inline void print_datime(void); static inline void banner(const char *progname) @@ -89,7 +89,7 @@ int main(int argc, char **argv) { int fd, rv; int rv; float lux; char *dev = "/dev/i2c-0"; char *progname=NULL; @@ -125,26 +125,17 @@ } } /*+--------------------------------+ *| open /dev/i2c-x device | *+--------------------------------+*/ if( (fd=open(dev, O_RDWR)) < 0) { printf("i2c device '%s' open failed: %s\n", dev, strerror(errno)); return -1; } while(1) { lux = tsl2561_get_lux(fd); if( !tsl2561_get_lux(dev, &lux) ) { print_datime(); printf("TSLl2561 get lux: %.3f\n", lux); } sleep(1); } close(fd); return 0; } @@ -260,17 +251,27 @@ return 0; } float tsl2561_get_lux(int fd) int tsl2561_get_lux(char *dev, float *lux) { int i; int i, fd; int rv = 0; unsigned char reg_data[REG_COUNT]; unsigned char buf; int ch0_data = 0; int ch1_data = 0; float ratio = 0.0; int chn0_data = 0; int chn1_data = 0; if( !lux ) { printf("Invalid input arguments\n"); return -1; } float div = 0.0; float lux = 0.0; if( (fd=open(dev, O_RDWR)) < 0) { printf("i2c device '%s' open failed: %s\n", dev, strerror(errno)); return -2; } tsl2561_power(fd, ON); @@ -279,38 +280,56 @@ /* Read register Channel0 and channel1 data from register */ for(i=0; i<REG_COUNT; i++) { tsl2561_readreg(fd, regs_addr[i], ®_data[i]); } chn0_data = reg_data[1]*256 + reg_data[0]; /* Channel0 = DATA0HIGH<<8 + DATA0LOW */ chn1_data = reg_data[3]*256 + reg_data[2]; /* channel1 = DATA1HIGH<<8 + DATA1LOW */ if( chn0_data<=0 || chn1_data<0 ) rv = tsl2561_readreg(fd, regs_addr[i], ®_data[i]); if( rv < 0) { lux = 0.0; goto OUT; printf("TSL2561 read register failed\n"); goto cleanup; } } div = (float)chn1_data / (float)chn0_data; rv = 0; ch0_data = (reg_data[1]<<8) + reg_data[0]; /* 通道0:可见光+红外 */ ch1_data = (reg_data[3]<<8) + reg_data[2]; /* 通道1:仅红外 */ if( div>0 && div<=0.5 ) lux = 0.304*chn0_data-0.062*chn0_data*pow(div,1.4); else if( div>0.5 && div<=0.61 ) lux = 0.0224*chn0_data-0.031*chn1_data; /* 根据datasheet,饱和时光照强度很大 */ if (ch0_data == 0xFFFF || ch1_data == 0xFFFF) { *lux = 50000.0; goto cleanup; } else if( div>0.61 && div<=0.8 ) lux = 0.0128*chn0_data-0.0153*chn1_data; if (ch0_data == 0) { /* 无光照 */ *lux = 0.0; goto cleanup; } else if( div>0.8 && div<=1.3 ) lux = 0.00146*chn0_data-0.00112*chn1_data; ratio = (float)ch1_data / (float)ch0_data; else if( div>1.3 ) lux = 0.0; if (ratio >= 0 && ratio <= 0.50) { *lux = 0.0304f * ch0_data - 0.062f * ch0_data * powf(ratio, 1.4f); } else if (ratio <= 0.61) { *lux = 0.0224f * ch0_data - 0.031f * ch1_data; } else if (ratio <= 0.80) { *lux = 0.0128f * ch0_data - 0.0153f * ch1_data; } else if (ratio <= 1.30) { *lux = 0.00146f * ch0_data - 0.00112f * ch1_data; } else { /* 超出有效范围 */ *lux = 0.0; } OUT: if (*lux < 0) { /* 确保结果非负 */ *lux = 0.0; } cleanup: tsl2561_power(fd, OFF); return lux; close(fd); return rv; } static inline void dump_buf(const char *prompt, char *buf, int size)