grove_digital_light
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 21:35:27 by 1.7.2