grove_digital_light

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers grove_digital_light.cpp Source File

grove_digital_light.cpp

00001 
00002 
00003 #include "suli2.h"
00004 #include "grove_digital_light.h"
00005 
00006 
00007 
00008 //local functions
00009 static void grove_digital_light_getlux(I2C_T *i2c);
00010 static unsigned long grove_digital_light_calculatelux(unsigned int iGain, unsigned int tInt, int iType);
00011 
00012 //local variables
00013 static unsigned char cmdbuf[2];
00014 static uint16_t ch0, ch1;
00015 static unsigned long chScale;
00016 static unsigned long channel1;
00017 static unsigned long channel0;
00018 static unsigned long  ratio1;
00019 static unsigned int b;
00020 static unsigned int m;
00021 static unsigned long temp;
00022 static unsigned long lux;
00023 
00024 
00025 
00026 void grove_digital_light_init(I2C_T *i2c, int pinsda, int pinscl)
00027 {
00028     suli_i2c_init(i2c, pinsda, pinscl);
00029 }
00030 
00031 bool grove_digital_light_write_setup(I2C_T *i2c)
00032 {
00033     cmdbuf[0] = TSL2561_Control;
00034     cmdbuf[1] = 0x03;
00035     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2);  // POWER UP
00036     cmdbuf[0] = TSL2561_Timing;
00037     cmdbuf[1] = 0x00;
00038     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2);  //No High Gain (1x), integration time of 13ms
00039     cmdbuf[0] = TSL2561_Interrupt;
00040     cmdbuf[1] = 0x00;
00041     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2);  
00042     cmdbuf[0] = TSL2561_Control;
00043     cmdbuf[1] = 0x00;
00044     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2);  // POWER Down
00045     
00046     return true;
00047 }
00048 
00049 static void grove_digital_light_getlux(I2C_T *i2c)
00050 {
00051     uint8_t CH0_LOW = 0, CH0_HIGH = 0, CH1_LOW = 0, CH1_HIGH = 0;
00052 
00053     cmdbuf[0] = TSL2561_Channal0L;
00054     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1);
00055     suli_i2c_read(i2c, TSL2561_Address, &CH0_LOW, 1);
00056     cmdbuf[0] = TSL2561_Channal0H;
00057     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1);
00058     suli_i2c_read(i2c, TSL2561_Address, &CH0_HIGH, 1);
00059     cmdbuf[0] = TSL2561_Channal1L;
00060     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1);
00061     suli_i2c_read(i2c, TSL2561_Address, &CH1_LOW, 1);
00062     cmdbuf[0] = TSL2561_Channal1H;
00063     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 1);
00064     suli_i2c_read(i2c, TSL2561_Address, &CH1_HIGH, 1);
00065 
00066     ch0 = (CH0_HIGH<<8) | CH0_LOW;
00067     ch1 = (CH1_HIGH<<8) | CH1_LOW;
00068 }
00069 
00070 static unsigned long grove_digital_light_calculatelux(unsigned int iGain, unsigned int tInt, int iType)
00071 {
00072     switch (tInt)
00073     {
00074         case 0:  // 13.7 msec
00075             chScale = CHSCALE_TINT0;
00076             break;
00077         case 1: // 101 msec
00078             chScale = CHSCALE_TINT1;
00079             break;
00080         default: // assume no scaling
00081             chScale = (1 << CH_SCALE);
00082             break;
00083     }
00084     if (!iGain)  chScale = chScale << 4; // scale 1X to 16X
00085     // scale the channel values
00086     channel0 = (ch0 * chScale) >> CH_SCALE;
00087     channel1 = (ch1 * chScale) >> CH_SCALE;
00088 
00089     ratio1 = 0;
00090     if (channel0!= 0) ratio1 = (channel1 << (RATIO_SCALE+1))/channel0;
00091     // round the ratio value
00092     unsigned long ratio = (ratio1 + 1) >> 1;
00093 
00094     switch (iType)
00095     {
00096         case 0: // T package
00097             if ((ratio >= 0) && (ratio <= K1T))
00098             {b=B1T; m=M1T;}
00099             else if (ratio <= K2T)
00100             {b=B2T; m=M2T;}
00101             else if (ratio <= K3T)
00102             {b=B3T; m=M3T;}
00103             else if (ratio <= K4T)
00104             {b=B4T; m=M4T;}
00105             else if (ratio <= K5T)
00106             {b=B5T; m=M5T;}
00107             else if (ratio <= K6T)
00108             {b=B6T; m=M6T;}
00109             else if (ratio <= K7T)
00110             {b=B7T; m=M7T;}
00111             else if (ratio > K8T)
00112             {b=B8T; m=M8T;}
00113             break;
00114         case 1:// CS package
00115             if ((ratio >= 0) && (ratio <= K1C))
00116             {b=B1C; m=M1C;}
00117             else if (ratio <= K2C)
00118             {b=B2C; m=M2C;}
00119             else if (ratio <= K3C)
00120             {b=B3C; m=M3C;}
00121             else if (ratio <= K4C)
00122             {b=B4C; m=M4C;}
00123             else if (ratio <= K5C)
00124             {b=B5C; m=M5C;}
00125             else if (ratio <= K6C)
00126             {b=B6C; m=M6C;}
00127             else if (ratio <= K7C)
00128             {b=B7C; m=M7C;}
00129     }
00130     temp=((channel0*b)-(channel1*m));
00131     if(temp<0) temp=0;
00132     temp+=(1<<(LUX_SCALE-1));
00133     // strip off fractional portion
00134     lux=temp>>LUX_SCALE;
00135     return (lux);
00136 }
00137 
00138 bool grove_digital_light_readvisiblelux(I2C_T *i2c, uint32_t *lux)
00139 {
00140     cmdbuf[0] = TSL2561_Control;
00141     cmdbuf[1] = 0x03;
00142     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2);  // POWER UP
00143     suli_delay_ms(14);
00144     grove_digital_light_getlux(i2c);
00145 
00146     cmdbuf[0] = TSL2561_Control;
00147     cmdbuf[1] = 0x00;
00148     suli_i2c_write(i2c, TSL2561_Address, cmdbuf, 2);  // POWER Down
00149     if(ch0/ch1 < 2 && ch0 > 4900)
00150     {
00151         return -1;  //ch0 out of range, but ch1 not. the lux is not valid in this situation.
00152     }
00153     *lux = grove_digital_light_calculatelux(0, 0, 0);  //T package, no gain, 13ms
00154     return true;
00155 }