@@ -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
5966uint8_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
8188uint8_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
95102uint8_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
338355uint8_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
402435uint8_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