Skip to content

Commit 3fd1bf1

Browse files
committed
refctored API
refactored API and added calibrations apis to normileze the value between 0 and 255 added debug dumping registers and allowed for manage all the registers parameters
1 parent 0011962 commit 3fd1bf1

File tree

2 files changed

+243
-30
lines changed

2 files changed

+243
-30
lines changed

src/LTR381RGB.cpp

Lines changed: 222 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
#define LTR381RGB_ALS_THRES_LTV_3 0X26
3434

3535
enum {
36-
ADC_RES_16BIT = 0x00,
37-
ADC_RES_17BIT = 0x01,
36+
ADC_RES_20BIT = 0x00,
37+
ADC_RES_19BIT = 0x01,
3838
ADC_RES_18BIT = 0x02,
39-
ADC_RES_19BIT = 0x03,
40-
ADC_RES_20BIT = 0x04,
39+
ADC_RES_17BIT = 0x03,
40+
ADC_RES_16BIT = 0x04,
4141
};
4242

4343
enum {
@@ -46,6 +46,9 @@ enum {
4646
ADC_MEAS_RATE_100MS = 0x02,
4747
ADC_MEAS_RATE_200MS = 0x03,
4848
ADC_MEAS_RATE_400MS = 0x04,
49+
ADC_MEAS_RATE_500MS = 0x05,
50+
ADC_MEAS_RATE_1000MS = 0x06,
51+
ADC_MEAS_RATE_2000MS = 0x07,
4952
};
5053

5154
enum {
@@ -71,6 +74,9 @@ int LTR381RGBClass::begin() {
7174

7275
uint8_t res = readRegister(LTR381RGB_PART_ID);
7376
if ((res & 0xF0) != 0xC0) {
77+
#ifdef DEBUG
78+
dumpReg();
79+
#endif
7480
return 0;
7581
}
7682

@@ -79,12 +85,13 @@ int LTR381RGBClass::begin() {
7985
if ((res & 0x20) != 0) {
8086
return 0;
8187
}
82-
88+
setCalibrations(158, 137, 155, 1, 1, 0);
8389
enableALSInterrupt();
84-
setGain(ALS_CS_GAIN_1);
85-
86-
setUpperThreshold(10000);
87-
setLowerThreshold(100);
90+
setGain(ALS_CS_GAIN_18);
91+
setMeasurementRate(ADC_MEAS_RATE_25MS);
92+
setADCResolution(ADC_RES_16BIT);
93+
setUpperThreshold(_upperThreshold);
94+
setLowerThreshold(lowerThreshold);
8895
return 1;
8996
}
9097

@@ -95,23 +102,59 @@ void LTR381RGBClass::end() {
95102
int LTR381RGBClass::readColors(int& r, int& g, int& b) {
96103
enableRGB();
97104
unsigned long start = millis();
98-
while(!available() && (millis() - start) < _timeout);
105+
while(!available() && (millis() - start) < _timeout) {
106+
delay(50);
107+
}
108+
disableMeas();
109+
uint8_t buf[9] = {0};
110+
int res = readRegisters(LTR381RGB_CS_DATA_GREEN, buf, 9);
111+
if(res != 1) {
112+
return 0;
113+
}
114+
if (_calibrated) {
115+
int lg = adcToValue((buf[2] << 16 | buf[1] << 8 | buf[0]));
116+
int lr = adcToValue((buf[5] << 16 | buf[4] << 8 | buf[3]));
117+
int lb = adcToValue((buf[8] << 16 | buf[7] << 8 | buf[6]));
118+
r = normAndTrim(lr, _minR, _maxR);
119+
g = normAndTrim(lg, _minG, _maxG);
120+
b = normAndTrim(lb, _minB, _maxB);
121+
122+
} else {
123+
g = adcToValue((buf[2] << 16 | buf[1] << 8 | buf[0]));
124+
r = adcToValue((buf[5] << 16 | buf[4] << 8 | buf[3]));
125+
b = adcToValue((buf[8] << 16 | buf[7] << 8 | buf[6]));
126+
}
127+
128+
return 1;
129+
}
130+
131+
int LTR381RGBClass::readRawColors(int& r, int& g, int& b) {
132+
enableRGB();
133+
unsigned long start = millis();
134+
while(!available() && (millis() - start) < _timeout) {
135+
delay(50);
136+
}
137+
disableMeas();
99138
uint8_t buf[9] = {0};
100139
int res = readRegisters(LTR381RGB_CS_DATA_GREEN, buf, 9);
101140
if(res != 1) {
102141
return 0;
103142
}
104-
g = buf[2] << 16 | buf[1] << 8 | buf[0];
105-
r = buf[5] << 16 | buf[4] << 8 | buf[3];
106-
b = buf[8] << 16 | buf[7] << 8 | buf[6];
143+
int resolution = getADCResolution(_adcResolution);
144+
g = resolution & (buf[2] << 16 | buf[1] << 8 | buf[0]);
145+
r = resolution & (buf[5] << 16 | buf[4] << 8 | buf[3]);
146+
b = resolution & (buf[8] << 16 | buf[7] << 8 | buf[6]);
107147

108148
return 1;
109149
}
110150

111151
int LTR381RGBClass::readAmbientLight(int& lux) {
112152
enableALS();
113153
unsigned long start = millis();
114-
while(!available() && (millis() - start) < _timeout);
154+
while(!available() && (millis() - start) < _timeout) {
155+
delay(50);
156+
}
157+
disableMeas();
115158
uint8_t buf[3] = {0};
116159
int res = readRegisters(LTR381RGB_ALS_DATA, buf, 3);
117160
if(res != 1) {
@@ -125,22 +168,31 @@ int LTR381RGBClass::readAmbientLight(int& lux) {
125168
int LTR381RGBClass::readLux(int& lux) {
126169
enableALS();
127170
unsigned long start = millis();
128-
while(!available() && (millis() - start) < _timeout);
171+
while(!available() && (millis() - start) < _timeout) {
172+
delay(50);
173+
}
174+
disableMeas();
129175
uint8_t buf[6] = {0};
130176
int res = readRegisters(LTR381RGB_CS_DATA_IR, buf, 6);
131177
if(res != 1) {
132178
return 0;
133179
}
180+
int gain = getLuxGain(_gain);
181+
float intTime = getLuxIntTime(_adcResolution);
134182
int ir = buf[2] << 16 | buf[1] << 8 | buf[0];
135183
int csg = buf[5] << 16 | buf[4] << 8 | buf[3];
136-
lux = ((0.8f*csg)/(_gain*_adcResolution))*(1 - (0.033f*(ir/csg)));
184+
lux = ((0.8f*csg)/(gain*intTime))*(1 - (0.033f*(ir/csg)));
185+
137186
return 1;
138187
}
139188

140189
int LTR381RGBClass::readIR(int& ir) {
141190
enableALS();
142191
unsigned long start = millis();
143-
while(!available() && (millis() - start) < _timeout);
192+
while(!available() && (millis() - start) < _timeout) {
193+
delay(50);
194+
}
195+
disableMeas();
144196
uint8_t buf[3] = {0};
145197
int res = readRegisters(LTR381RGB_CS_DATA_IR, buf, 3);
146198
if(res != 1) {
@@ -152,19 +204,31 @@ int LTR381RGBClass::readIR(int& ir) {
152204
}
153205

154206
void LTR381RGBClass::setGain(int gain) {
207+
if (gain > 0x04) {
208+
gain = 0x04;
209+
}
210+
_gain = gain;
155211
writeRegister(LTR381RGB_ALS_CS_GAIN, (0x07 & gain));
156-
_gain = getLuxGain(gain);
157212
}
158213

159214
void LTR381RGBClass::setADCResolution(int resolution) {
215+
if (resolution > 0x04) {
216+
resolution = 0x04;
217+
}
160218
uint8_t res = readRegister(LTR381RGB_ALS_CS_MEAS_RATE);
161-
writeRegister(LTR381RGB_ALS_CS_MEAS_RATE, ((res & 0xF8) | resolution));
162-
_adcResolution = getLuxResolution(resolution);
219+
writeRegister(LTR381RGB_ALS_CS_MEAS_RATE, ((res & 0x8F) | (resolution << 4)));
220+
_adcResolution = resolution;
221+
setTimeout(getADCResTime(resolution) + getADCRate(_rate));
163222
}
164223

165224
void LTR381RGBClass::setMeasurementRate(int rate) {
225+
if (rate > 0x08) {
226+
rate = 0x08;
227+
}
228+
_rate = rate;
166229
uint8_t res = readRegister(LTR381RGB_ALS_CS_MEAS_RATE);
167-
writeRegister(LTR381RGB_ALS_CS_MEAS_RATE, ((res & 0x8F) | (rate << 4)));
230+
writeRegister(LTR381RGB_ALS_CS_MEAS_RATE, ((res & 0xF8) | rate));
231+
setTimeout(getADCResTime(_adcResolution) + getADCRate(rate));
168232
}
169233

170234
void LTR381RGBClass::setUpperThreshold(int utv) {
@@ -175,6 +239,7 @@ void LTR381RGBClass::setUpperThreshold(int utv) {
175239
writeRegister(LTR381RGB_ALS_THRES_UTV_1, utv0);
176240
writeRegister(LTR381RGB_ALS_THRES_UTV_2, utv1);
177241
writeRegister(LTR381RGB_ALS_THRES_UTV_3, 0x0F & utv2);
242+
_upperThreshold = utv;
178243
}
179244

180245
void LTR381RGBClass::setLowerThreshold(int ltv) {
@@ -185,15 +250,62 @@ void LTR381RGBClass::setLowerThreshold(int ltv) {
185250
writeRegister(LTR381RGB_ALS_THRES_LTV_1, ltv0);
186251
writeRegister(LTR381RGB_ALS_THRES_LTV_2, ltv1);
187252
writeRegister(LTR381RGB_ALS_THRES_LTV_3, 0x0F & ltv2);
253+
_lowerThreshold = ltv;
188254
}
189255

190256
void LTR381RGBClass::setTimeout(unsigned long timeout) {
191-
_timeout = timeout;
257+
if (timeout > 200) {
258+
_timeout = timeout;
259+
} else {
260+
_timeout = 200;
261+
}
262+
}
263+
264+
int LTR381RGBClass::getADCResTime(int resolution) {
265+
switch(resolution) {
266+
case ADC_RES_16BIT:
267+
return 25;
268+
case ADC_RES_17BIT:
269+
return 50;
270+
case ADC_RES_18BIT:
271+
return 100;
272+
case ADC_RES_19BIT:
273+
return 200;
274+
case ADC_RES_20BIT:
275+
return 400;
276+
default:
277+
return 100;
278+
}
279+
}
280+
281+
int LTR381RGBClass::getADCRate(int rate) {
282+
switch(rate) {
283+
case ADC_MEAS_RATE_25MS:
284+
return 25;
285+
case ADC_MEAS_RATE_50MS:
286+
return 50;
287+
case ADC_MEAS_RATE_100MS:
288+
return 100;
289+
case ADC_MEAS_RATE_200MS:
290+
return 200;
291+
case ADC_MEAS_RATE_400MS:
292+
return 400;
293+
case ADC_MEAS_RATE_500MS:
294+
return 500;
295+
case ADC_MEAS_RATE_1000MS:
296+
return 1000;
297+
case ADC_MEAS_RATE_2000MS:
298+
return 2000;
299+
case ADC_MEAS_RATE_2000MS + 1:
300+
return 2000;
301+
default:
302+
return 100;
303+
}
192304
}
193305

194306
void LTR381RGBClass::enableALSInterrupt() {
195307
uint8_t res = readRegister(LTR381RGB_INT_CFG);
196-
writeRegister(LTR381RGB_INT_CFG, res | 0x03);
308+
writeRegister(LTR381RGB_INT_CFG, res | 0x04);
197309
}
198310

199311
void LTR381RGBClass::disableALSInterrupt() {
@@ -206,6 +318,37 @@ void LTR381RGBClass::resetSW() {
206318
writeRegister(LTR381RGB_MAIN_CTRL, res | 0x80);
207319
}
208320

321+
void LTR381RGBClass::setCalibrations(int rmax, int gmax, int bmax, int rmin, int gmin, int bmin) {
322+
_maxR = rmax;
323+
_maxG = gmax;
324+
_maxB = bmax;
325+
_minR = rmin;
326+
_minG = gmin;
327+
_minB = bmin;
328+
_calibrated = true;
329+
}
330+
331+
void LTR381RGBClass::dumpReg() {
332+
for (int i = 0x00; i < 0x27; i++) {
333+
if(i == 0x01 || i == 0x02 || i ==0x03 || i == 0x08 || i == 0x09
334+
|| i == 016 || i == 0x17 || i == 0x18 || i == 0x1B || i == 0x1C
335+
|| i == 0x1D || i == 0x1E || i == 0x1F || i == 0x20) {
336+
Serial.print("ADDRESS 0x");
337+
Serial.print(i, HEX);
338+
Serial.println(" IS RESERVED");
339+
continue;
340+
}
341+
342+
int res = readRegister(i);
343+
Serial.print("REGISTER ADDRESS 0x");
344+
Serial.print(i, HEX);
345+
Serial.print(" VALUE= 0x");
346+
Serial.print(res, HEX);
347+
Serial.print(":");
348+
Serial.println(res, BIN);
349+
}
350+
}
351+
209352
int LTR381RGBClass::getLuxGain(int gain) {
210353
switch(gain) {
211354
case ALS_CS_GAIN_1:
@@ -218,11 +361,29 @@ int LTR381RGBClass::getLuxGain(int gain) {
218361
return 9;
219362
case ALS_CS_GAIN_18:
220363
return 18;
364+
default:
365+
return 6;
366+
}
367+
}
368+
369+
int LTR381RGBClass::getADCResolution(int resolution) {
370+
switch(resolution) {
371+
case ADC_RES_16BIT:
372+
return 65534;
373+
case ADC_RES_17BIT:
374+
return 131071;
375+
case ADC_RES_18BIT:
376+
return 262143;
377+
case ADC_RES_19BIT:
378+
return 524287;
379+
case ADC_RES_20BIT:
380+
return 1048575;
381+
default:
382+
return 262143;
221383
}
222-
return _gain;
223384
}
224385

225-
float LTR381RGBClass::getLuxResolution(int resolution) {
386+
float LTR381RGBClass::getLuxIntTime(int resolution) {
226387
switch(resolution) {
227388
case ADC_RES_16BIT:
228389
return 0.25;
@@ -234,12 +395,25 @@ float LTR381RGBClass::getLuxResolution(int resolution) {
234395
return 2.0f;
235396
case ADC_RES_20BIT:
236397
return 4.0f;
398+
default:
399+
return 1.0f;
237400
}
238-
return _adcResolution;
239401
}
240402

241403
int LTR381RGBClass::available() {
242404
auto res = readRegister(LTR381RGB_MAIN_STATUS);
405+
if ((res & 0x20) == 0x20) {
406+
Serial.println("Power-On event happens");
407+
resetSW();
408+
#ifdef DEBUG
409+
dumpReg();
410+
#endif
411+
// clear the reading after the reset
412+
res = readRegister(LTR381RGB_MAIN_STATUS);
413+
setADCResolution(_adcResolution);
414+
setGain(_gain);
415+
return 0;
416+
}
243417
if ((res & 0x08) == 0x08) {
244418
return 1;
245419
}
@@ -254,6 +428,28 @@ void LTR381RGBClass::enableALS() {
254428
writeRegister(LTR381RGB_MAIN_CTRL, 0x02);
255429
}
256430

431+
void LTR381RGBClass::disableMeas() {
432+
writeRegister(LTR381RGB_MAIN_CTRL, 0x00);
433+
}
434+
435+
int LTR381RGBClass::normAndTrim(int color, int min, int max) {
436+
color = (color - min)*255/(max - min);
437+
if (color < 0) {
438+
color = 0;
439+
}
440+
if (color > 255) {
441+
color = 255;
442+
}
443+
return color;
444+
445+
}
446+
447+
int LTR381RGBClass::adcToValue(int adc) {
448+
int resolution = getADCResolution(_adcResolution);
449+
return ((resolution & adc)*255/(resolution));;
450+
}
451+
452+
257453
int LTR381RGBClass::readRegister(uint8_t address) {
258454
uint8_t value;
259455
if (readRegisters(address, &value, sizeof(value)) != 1) {

0 commit comments

Comments
 (0)