Skip to content

Commit 0b7337b

Browse files
committed
- Fixed AS7261 hardware ID.
- Changed protos for all functions with Wire failure potential. - Added fcn exits for Wire failures. - Added local timeout for measurement fcn. - Added retry limit.
1 parent 8d0a0fb commit 0b7337b

File tree

2 files changed

+117
-73
lines changed

2 files changed

+117
-73
lines changed

src/AS726X.cpp

Lines changed: 97 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,31 @@ 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
{
21+
Serial.print("_sensorVersion: "); Serial.println(_sensorVersion);
1922
return false;
2023
}
2124

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

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

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.
30+
if(setIndicatorCurrent(0b11)) return false; //Set to 8mA (maximum)
3031

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

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

3543
return true;
3644
}
@@ -45,15 +53,15 @@ uint8_t AS726X::getVersion()
4553
//Mode 1: Continuous reading of GYOR (7262) / RTUX (7263)
4654
//Mode 2: Continuous reading of all channels (power-on default)
4755
//Mode 3: One-shot reading of all channels
48-
void AS726X::setMeasurementMode(uint8_t mode)
56+
int AS726X::setMeasurementMode(uint8_t mode)
4957
{
5058
if (mode > 0b11) mode = 0b11;
5159

5260
//Read, mask/set, write
5361
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
5462
value &= 0b11110011; //Clear BANK bits
5563
value |= (mode << 2); //Set BANK bits with user's choice
56-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
64+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
5765
}
5866

5967
uint8_t AS726X::getMeasurementMode()
@@ -67,15 +75,15 @@ uint8_t AS726X::getMeasurementMode()
6775
//Gain 1: 3.7x
6876
//Gain 2: 16x
6977
//Gain 3: 64x
70-
void AS726X::setGain(uint8_t gain)
78+
int AS726X::setGain(uint8_t gain)
7179
{
7280
if (gain > 0b11) gain = 0b11;
7381

7482
//Read, mask/set, write
7583
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
7684
value &= 0b11001111; //Clear GAIN bits
7785
value |= (gain << 4); //Set GAIN bits with user's choice
78-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
86+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
7987
}
8088

8189
uint8_t AS726X::getGain()
@@ -87,9 +95,9 @@ uint8_t AS726X::getGain()
8795
//Sets the integration value
8896
//Give this function a uint8_t from 0 to 255.
8997
//Time will be 2.8ms * [integration value]
90-
void AS726X::setIntegrationTime(uint8_t integrationValue)
98+
int AS726X::setIntegrationTime(uint8_t integrationValue)
9199
{
92-
virtualWriteRegister(AS726x_INT_T, integrationValue); //Write
100+
return virtualWriteRegister(AS726x_INT_T, integrationValue); //Write
93101
}
94102

95103
uint8_t AS726X::getIntegrationTime()
@@ -98,49 +106,59 @@ uint8_t AS726X::getIntegrationTime()
98106
return value;
99107
}
100108

101-
void AS726X::enableInterrupt()
109+
int AS726X::enableInterrupt()
102110
{
103111
//Read, mask/set, write
104112
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
105113
value |= 0b01000000; //Set INT bit
106-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
114+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
107115
}
108116

109117
//Disables the interrupt pin
110-
void AS726X::disableInterrupt()
118+
int AS726X::disableInterrupt()
111119
{
112120
//Read, mask/set, write
113121
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
114122
value &= 0b10111111; //Clear INT bit
115-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
123+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
116124
}
117125

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

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

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

129144
//Readings can now be accessed via getViolet(), getBlue(), etc
145+
return 0;
130146
}
131147

132148
//Turns on bulb, takes measurements, turns off bulb
133-
void AS726X::takeMeasurementsWithBulb()
149+
int AS726X::takeMeasurementsWithBulb()
134150
{
135151
//enableIndicator(); //Tell the world we are taking a reading.
136152
//The indicator LED is red and may corrupt the readings
137153

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

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

142-
disableBulb(); //Turn off bulb to avoid heating sensor
143-
//disableIndicator();
161+
return 0;
144162
}
145163

146164
//Get the various color readings
@@ -239,74 +257,74 @@ bool AS726X::dataAvailable()
239257

240258
//Clears the DRDY flag
241259
//Normally this should clear when data registers are read
242-
void AS726X::clearDataAvailable()
260+
int AS726X::clearDataAvailable()
243261
{
244262
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP);
245263
value &= ~(1 << 1); //Set the DATA_RDY bit
246-
virtualWriteRegister(AS726x_CONTROL_SETUP, value);
264+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value);
247265
}
248266

249267
//Enable the onboard indicator LED
250-
void AS726X::enableIndicator()
268+
int AS726X::enableIndicator()
251269
{
252270
//Read, mask/set, write
253271
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
254272
value |= (1 << 0); //Set the bit
255-
virtualWriteRegister(AS726x_LED_CONTROL, value);
273+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
256274
}
257275

258276
//Disable the onboard indicator LED
259-
void AS726X::disableIndicator()
277+
int AS726X::disableIndicator()
260278
{
261279
//Read, mask/set, write
262280
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
263281
value &= ~(1 << 0); //Clear the bit
264-
virtualWriteRegister(AS726x_LED_CONTROL, value);
282+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
265283
}
266284

267285
//Set the current limit of onboard LED. Default is max 8mA = 0b11.
268-
void AS726X::setIndicatorCurrent(uint8_t current)
286+
int AS726X::setIndicatorCurrent(uint8_t current)
269287
{
270288
if (current > 0b11) current = 0b11;
271289
//Read, mask/set, write
272290
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL); //Read
273291
value &= 0b11111001; //Clear ICL_IND bits
274292
value |= (current << 1); //Set ICL_IND bits with user's choice
275-
virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
293+
return virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
276294
}
277295

278296
//Enable the onboard 5700k or external incandescent bulb
279-
void AS726X::enableBulb()
297+
int AS726X::enableBulb()
280298
{
281299
//Read, mask/set, write
282300
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
283301
value |= (1 << 3); //Set the bit
284-
virtualWriteRegister(AS726x_LED_CONTROL, value);
302+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
285303
}
286304

287305
//Disable the onboard 5700k or external incandescent bulb
288-
void AS726X::disableBulb()
306+
int AS726X::disableBulb()
289307
{
290308
//Read, mask/set, write
291309
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL);
292310
value &= ~(1 << 3); //Clear the bit
293-
virtualWriteRegister(AS726x_LED_CONTROL, value);
311+
return virtualWriteRegister(AS726x_LED_CONTROL, value);
294312
}
295313

296314
//Set the current limit of bulb/LED.
297315
//Current 0: 12.5mA
298316
//Current 1: 25mA
299317
//Current 2: 50mA
300318
//Current 3: 100mA
301-
void AS726X::setBulbCurrent(uint8_t current)
319+
int AS726X::setBulbCurrent(uint8_t current)
302320
{
303321
if (current > 0b11) current = 0b11; //Limit to two bits
304322

305323
//Read, mask/set, write
306324
uint8_t value = virtualReadRegister(AS726x_LED_CONTROL); //Read
307325
value &= 0b11001111; //Clear ICL_DRV bits
308326
value |= (current << 4); //Set ICL_DRV bits with user's choice
309-
virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
327+
return virtualWriteRegister(AS726x_LED_CONTROL, value); //Write
310328
}
311329

312330
//Returns the temperature in C
@@ -326,18 +344,19 @@ float AS726X::getTemperatureF()
326344

327345
//Does a soft reset
328346
//Give sensor at least 1000ms to reset
329-
void AS726X::softReset()
347+
int AS726X::softReset()
330348
{
331349
//Read, mask/set, write
332350
uint8_t value = virtualReadRegister(AS726x_CONTROL_SETUP); //Read
333351
value |= (1 << 7); //Set RST bit
334-
virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
352+
return virtualWriteRegister(AS726x_CONTROL_SETUP, value); //Write
335353
}
336354

337355
//Read a virtual register from the AS726x
338356
uint8_t AS726X::virtualReadRegister(uint8_t virtualAddr)
339357
{
340358
uint8_t status;
359+
uint8_t retries = 0;
341360

342361
//Do a prelim check of the read register
343362
status = readRegister(AS72XX_SLAVE_STATUS_REG);
@@ -351,75 +370,98 @@ uint8_t AS726X::virtualReadRegister(uint8_t virtualAddr)
351370
while (1)
352371
{
353372
status = readRegister(AS72XX_SLAVE_STATUS_REG);
373+
if (status == 0xFF) return status;
354374
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // If TX bit is clear, it is ok to write
355375
delay(POLLING_DELAY);
376+
if(retries++ > retries) return 0xFF;
356377
}
357378

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

361384
//Wait for READ flag to be set
362385
while (1)
363386
{
364387
status = readRegister(AS72XX_SLAVE_STATUS_REG);
388+
if (status == 0xFF) return status;
365389
if ((status & AS72XX_SLAVE_RX_VALID) != 0) break; // Read data is ready.
366390
delay(POLLING_DELAY);
391+
if(retries++ > retries) return 0xFF;
367392
}
368393

369394
uint8_t incoming = readRegister(AS72XX_SLAVE_READ_REG);
370395
return (incoming);
371396
}
372397

373398
//Write to a virtual register in the AS726x
374-
void AS726X::virtualWriteRegister(uint8_t virtualAddr, uint8_t dataToWrite)
399+
int AS726X::virtualWriteRegister(uint8_t virtualAddr, uint8_t dataToWrite)
375400
{
376401
uint8_t status;
402+
uint8_t retries = 0;
377403

378404
//Wait for WRITE register to be empty
379405
while (1)
380406
{
381407
status = readRegister(AS72XX_SLAVE_STATUS_REG);
408+
if (status == 0xFF) return -1;
382409
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
383410
delay(POLLING_DELAY);
411+
if(retries++ > retries) return -1;
384412
}
385413

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

417+
retries = 0;
418+
389419
//Wait for WRITE register to be empty
390420
while (1)
391421
{
392422
status = readRegister(AS72XX_SLAVE_STATUS_REG);
423+
if (status == 0xFF) return -1;
393424
if ((status & AS72XX_SLAVE_TX_VALID) == 0) break; // No inbound TX pending at slave. Okay to write now.
394425
delay(POLLING_DELAY);
426+
if(retries++ > retries) return -1;
395427
}
396428

397429
// Send the data to complete the operation.
398430
writeRegister(AS72XX_SLAVE_WRITE_REG, dataToWrite);
431+
432+
return 0;
399433
}
400434

401435
//Reads from a give location from the AS726x
402436
uint8_t AS726X::readRegister(uint8_t addr)
403437
{
438+
uint8_t err = 0xFF;
439+
404440
_i2cPort->beginTransmission(AS726X_ADDR);
405-
_i2cPort->write(addr);
406-
_i2cPort->endTransmission();
441+
if(_i2cPort->write(addr) == 0) return err;
442+
if(_i2cPort->endTransmission()) return err;
407443

408-
_i2cPort->requestFrom(AS726X_ADDR, 1);
444+
if(_i2cPort->requestFrom(AS726X_ADDR, 1) == 0) return err;
409445
if (_i2cPort->available()) {
410446
return (_i2cPort->read());
411447
}
412448
else {
413449
Serial.println("I2C Error");
414-
return (0xFF); //Error
450+
return err; //Error
415451
}
452+
453+
return 0;
416454
}
417455

418456
//Write a value to a spot in the AS726x
419-
void AS726X::writeRegister(uint8_t addr, uint8_t val)
457+
int AS726X::writeRegister(uint8_t addr, uint8_t val)
420458
{
459+
uint8_t err = 0xFF;
460+
421461
_i2cPort->beginTransmission(AS726X_ADDR);
422-
_i2cPort->write(addr);
423-
_i2cPort->write(val);
424-
_i2cPort->endTransmission();
462+
if(_i2cPort->write(addr) == 0) return (int)err;
463+
if(_i2cPort->write(val) == 0) return (int)err;
464+
if(_i2cPort->endTransmission()) return (int)err;
465+
466+
return 0;
425467
}

0 commit comments

Comments
 (0)