Skip to content

Commit ecdbf3f

Browse files
authored
Merge pull request #6 from ufanders/add-error-handling
Added error handling
2 parents 8d0a0fb + 73faeff commit ecdbf3f

File tree

2 files changed

+116
-73
lines changed

2 files changed

+116
-73
lines changed

src/AS726X.cpp

Lines changed: 96 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,30 @@ bool AS726X::begin(TwoWire &wirePort, uint8_t gain, uint8_t measurementMode)
1414
_sensorVersion = virtualReadRegister(AS726x_HW_VERSION);
1515

1616
//HW version for AS7262, AS7263 and AS7261
17-
if (_sensorVersion != 0x3E && _sensorVersion != 0x3F && _sensorVersion != 0x40)
17+
if (_sensorVersion != SENSORTYPE_AS7261 &&
18+
_sensorVersion != SENSORTYPE_AS7262 &&
19+
_sensorVersion != SENSORTYPE_AS7263)
1820
{
1921
return false;
2022
}
2123

22-
setBulbCurrent(0b00); //Set to 12.5mA (minimum)
23-
disableBulb(); //Turn off to avoid heating the sensor
24+
//Set to 12.5mA (minimum)
25+
if(setBulbCurrent(0b00)) return false;
2426

25-
setIndicatorCurrent(0b11); //Set to 8mA (maximum)
26-
disableIndicator(); //Turn off lights to save power
27+
if(disableBulb()) return false; //Turn off to avoid heating the sensor
2728

28-
setIntegrationTime(50); //50 * 2.8ms = 140ms. 0 to 255 is valid.
29-
//If you use Mode 2 or 3 (all the colors) then integration time is double. 140*2 = 280ms between readings.
29+
if(setIndicatorCurrent(0b11)) return false; //Set to 8mA (maximum)
3030

31-
setGain(gain); //Set gain to 64x
31+
if(disableIndicator()) return false; //Turn off lights to save power
3232

33-
setMeasurementMode(measurementMode); //One-shot mode
33+
if(setIntegrationTime(50)) return false; //50 * 2.8ms = 140ms. 0 to 255 is valid.
34+
35+
//If you use Mode 2 or 3 (all the colors) then integration time is double.
36+
//140*2 = 280ms between readings.
37+
38+
if(setGain(gain)) return false; //Set gain to 64x
39+
40+
if(setMeasurementMode(measurementMode)) return false; //One-shot mode
3441

3542
return true;
3643
}
@@ -45,15 +52,15 @@ uint8_t AS726X::getVersion()
4552
//Mode 1: Continuous reading of GYOR (7262) / RTUX (7263)
4653
//Mode 2: Continuous reading of all channels (power-on default)
4754
//Mode 3: One-shot reading of all channels
48-
void AS726X::setMeasurementMode(uint8_t mode)
55+
int AS726X::setMeasurementMode(uint8_t mode)
4956
{
5057
if (mode > 0b11) mode = 0b11;
5158

5259
//Read, mask/set, write
5360
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
5461
value &= 0b11110011; //Clear BANK bits
5562
value |= (mode << 2); //Set BANK bits with user's choice
56-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
63+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
5764
}
5865

5966
uint8_t AS726X::getMeasurementMode()
@@ -67,15 +74,15 @@ uint8_t AS726X::getMeasurementMode()
6774
//Gain 1: 3.7x
6875
//Gain 2: 16x
6976
//Gain 3: 64x
70-
void AS726X::setGain(uint8_t gain)
77+
int AS726X::setGain(uint8_t gain)
7178
{
7279
if (gain > 0b11) gain = 0b11;
7380

7481
//Read, mask/set, write
7582
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
7683
value &= 0b11001111; //Clear GAIN bits
7784
value |= (gain << 4); //Set GAIN bits with user's choice
78-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
85+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
7986
}
8087

8188
uint8_t AS726X::getGain()
@@ -87,9 +94,9 @@ uint8_t AS726X::getGain()
8794
//Sets the integration value
8895
//Give this function a uint8_t from 0 to 255.
8996
//Time will be 2.8ms * [integration value]
90-
void AS726X::setIntegrationTime(uint8_t integrationValue)
97+
int AS726X::setIntegrationTime(uint8_t integrationValue)
9198
{
92-
virtualWriteRegister(AS726x_INT_T, integrationValue); //Write
99+
return virtualWriteRegister(AS726x_INT_T, integrationValue); //Write
93100
}
94101

95102
uint8_t AS726X::getIntegrationTime()
@@ -98,49 +105,59 @@ uint8_t AS726X::getIntegrationTime()
98105
return value;
99106
}
100107

101-
void AS726X::enableInterrupt()
108+
int AS726X::enableInterrupt()
102109
{
103110
//Read, mask/set, write
104111
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
105112
value |= 0b01000000; //Set INT bit
106-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
113+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
107114
}
108115

109116
//Disables the interrupt pin
110-
void AS726X::disableInterrupt()
117+
int AS726X::disableInterrupt()
111118
{
112119
//Read, mask/set, write
113120
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
114121
value &= 0b10111111; //Clear INT bit
115-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
122+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
116123
}
117124

118125
//Tells IC to take measurements and polls for data ready flag
119-
void AS726X::takeMeasurements()
126+
int AS726X::takeMeasurements()
120127
{
121-
clearDataAvailable(); //Clear DATA_RDY flag when using Mode 3
128+
//Clear DATA_RDY flag when using Mode 3
129+
if(clearDataAvailable()) return -1;
130+
131+
//Goto mode 3 for one shot measurement of all channels
132+
if(setMeasurementMode(3)) return -1;
122133

123-
//Goto mode 3 for one shot measurement of all channels
124-
setMeasurementMode(3);
134+
uint32_t timeout = millis() + TIMEOUT;
125135

126136
//Wait for data to be ready
127-
while (dataAvailable() == false) delay(POLLING_DELAY);
137+
while (dataAvailable() == false)
138+
{
139+
delay(POLLING_DELAY);
140+
if(millis() > timeout) return -1;
141+
}
128142

129143
//Readings can now be accessed via getViolet(), getBlue(), etc
144+
return 0;
130145
}
131146

132147
//Turns on bulb, takes measurements, turns off bulb
133-
void AS726X::takeMeasurementsWithBulb()
148+
int AS726X::takeMeasurementsWithBulb()
134149
{
135150
//enableIndicator(); //Tell the world we are taking a reading.
136151
//The indicator LED is red and may corrupt the readings
137152

138-
enableBulb(); //Turn on bulb to take measurement
153+
if(enableBulb()) return -1; //Turn on bulb to take measurement
154+
155+
if(takeMeasurements()) return -1;
139156

140-
takeMeasurements();
157+
if(disableBulb()) return -1; //Turn off bulb to avoid heating sensor
158+
//disableIndicator();
141159

142-
disableBulb(); //Turn off bulb to avoid heating sensor
143-
//disableIndicator();
160+
return 0;
144161
}
145162

146163
//Get the various color readings
@@ -239,74 +256,74 @@ bool AS726X::dataAvailable()
239256

240257
//Clears the DRDY flag
241258
//Normally this should clear when data registers are read
242-
void AS726X::clearDataAvailable()
259+
int AS726X::clearDataAvailable()
243260
{
244261
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP);
245262
value &= ~(1 << 1); //Set the DATA_RDY bit
246-
virtualWriteRegister(AS726x_CONTROL_SETUP, value);
263+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value);
247264
}
248265

249266
//Enable the onboard indicator LED
250-
void AS726X::enableIndicator()
267+
int AS726X::enableIndicator()
251268
{
252269
//Read, mask/set, write
253270
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
254271
value |= (1 << 0); //Set the bit
255-
virtualWriteRegister(AS726x_LED_CONTROL, value);
272+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
256273
}
257274

258275
//Disable the onboard indicator LED
259-
void AS726X::disableIndicator()
276+
int AS726X::disableIndicator()
260277
{
261278
//Read, mask/set, write
262279
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
263280
value &= ~(1 << 0); //Clear the bit
264-
virtualWriteRegister(AS726x_LED_CONTROL, value);
281+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
265282
}
266283

267284
//Set the current limit of onboard LED. Default is max 8mA = 0b11.
268-
void AS726X::setIndicatorCurrent(uint8_t current)
285+
int AS726X::setIndicatorCurrent(uint8_t current)
269286
{
270287
if (current > 0b11) current = 0b11;
271288
//Read, mask/set, write
272289
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL); //Read
273290
value &= 0b11111001; //Clear ICL_IND bits
274291
value |= (current << 1); //Set ICL_IND bits with user's choice
275-
virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
292+
return virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
276293
}
277294

278295
//Enable the onboard 5700k or external incandescent bulb
279-
void AS726X::enableBulb()
296+
int AS726X::enableBulb()
280297
{
281298
//Read, mask/set, write
282299
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
283300
value |= (1 << 3); //Set the bit
284-
virtualWriteRegister(AS726x_LED_CONTROL, value);
301+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
285302
}
286303

287304
//Disable the onboard 5700k or external incandescent bulb
288-
void AS726X::disableBulb()
305+
int AS726X::disableBulb()
289306
{
290307
//Read, mask/set, write
291308
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
292309
value &= ~(1 << 3); //Clear the bit
293-
virtualWriteRegister(AS726x_LED_CONTROL, value);
310+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
294311
}
295312

296313
//Set the current limit of bulb/LED.
297314
//Current 0: 12.5mA
298315
//Current 1: 25mA
299316
//Current 2: 50mA
300317
//Current 3: 100mA
301-
void AS726X::setBulbCurrent(uint8_t current)
318+
int AS726X::setBulbCurrent(uint8_t current)
302319
{
303320
if (current > 0b11) current = 0b11; //Limit to two bits
304321

305322
//Read, mask/set, write
306323
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL); //Read
307324
value &= 0b11001111; //Clear ICL_DRV bits
308325
value |= (current << 4); //Set ICL_DRV bits with user's choice
309-
virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
326+
return virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
310327
}
311328

312329
//Returns the temperature in C
@@ -326,18 +343,19 @@ float AS726X::getTemperatureF()
326343

327344
//Does a soft reset
328345
//Give sensor at least 1000ms to reset
329-
void AS726X::softReset()
346+
int AS726X::softReset()
330347
{
331348
//Read, mask/set, write
332349
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
333350
value |= (1 << 7); //Set RST bit
334-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
351+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
335352
}
336353

337354
//Read a virtual register from the AS726x
338355
uint8_t AS726X::virtualReadRegister(uint8_t virtualAddr)
339356
{
340357
uint8_t status;
358+
uint8_t retries = 0;
341359

342360
//Do a prelim check of the read register
343361
status = readRegister(AS72XX_SLAVE_STATUS_REG);
@@ -351,75 +369,98 @@ uint8_t AS726X::virtualReadRegister(uint8_t virtualAddr)
351369
while (1)
352370
{
353371
status = readRegister(AS72XX_SLAVE_STATUS_REG);
372+
if (status == 0xFF) return status;
354373
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // If TX bit is clear, it is ok to write
355374
delay(POLLING_DELAY);
375+
if(retries++ > retries) return 0xFF;
356376
}
357377

358378
// Send the virtual register address (bit 7 should be 0 to indicate we are reading a register).
359-
writeRegister(AS72XX_SLAVE_WRITE_REG, virtualAddr);
379+
if(writeRegister(AS72XX_SLAVE_WRITE_REG, virtualAddr)) return 0xFF;
380+
381+
retries = 0;
360382

361383
//Wait for READ flag to be set
362384
while (1)
363385
{
364386
status = readRegister(AS72XX_SLAVE_STATUS_REG);
387+
if (status == 0xFF) return status;
365388
if ((status & AS72XX_SLAVE_RX_VALID) != 0) break; // Read data is ready.
366389
delay(POLLING_DELAY);
390+
if(retries++ > retries) return 0xFF;
367391
}
368392

369393
uint8_t incoming = readRegister(AS72XX_SLAVE_READ_REG);
370394
return (incoming);
371395
}
372396

373397
//Write to a virtual register in the AS726x
374-
void AS726X::virtualWriteRegister(uint8_t virtualAddr, uint8_t dataToWrite)
398+
int AS726X::virtualWriteRegister(uint8_t virtualAddr, uint8_t dataToWrite)
375399
{
376400
uint8_t status;
401+
uint8_t retries = 0;
377402

378403
//Wait for WRITE register to be empty
379404
while (1)
380405
{
381406
status = readRegister(AS72XX_SLAVE_STATUS_REG);
407+
if (status == 0xFF) return -1;
382408
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
383409
delay(POLLING_DELAY);
410+
if(retries++ > retries) return -1;
384411
}
385412

386413
// Send the virtual register address (setting bit 7 to indicate we are writing to a register).
387414
writeRegister(AS72XX_SLAVE_WRITE_REG, (virtualAddr | 0x80));
388415

416+
retries = 0;
417+
389418
//Wait for WRITE register to be empty
390419
while (1)
391420
{
392421
status = readRegister(AS72XX_SLAVE_STATUS_REG);
422+
if (status == 0xFF) return -1;
393423
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
394424
delay(POLLING_DELAY);
425+
if(retries++ > retries) return -1;
395426
}
396427

397428
// Send the data to complete the operation.
398429
writeRegister(AS72XX_SLAVE_WRITE_REG, dataToWrite);
430+
431+
return 0;
399432
}
400433

401434
//Reads from a give location from the AS726x
402435
uint8_t AS726X::readRegister(uint8_t addr)
403436
{
437+
uint8_t err = 0xFF;
438+
404439
_i2cPort->beginTransmission(AS726X_ADDR);
405-
_i2cPort->write(addr);
406-
_i2cPort->endTransmission();
440+
if(_i2cPort->write(addr) == 0) return err;
441+
if(_i2cPort->endTransmission()) return err;
407442

408-
_i2cPort->requestFrom(AS726X_ADDR, 1);
443+
if(_i2cPort->requestFrom(AS726X_ADDR, 1) == 0) return err;
409444
if (_i2cPort->available()) {
410445
return (_i2cPort->read());
411446
}
412447
else {
413448
Serial.println("I2C Error");
414-
return (0xFF); //Error
449+
return err; //Error
415450
}
451+
452+
return 0;
416453
}
417454

418455
//Write a value to a spot in the AS726x
419-
void AS726X::writeRegister(uint8_t addr, uint8_t val)
456+
int AS726X::writeRegister(uint8_t addr, uint8_t val)
420457
{
458+
uint8_t err = 0xFF;
459+
421460
_i2cPort->beginTransmission(AS726X_ADDR);
422-
_i2cPort->write(addr);
423-
_i2cPort->write(val);
424-
_i2cPort->endTransmission();
461+
if(_i2cPort->write(addr) == 0) return (int)err;
462+
if(_i2cPort->write(val) == 0) return (int)err;
463+
if(_i2cPort->endTransmission()) return (int)err;
464+
465+
return 0;
425466
}

0 commit comments

Comments
 (0)