diff --git a/README.md b/README.md index 0a7917d..fa0798f 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,8 @@ -ClosedCube Arduino Library for -ClosedCube OPT3001 Digital Ambient Light Sensor (ALS) with High Precision Human Eye Response Breakout +Arduino and ESP32 Library for +OPT300x Digital Ambient Light Sensor Family (ALS) with High Precision Human Eye Response ===================================================================================================== -This is breakout board for [Texas Instruments OPT3001](http://www.ti.com/product/OPT3001) Digital Ambient Light Sensor (ALS) Sensor - -[![](https://github.com/closedcube/ClosedCube_OPT3001_Arduino/blob/master/images/B060_OPT3001_Pic1.jpg)](https://www.tindie.com/stores/closedcube/) -[![](https://github.com/closedcube/ClosedCube_OPT3001_Arduino/blob/master/images/B060_OPT3001_Pic2.jpg)](https://www.tindie.com/stores/closedcube/) - -### Where to Buy? - -I sell on Tindie +This Library was tested sucessfully with: +OPT3001 and OPT3004 on Arduino Uno and ESP32C6 diff --git a/examples/opt3001demo/opt3001demo.ino b/examples/opt3001demo/opt3001demo.ino deleted file mode 100644 index 8bdca76..0000000 --- a/examples/opt3001demo/opt3001demo.ino +++ /dev/null @@ -1,120 +0,0 @@ -/* - -This is example for ClosedCube OPT3001 Digital Ambient Light Sensor breakout board - -Initial Date: 02-Dec-2015 - -Hardware connections for Arduino Uno: -VDD to 3.3V DC -SDA to A4 -SCL to A5 -GND to common ground - -Written by AA for ClosedCube - -MIT License - -*/ - -#include -#include - -ClosedCube_OPT3001 opt3001; - -#define OPT3001_ADDRESS 0x45 - -void setup() -{ - Serial.begin(9600); - Serial.println("ClosedCube OPT3001 Arduino Test"); - - opt3001.begin(OPT3001_ADDRESS); - Serial.print("OPT3001 Manufacturer ID"); - Serial.println(opt3001.readManufacturerID()); - Serial.print("OPT3001 Device ID"); - Serial.println(opt3001.readDeviceID()); - - configureSensor(); - printResult("High-Limit", opt3001.readHighLimit()); - printResult("Low-Limit", opt3001.readLowLimit()); - Serial.println("----"); -} - -void loop() -{ - OPT3001 result = opt3001.readResult(); - printResult("OPT3001", result); - delay(500); -} - -void configureSensor() { - OPT3001_Config newConfig; - - newConfig.RangeNumber = B1100; - newConfig.ConvertionTime = B0; - newConfig.Latch = B1; - newConfig.ModeOfConversionOperation = B11; - - OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig); - if (errorConfig != NO_ERROR) - printError("OPT3001 configuration", errorConfig); - else { - OPT3001_Config sensorConfig = opt3001.readConfig(); - Serial.println("OPT3001 Current Config:"); - Serial.println("------------------------------"); - - Serial.print("Conversion ready (R):"); - Serial.println(sensorConfig.ConversionReady,HEX); - - Serial.print("Conversion time (R/W):"); - Serial.println(sensorConfig.ConvertionTime, HEX); - - Serial.print("Fault count field (R/W):"); - Serial.println(sensorConfig.FaultCount, HEX); - - Serial.print("Flag high field (R-only):"); - Serial.println(sensorConfig.FlagHigh, HEX); - - Serial.print("Flag low field (R-only):"); - Serial.println(sensorConfig.FlagLow, HEX); - - Serial.print("Latch field (R/W):"); - Serial.println(sensorConfig.Latch, HEX); - - Serial.print("Mask exponent field (R/W):"); - Serial.println(sensorConfig.MaskExponent, HEX); - - Serial.print("Mode of conversion operation (R/W):"); - Serial.println(sensorConfig.ModeOfConversionOperation, HEX); - - Serial.print("Polarity field (R/W):"); - Serial.println(sensorConfig.Polarity, HEX); - - Serial.print("Overflow flag (R-only):"); - Serial.println(sensorConfig.OverflowFlag, HEX); - - Serial.print("Range number (R/W):"); - Serial.println(sensorConfig.RangeNumber, HEX); - - Serial.println("------------------------------"); - } - -} - -void printResult(String text, OPT3001 result) { - if (result.error == NO_ERROR) { - Serial.print(text); - Serial.print(": "); - Serial.print(result.lux); - Serial.println(" lux"); - } - else { - printError(text,result.error); - } -} - -void printError(String text, OPT3001_ErrorCode error) { - Serial.print(text); - Serial.print(": [ERROR] Code #"); - Serial.println(error); -} \ No newline at end of file diff --git a/examples/opt300xdemo/opt300xdemo.ino b/examples/opt300xdemo/opt300xdemo.ino new file mode 100644 index 0000000..169ee34 --- /dev/null +++ b/examples/opt300xdemo/opt300xdemo.ino @@ -0,0 +1,131 @@ +/* + +This is example for OPT300x Digital Ambient Light Sensor Family +Tested on OPT 3001 and 3004 + +Initial Date: 02-Dec-2015 +Last Eddit: 05.07.2025 bs MS added ESP32 suport generalised frome OPT3001 to +OPT300x Family + +Hardware connections for Arduino Uno: +VDD to 3.3V DC +SDA to A4 +SCL to A5 +GND to common ground + +Written by AA for ClosedCube + +MIT License + +*/ + +#include "OPT300x.h" +#include + +OPT300x opt300x; + +#define OPT300x_ADDRESS 0x44 + +// to suport ESP32 pin assignment, I2C pins need to be defined +#ifdef ESP32 +#define I2C_SDA 6 +#define I2C_SCL 7 +#endif + +void setup() { + Serial.begin(115200); + delay(2000); + Serial.println("OPT300x Test"); + delay(2000); +#ifdef ESP32 + Wire.begin(I2C_SDA, I2C_SCL); +#else + Wire.begin(); +#endif + opt300x.begin(OPT300x_ADDRESS); + Serial.print("OPT300x Manufacturer ID"); + Serial.println(opt300x.readManufacturerID()); + Serial.print("OPT300x Device ID"); + Serial.println(opt300x.readDeviceID()); + + configureSensor(); + printResult("High-Limit", opt300x.readHighLimit()); + printResult("Low-Limit", opt300x.readLowLimit()); + Serial.println("----"); +} + +void loop() { + OPT300x_S result = opt300x.readResult(); + printResult("OPT300x", result); + delay(500); +} + +void configureSensor() { + OPT300x_Config newConfig; + + newConfig.RangeNumber = B1100; + newConfig.ConvertionTime = B0; + newConfig.Latch = B1; + newConfig.ModeOfConversionOperation = B11; + + OPT300x_ErrorCode errorConfig = opt300x.writeConfig(newConfig); + if (errorConfig != NO_ERROR) + printError("OPT300x configuration", errorConfig); + else { + OPT300x_Config sensorConfig = opt300x.readConfig(); + Serial.println("OPT300x Current Config:"); + Serial.println("------------------------------"); + + Serial.print("Conversion ready (R):"); + Serial.println(sensorConfig.ConversionReady, HEX); + + Serial.print("Conversion time (R/W):"); + Serial.println(sensorConfig.ConvertionTime, HEX); + + Serial.print("Fault count field (R/W):"); + Serial.println(sensorConfig.FaultCount, HEX); + + Serial.print("Flag high field (R-only):"); + Serial.println(sensorConfig.FlagHigh, HEX); + + Serial.print("Flag low field (R-only):"); + Serial.println(sensorConfig.FlagLow, HEX); + + Serial.print("Latch field (R/W):"); + Serial.println(sensorConfig.Latch, HEX); + + Serial.print("Mask exponent field (R/W):"); + Serial.println(sensorConfig.MaskExponent, HEX); + + Serial.print("Mode of conversion operation (R/W):"); + Serial.println(sensorConfig.ModeOfConversionOperation, HEX); + + Serial.print("Polarity field (R/W):"); + Serial.println(sensorConfig.Polarity, HEX); + + Serial.print("Overflow flag (R-only):"); + Serial.println(sensorConfig.OverflowFlag, HEX); + + Serial.print("Range number (R/W):"); + Serial.println(sensorConfig.RangeNumber, HEX); + + Serial.println("------------------------------"); + } +} + +void printResult(String text, OPT300x_S result) { + if (result.error == NO_ERROR) { + Serial.print(text); + Serial.print(": "); + Serial.print(result.lux); + Serial.println(" lux"); + } else { + printError(text, result.error); + } +} + +void printError(String text, OPT300x_ErrorCode error) { + Serial.print(text); + Serial.print(": [ERROR] Code #"); + Serial.println(error); +} diff --git a/keywords.txt b/keywords.txt index 82702f7..17131e7 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,12 +1,12 @@ ################################################################## -# Syntax Coloring Map For ClosedCube OPT3001 Digital Ambient Light Sensor Library +# Syntax Coloring Map For OPT300x Digital Ambient Light Sensor Library ################################################################## ################################################################## # Datatypes (KEYWORD1) ################################################################## -ClosedCube_OPT3001 KEYWORD1 +OPT300x KEYWORD1 ################################################################## # Methods and Functions (KEYWORD2) diff --git a/library.properties b/library.properties index 598d607..20695c9 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=ClosedCube OPT3001 -version=1.1.2 -author=ClosedCube -maintainer=ClosedCube -sentence=Arduino library for Texas Instruments OPT3001 Digital Ambient Light Sensor (ALS) -paragraph=Arduino library for Texas Instruments OPT3001 Digital Ambient Light Sensor (ALS) +name=OPT300x +version=1.2.0 +author=ClosedCube and Miro Sieber +maintainer=Miro SieberĀ  +sentence=Arduino and ESP32 library for Texas Instruments OPT300x Digital Ambient Light Sensor Family +paragraph=This library provides an easy-to-use interface for the Texas Instruments OPT300x family of digital ambient light sensors, supporting initialization, configuration, and light intensity measurement over I2C. Compatible with Arduino and ESP32 platforms. category=Sensors -url=https://github.com/closedcube/ClosedCube_OPT3001_Arduino -architectures=* \ No newline at end of file +url=[https://github.com/mirosieber/OPT300x](https://github.com/mirosieber/OPT300x) +architectures=\* diff --git a/src/ClosedCube_OPT3001.cpp b/src/ClosedCube_OPT3001.cpp deleted file mode 100644 index a6b6a12..0000000 --- a/src/ClosedCube_OPT3001.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - -Arduino library for Texas Instruments OPT3001 Digital Ambient Light Sensor -Written by AA for ClosedCube ---- - -The MIT License (MIT) - -Copyright (c) 2015 ClosedCube Limited - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ -#include - -#include "ClosedCube_OPT3001.h" - -ClosedCube_OPT3001::ClosedCube_OPT3001() -{ -} - -OPT3001_ErrorCode ClosedCube_OPT3001::begin(uint8_t address) { - OPT3001_ErrorCode error = NO_ERROR; - _address = address; - Wire.begin(); - - return NO_ERROR; -} - -uint16_t ClosedCube_OPT3001::readManufacturerID() { - uint16_t result = 0; - OPT3001_ErrorCode error = writeData(MANUFACTURER_ID); - if (error == NO_ERROR) - error = readData(&result); - return result; -} - -uint16_t ClosedCube_OPT3001::readDeviceID() { - uint16_t result = 0; - OPT3001_ErrorCode error = writeData(DEVICE_ID); - if (error == NO_ERROR) - error = readData(&result); - return result; -} - -OPT3001_Config ClosedCube_OPT3001::readConfig() { - OPT3001_Config config; - OPT3001_ErrorCode error = writeData(CONFIG); - if (error == NO_ERROR) - error = readData(&config.rawData); - return config; -} - -OPT3001_ErrorCode ClosedCube_OPT3001::writeConfig(OPT3001_Config config) { - Wire.beginTransmission(_address); - Wire.write(CONFIG); - Wire.write(config.rawData >> 8); - Wire.write(config.rawData & 0x00FF); - return (OPT3001_ErrorCode)(-10 * Wire.endTransmission()); -} - -OPT3001 ClosedCube_OPT3001::readResult() { - return readRegister(RESULT); -} - -OPT3001 ClosedCube_OPT3001::readHighLimit() { - return readRegister(HIGH_LIMIT); -} - -OPT3001 ClosedCube_OPT3001::readLowLimit() { - return readRegister(LOW_LIMIT); -} - -OPT3001 ClosedCube_OPT3001::readRegister(OPT3001_Commands command) { - OPT3001_ErrorCode error = writeData(command); - if (error == NO_ERROR) { - OPT3001 result; - result.lux = 0; - result.error = NO_ERROR; - - OPT3001_ER er; - error = readData(&er.rawData); - if (error == NO_ERROR) { - result.raw = er; - result.lux = 0.01*pow(2, er.Exponent)*er.Result; - } - else { - result.error = error; - } - - return result; - } - else { - return returnError(error); - } -} - -OPT3001_ErrorCode ClosedCube_OPT3001::writeData(OPT3001_Commands command) -{ - Wire.beginTransmission(_address); - Wire.write(command); - return (OPT3001_ErrorCode)(-10 * Wire.endTransmission(true)); -} - -OPT3001_ErrorCode ClosedCube_OPT3001::readData(uint16_t* data) -{ - uint8_t buf[2]; - - Wire.requestFrom(_address, (uint8_t)2); - - int counter = 0; - while (Wire.available() < 2) - { - counter++; - delay(10); - if (counter > 250) - return TIMEOUT_ERROR; - } - - Wire.readBytes(buf, 2); - *data = (buf[0] << 8) | buf[1]; - - return NO_ERROR; -} - - -OPT3001 ClosedCube_OPT3001::returnError(OPT3001_ErrorCode error) { - OPT3001 result; - result.lux = 0; - result.error = error; - return result; -} diff --git a/src/ClosedCube_OPT3001.h b/src/ClosedCube_OPT3001.h deleted file mode 100644 index 764b5bc..0000000 --- a/src/ClosedCube_OPT3001.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - -Arduino library for Texas Instruments OPT3001 Digital Ambient Light Sensor - ---- - -The MIT License (MIT) - -Copyright (c) 2015 ClosedCube Limited - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#ifndef CLOSEDCUBE_OPT3001 -#define CLOSEDCUBE_OPT3001 - -#include - -typedef enum { - RESULT = 0x00, - CONFIG = 0x01, - LOW_LIMIT = 0x02, - HIGH_LIMIT = 0x03, - - MANUFACTURER_ID = 0x7E, - DEVICE_ID = 0x7F, -} OPT3001_Commands; - - -typedef enum { - NO_ERROR = 0, - TIMEOUT_ERROR = -100, - - // Wire I2C translated error codes - WIRE_I2C_DATA_TOO_LOG = -10, - WIRE_I2C_RECEIVED_NACK_ON_ADDRESS = -20, - WIRE_I2C_RECEIVED_NACK_ON_DATA = -30, - WIRE_I2C_UNKNOW_ERROR = -40 -} OPT3001_ErrorCode; - -typedef union { - uint16_t rawData; - struct { - uint16_t Result : 12; - uint8_t Exponent : 4; - }; -} OPT3001_ER; - - -typedef union { - struct { - uint8_t FaultCount : 2; - uint8_t MaskExponent : 1; - uint8_t Polarity : 1; - uint8_t Latch : 1; - uint8_t FlagLow : 1; - uint8_t FlagHigh : 1; - uint8_t ConversionReady : 1; - uint8_t OverflowFlag : 1; - uint8_t ModeOfConversionOperation : 2; - uint8_t ConvertionTime : 1; - uint8_t RangeNumber : 4; - }; - uint16_t rawData; -} OPT3001_Config; - -struct OPT3001 { - float lux; - OPT3001_ER raw; - OPT3001_ErrorCode error; -}; - -class ClosedCube_OPT3001 { -public: - ClosedCube_OPT3001(); - - OPT3001_ErrorCode begin(uint8_t address); - - uint16_t readManufacturerID(); - uint16_t readDeviceID(); - - OPT3001 readResult(); - OPT3001 readHighLimit(); - OPT3001 readLowLimit(); - - OPT3001_Config readConfig(); - OPT3001_ErrorCode writeConfig(OPT3001_Config config); - -private: - uint8_t _address; - - OPT3001_ErrorCode writeData(OPT3001_Commands command); - OPT3001_ErrorCode readData(uint16_t* data); - - OPT3001 readRegister(OPT3001_Commands command); - OPT3001 returnError(OPT3001_ErrorCode error); - - float calculateLux(OPT3001_ER er); -}; - - -#endif \ No newline at end of file diff --git a/src/OPT300x.cpp b/src/OPT300x.cpp new file mode 100644 index 0000000..a100ab5 --- /dev/null +++ b/src/OPT300x.cpp @@ -0,0 +1,134 @@ +/* + +Arduino/ESP32 library for Texas Instruments OPT300x Digital Ambient Light Sensor +Famyily Tested on OPT 3001 and 3004 + +--- + +The MIT License (MIT) + +Copyright (c) 2015 ClosedCube Limited + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ +#include + +#include "OPT300x.h" + +OPT300x::OPT300x() {} + +OPT300x_ErrorCode OPT300x::begin(uint8_t address) { + OPT300x_ErrorCode error = NO_ERROR; + _address = address; + + return NO_ERROR; +} + +uint16_t OPT300x::readManufacturerID() { + uint16_t result = 0; + OPT300x_ErrorCode error = writeData(MANUFACTURER_ID); + if (error == NO_ERROR) + error = readData(&result); + return result; +} + +uint16_t OPT300x::readDeviceID() { + uint16_t result = 0; + OPT300x_ErrorCode error = writeData(DEVICE_ID); + if (error == NO_ERROR) + error = readData(&result); + return result; +} + +OPT300x_Config OPT300x::readConfig() { + OPT300x_Config config; + OPT300x_ErrorCode error = writeData(CONFIG); + if (error == NO_ERROR) + error = readData(&config.rawData); + return config; +} + +OPT300x_ErrorCode OPT300x::writeConfig(OPT300x_Config config) { + Wire.beginTransmission(_address); + Wire.write(CONFIG); + Wire.write(config.rawData >> 8); + Wire.write(config.rawData & 0x00FF); + return (OPT300x_ErrorCode)(-10 * Wire.endTransmission()); +} + +OPT300x_S OPT300x::readResult() { return readRegister(RESULT); } + +OPT300x_S OPT300x::readHighLimit() { return readRegister(HIGH_LIMIT); } + +OPT300x_S OPT300x::readLowLimit() { return readRegister(LOW_LIMIT); } + +OPT300x_S OPT300x::readRegister(OPT300x_Commands command) { + OPT300x_ErrorCode error = writeData(command); + if (error == NO_ERROR) { + OPT300x_S result; + result.lux = 0; + result.error = NO_ERROR; + + OPT300x_ER er; + error = readData(&er.rawData); + if (error == NO_ERROR) { + result.raw = er; + result.lux = 0.01 * pow(2, er.Exponent) * er.Result; + } else { + result.error = error; + } + + return result; + } else { + return returnError(error); + } +} + +OPT300x_ErrorCode OPT300x::writeData(OPT300x_Commands command) { + Wire.beginTransmission(_address); + Wire.write(command); + return (OPT300x_ErrorCode)(-10 * Wire.endTransmission(true)); +} + +OPT300x_ErrorCode OPT300x::readData(uint16_t *data) { + uint8_t buf[2]; + + Wire.requestFrom(_address, (uint8_t)2); + + int counter = 0; + while (Wire.available() < 2) { + counter++; + delay(10); + if (counter > 250) + return TIMEOUT_ERROR; + } + + Wire.readBytes(buf, 2); + *data = (buf[0] << 8) | buf[1]; + + return NO_ERROR; +} + +OPT300x_S OPT300x::returnError(OPT300x_ErrorCode error) { + OPT300x_S result; + result.lux = 0; + result.error = error; + return result; +} diff --git a/src/OPT300x.h b/src/OPT300x.h new file mode 100644 index 0000000..77753ce --- /dev/null +++ b/src/OPT300x.h @@ -0,0 +1,117 @@ +/* + +Arduino/ESP32 library for Texas Instruments OPT300x Digital Ambient Light Sensor +Famyily Tested on OPT 3001 and 3004 + +--- + +The MIT License (MIT) + +Copyright (c) 2015 ClosedCube Limited + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +#ifndef _OPT300x_H_ +#define _OPT300x_H_ + +#include + +typedef enum { + RESULT = 0x00, + CONFIG = 0x01, + LOW_LIMIT = 0x02, + HIGH_LIMIT = 0x03, + + MANUFACTURER_ID = 0x7E, + DEVICE_ID = 0x7F, +} OPT300x_Commands; + +typedef enum { + NO_ERROR = 0, + TIMEOUT_ERROR = -100, + + // Wire I2C translated error codes + WIRE_I2C_DATA_TOO_LOG = -10, + WIRE_I2C_RECEIVED_NACK_ON_ADDRESS = -20, + WIRE_I2C_RECEIVED_NACK_ON_DATA = -30, + WIRE_I2C_UNKNOW_ERROR = -40 +} OPT300x_ErrorCode; + +typedef union { + uint16_t rawData; + struct { + uint16_t Result : 12; + uint8_t Exponent : 4; + }; +} OPT300x_ER; + +typedef union { + struct { + uint8_t FaultCount : 2; + uint8_t MaskExponent : 1; + uint8_t Polarity : 1; + uint8_t Latch : 1; + uint8_t FlagLow : 1; + uint8_t FlagHigh : 1; + uint8_t ConversionReady : 1; + uint8_t OverflowFlag : 1; + uint8_t ModeOfConversionOperation : 2; + uint8_t ConvertionTime : 1; + uint8_t RangeNumber : 4; + }; + uint16_t rawData; +} OPT300x_Config; + +struct OPT300x_S { + float lux; + OPT300x_ER raw; + OPT300x_ErrorCode error; +}; + +class OPT300x { +public: + OPT300x(); + + OPT300x_ErrorCode begin(uint8_t address); + + uint16_t readManufacturerID(); + uint16_t readDeviceID(); + + OPT300x_S readResult(); + OPT300x_S readHighLimit(); + OPT300x_S readLowLimit(); + + OPT300x_Config readConfig(); + OPT300x_ErrorCode writeConfig(OPT300x_Config config); + +private: + uint8_t _address; + + OPT300x_ErrorCode writeData(OPT300x_Commands command); + OPT300x_ErrorCode readData(uint16_t *data); + + OPT300x_S readRegister(OPT300x_Commands command); + OPT300x_S returnError(OPT300x_ErrorCode error); + + float calculateLux(OPT300x_ER er); +}; + +#endif