grove_digital_light
Revision 0:54ed8f245631, committed 2015-06-09
- Comitter:
- JackyZhangFromSeeed
- Date:
- Tue Jun 09 10:17:49 2015 +0000
- Commit message:
- grove_digital_light
Changed in this revision
diff -r 000000000000 -r 54ed8f245631 grove_digital_light.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/grove_digital_light.cpp Tue Jun 09 10:17:49 2015 +0000 @@ -0,0 +1,155 @@ + + +#include "suli2.h" +#include "grove_digital_light.h" + + + +//local functions +static void grove_digital_light_getlux(I2C_T *i2c); +static unsigned long grove_digital_light_calculatelux(unsigned int iGain, unsigned int tInt, int iType); + +//local variables +static unsigned char cmdbuf[2]; +static uint16_t ch0, ch1; +static unsigned long chScale; +static unsigned long channel1; +static unsigned long channel0; +static unsigned long ratio1; +static unsigned int b; +static unsigned int m; +static unsigned long temp; +static unsigned long lux; + + + +void grove_digital_light_init(I2C_T *i2c, int pinsda, int pinscl) +{ + suli_i2c_init(i2c, pinsda, pinscl); +} + +bool grove_digital_light_write_setup(I2C_T *i2c) +{ + cmdbuf[0] = TSL2561_Control; + cmdbuf[1] = 0x03; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2); // POWER UP + cmdbuf[0] = TSL2561_Timing; + cmdbuf[1] = 0x00; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2); //No High Gain (1x), integration time of 13ms + cmdbuf[0] = TSL2561_Interrupt; + cmdbuf[1] = 0x00; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2); + cmdbuf[0] = TSL2561_Control; + cmdbuf[1] = 0x00; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2); // POWER Down + + return true; +} + +static void grove_digital_light_getlux(I2C_T *i2c) +{ + uint8_t CH0_LOW = 0, CH0_HIGH = 0, CH1_LOW = 0, CH1_HIGH = 0; + + cmdbuf[0] = TSL2561_Channal0L; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1); + suli_i2c_read(i2c, TSL2561_Address, &CH0_LOW, 1); + cmdbuf[0] = TSL2561_Channal0H; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1); + suli_i2c_read(i2c, TSL2561_Address, &CH0_HIGH, 1); + cmdbuf[0] = TSL2561_Channal1L; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1); + suli_i2c_read(i2c, TSL2561_Address, &CH1_LOW, 1); + cmdbuf[0] = TSL2561_Channal1H; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1); + suli_i2c_read(i2c, TSL2561_Address, &CH1_HIGH, 1); + + ch0 = (CH0_HIGH<<8) | CH0_LOW; + ch1 = (CH1_HIGH<<8) | CH1_LOW; +} + +static unsigned long grove_digital_light_calculatelux(unsigned int iGain, unsigned int tInt, int iType) +{ + switch (tInt) + { + case 0: // 13.7 msec + chScale = CHSCALE_TINT0; + break; + case 1: // 101 msec + chScale = CHSCALE_TINT1; + break; + default: // assume no scaling + chScale = (1 << CH_SCALE); + break; + } + if (!iGain) chScale = chScale << 4; // scale 1X to 16X + // scale the channel values + channel0 = (ch0 * chScale) >> CH_SCALE; + channel1 = (ch1 * chScale) >> CH_SCALE; + + ratio1 = 0; + if (channel0!= 0) ratio1 = (channel1 << (RATIO_SCALE+1))/channel0; + // round the ratio value + unsigned long ratio = (ratio1 + 1) >> 1; + + switch (iType) + { + case 0: // T package + if ((ratio >= 0) && (ratio <= K1T)) + {b=B1T; m=M1T;} + else if (ratio <= K2T) + {b=B2T; m=M2T;} + else if (ratio <= K3T) + {b=B3T; m=M3T;} + else if (ratio <= K4T) + {b=B4T; m=M4T;} + else if (ratio <= K5T) + {b=B5T; m=M5T;} + else if (ratio <= K6T) + {b=B6T; m=M6T;} + else if (ratio <= K7T) + {b=B7T; m=M7T;} + else if (ratio > K8T) + {b=B8T; m=M8T;} + break; + case 1:// CS package + if ((ratio >= 0) && (ratio <= K1C)) + {b=B1C; m=M1C;} + else if (ratio <= K2C) + {b=B2C; m=M2C;} + else if (ratio <= K3C) + {b=B3C; m=M3C;} + else if (ratio <= K4C) + {b=B4C; m=M4C;} + else if (ratio <= K5C) + {b=B5C; m=M5C;} + else if (ratio <= K6C) + {b=B6C; m=M6C;} + else if (ratio <= K7C) + {b=B7C; m=M7C;} + } + temp=((channel0*b)-(channel1*m)); + if(temp<0) temp=0; + temp+=(1<<(LUX_SCALE-1)); + // strip off fractional portion + lux=temp>>LUX_SCALE; + return (lux); +} + +bool grove_digital_light_readvisiblelux(I2C_T *i2c, uint32_t *lux) +{ + cmdbuf[0] = TSL2561_Control; + cmdbuf[1] = 0x03; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2); // POWER UP + suli_delay_ms(14); + grove_digital_light_getlux(i2c); + + cmdbuf[0] = TSL2561_Control; + cmdbuf[1] = 0x00; + suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2); // POWER Down + if(ch0/ch1 < 2 && ch0 > 4900) + { + return -1; //ch0 out of range, but ch1 not. the lux is not valid in this situation. + } + *lux = grove_digital_light_calculatelux(0, 0, 0); //T package, no gain, 13ms + return true; +}
diff -r 000000000000 -r 54ed8f245631 grove_digital_light.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/grove_digital_light.h Tue Jun 09 10:17:49 2015 +0000 @@ -0,0 +1,79 @@ + + + +#ifndef __GROVE_DIGITAL_LIGHT_H__ +#define __GROVE_DIGITAL_LIGHT_H__ + +#include "suli2.h" + +#define TSL2561_Address (0x29<<1) //device address + +#define TSL2561_Control 0x80 +#define TSL2561_Timing 0x81 +#define TSL2561_Interrupt 0x86 +#define TSL2561_Channal0L 0x8C +#define TSL2561_Channal0H 0x8D +#define TSL2561_Channal1L 0x8E +#define TSL2561_Channal1H 0x8F + +#define LUX_SCALE 14 // scale by 2^14 +#define RATIO_SCALE 9 // scale ratio by 2^9 +#define CH_SCALE 10 // scale channel values by 2^10 +#define CHSCALE_TINT0 0x7517 // 322/11 * 2^CH_SCALE +#define CHSCALE_TINT1 0x0fe7 // 322/81 * 2^CH_SCALE + +#define K1T 0x0040 // 0.125 * 2^RATIO_SCALE +#define B1T 0x01f2 // 0.0304 * 2^LUX_SCALE +#define M1T 0x01be // 0.0272 * 2^LUX_SCALE +#define K2T 0x0080 // 0.250 * 2^RATIO_SCA +#define B2T 0x0214 // 0.0325 * 2^LUX_SCALE +#define M2T 0x02d1 // 0.0440 * 2^LUX_SCALE +#define K3T 0x00c0 // 0.375 * 2^RATIO_SCALE +#define B3T 0x023f // 0.0351 * 2^LUX_SCALE +#define M3T 0x037b // 0.0544 * 2^LUX_SCALE +#define K4T 0x0100 // 0.50 * 2^RATIO_SCALE +#define B4T 0x0270 // 0.0381 * 2^LUX_SCALE +#define M4T 0x03fe // 0.0624 * 2^LUX_SCALE +#define K5T 0x0138 // 0.61 * 2^RATIO_SCALE +#define B5T 0x016f // 0.0224 * 2^LUX_SCALE +#define M5T 0x01fc // 0.0310 * 2^LUX_SCALE +#define K6T 0x019a // 0.80 * 2^RATIO_SCALE +#define B6T 0x00d2 // 0.0128 * 2^LUX_SCALE +#define M6T 0x00fb // 0.0153 * 2^LUX_SCALE +#define K7T 0x029a // 1.3 * 2^RATIO_SCALE +#define B7T 0x0018 // 0.00146 * 2^LUX_SCALE +#define M7T 0x0012 // 0.00112 * 2^LUX_SCALE +#define K8T 0x029a // 1.3 * 2^RATIO_SCALE +#define B8T 0x0000 // 0.000 * 2^LUX_SCALE +#define M8T 0x0000 // 0.000 * 2^LUX_SCALE + +#define K1C 0x0043 // 0.130 * 2^RATIO_SCALE +#define B1C 0x0204 // 0.0315 * 2^LUX_SCALE +#define M1C 0x01ad // 0.0262 * 2^LUX_SCALE +#define K2C 0x0085 // 0.260 * 2^RATIO_SCALE +#define B2C 0x0228 // 0.0337 * 2^LUX_SCALE +#define M2C 0x02c1 // 0.0430 * 2^LUX_SCALE +#define K3C 0x00c8 // 0.390 * 2^RATIO_SCALE +#define B3C 0x0253 // 0.0363 * 2^LUX_SCALE +#define M3C 0x0363 // 0.0529 * 2^LUX_SCALE +#define K4C 0x010a // 0.520 * 2^RATIO_SCALE +#define B4C 0x0282 // 0.0392 * 2^LUX_SCALE +#define M4C 0x03df // 0.0605 * 2^LUX_SCALE +#define K5C 0x014d // 0.65 * 2^RATIO_SCALE +#define B5C 0x0177 // 0.0229 * 2^LUX_SCALE +#define M5C 0x01dd // 0.0291 * 2^LUX_SCALE +#define K6C 0x019a // 0.80 * 2^RATIO_SCALE +#define B6C 0x0101 // 0.0157 * 2^LUX_SCALE +#define M6C 0x0127 // 0.0180 * 2^LUX_SCALE +#define K7C 0x029a // 1.3 * 2^RATIO_SCALE +#define B7C 0x0037 // 0.00338 * 2^LUX_SCALE +#define M7C 0x002b // 0.00260 * 2^LUX_SCALE +#define K8C 0x029a // 1.3 * 2^RATIO_SCALE +#define B8C 0x0000 // 0.000 * 2^LUX_SCALE +#define M8C 0x0000 // 0.000 * 2^LUX_SCALE + +void grove_digital_light_init(I2C_T *i2c, int pinsda, int pinscl); +bool grove_digital_light_write_setup(I2C_T *i2c); +bool grove_digital_light_readvisiblelux(I2C_T *i2c, uint32_t *lux); + +#endif
diff -r 000000000000 -r 54ed8f245631 grove_digital_light_class.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/grove_digital_light_class.cpp Tue Jun 09 10:17:49 2015 +0000 @@ -0,0 +1,22 @@ + + +#include "grove_digital_light_class.h" + +GroveDigitalLight::GroveDigitalLight(int pinsda, int pinscl) +{ + this->i2c = (I2C_T *)malloc(sizeof(I2C_T)); + grove_digital_light_init(this->i2c, pinsda, pinscl); +} + +bool GroveDigitalLight::write_setup(void) +{ + return grove_digital_light_write_setup(this->i2c); +} + +bool GroveDigitalLight::read_lux(uint32_t *lux) +{ + return grove_digital_light_readvisiblelux(this->i2c, lux); +} + + +
diff -r 000000000000 -r 54ed8f245631 grove_digital_light_class.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/grove_digital_light_class.h Tue Jun 09 10:17:49 2015 +0000 @@ -0,0 +1,24 @@ + + + +#ifndef __GROVE_DIGITAL_LIGHT_CLASS_H__ +#define __GROVE_DIGITAL_LIGHT_CLASS_H__ + +#include "grove_digital_light.h" + +//GROVE_NAME "Grove_DigitalLight" +//IF_TYPE I2C +//IMAGE_URL http://www.seeedstudio.com/wiki/File:Digital_Light_Sensor.jpg + +class GroveDigitalLight +{ +public: + GroveDigitalLight(int pinsda, int pinscl); + bool write_setup(void); + bool read_lux(uint32_t *lux); + +private: + I2C_T *i2c; +}; + +#endif