/ Adafruit_SI1145.cpp
Adafruit_SI1145.cpp
1 /*************************************************** 2 This is a library for the Si1145 UV/IR/Visible Light Sensor 3 4 Designed specifically to work with the Si1145 sensor in the 5 adafruit shop 6 ----> https://www.adafruit.com/products/1777 7 8 These sensors use I2C to communicate, 2 pins are required to 9 interface 10 Adafruit invests time and resources providing this open source code, 11 please support Adafruit and open-source hardware by purchasing 12 products from Adafruit! 13 14 Written by Limor Fried/Ladyada for Adafruit Industries. 15 BSD license, all text above must be included in any redistribution 16 ****************************************************/ 17 18 #include "Adafruit_SI1145.h" 19 20 /** 21 * @brief Destructor 22 * 23 */ 24 Adafruit_SI1145::~Adafruit_SI1145() { 25 if (i2c_dev) 26 delete i2c_dev; 27 } 28 /** 29 * @brief Construct a new Adafruit_SI1145::Adafruit_SI1145 object 30 * 31 */ 32 Adafruit_SI1145::Adafruit_SI1145() {} 33 /** 34 * @brief Initize the driver, specifying the `TwoWire` bus to use 35 * 36 * @param pBus Pointer to the `TwoWire` I2C bus to use 37 * @return boolean true: success false: failure to initialize the sensor 38 */ 39 boolean Adafruit_SI1145::begin(TwoWire *pBus) { 40 return begin(SI1145_ADDR, pBus); 41 } 42 /** 43 * @brief Initize the driver, supplying both a `TwoWire` bus and I2C address 44 * 45 * @param addr The I2C address of the Sensor 46 * @param pBus Pointer to the `TwoWire` instance to use 47 * @return boolean true: success false: failure to initize the sensor 48 */ 49 boolean Adafruit_SI1145::begin(uint8_t addr, TwoWire *pBus) { 50 if (i2c_dev) 51 delete i2c_dev; 52 i2c_dev = new Adafruit_I2CDevice(addr, pBus); 53 if (!i2c_dev->begin()) { 54 return false; 55 } 56 57 uint8_t id = read8(SI1145_REG_PARTID); 58 if (id != 0x45) 59 return false; // look for SI1145 60 61 reset(); 62 63 /***********************************/ 64 // enable UVindex measurement coefficients! 65 write8(SI1145_REG_UCOEFF0, 0x29); 66 write8(SI1145_REG_UCOEFF1, 0x89); 67 write8(SI1145_REG_UCOEFF2, 0x02); 68 write8(SI1145_REG_UCOEFF3, 0x00); 69 70 // enable UV sensor 71 writeParam(SI1145_PARAM_CHLIST, 72 SI1145_PARAM_CHLIST_ENUV | SI1145_PARAM_CHLIST_ENALSIR | 73 SI1145_PARAM_CHLIST_ENALSVIS | SI1145_PARAM_CHLIST_ENPS1); 74 // enable interrupt on every sample 75 write8(SI1145_REG_INTCFG, SI1145_REG_INTCFG_INTOE); 76 write8(SI1145_REG_IRQEN, SI1145_REG_IRQEN_ALSEVERYSAMPLE); 77 78 /****************************** Prox Sense 1 */ 79 80 // program LED current 81 write8(SI1145_REG_PSLED21, 0x03); // 20mA for LED 1 only 82 writeParam(SI1145_PARAM_PS1ADCMUX, SI1145_PARAM_ADCMUX_LARGEIR); 83 // prox sensor #1 uses LED #1 84 writeParam(SI1145_PARAM_PSLED12SEL, SI1145_PARAM_PSLED12SEL_PS1LED1); 85 // fastest clocks, clock div 1 86 writeParam(SI1145_PARAM_PSADCGAIN, 0); 87 // take 511 clocks to measure 88 writeParam(SI1145_PARAM_PSADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK); 89 // in prox mode, high range 90 writeParam(SI1145_PARAM_PSADCMISC, 91 SI1145_PARAM_PSADCMISC_RANGE | SI1145_PARAM_PSADCMISC_PSMODE); 92 93 writeParam(SI1145_PARAM_ALSIRADCMUX, SI1145_PARAM_ADCMUX_SMALLIR); 94 // fastest clocks, clock div 1 95 writeParam(SI1145_PARAM_ALSIRADCGAIN, 0); 96 // take 511 clocks to measure 97 writeParam(SI1145_PARAM_ALSIRADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK); 98 // in high range mode 99 writeParam(SI1145_PARAM_ALSIRADCMISC, SI1145_PARAM_ALSIRADCMISC_RANGE); 100 101 // fastest clocks, clock div 1 102 writeParam(SI1145_PARAM_ALSVISADCGAIN, 0); 103 // take 511 clocks to measure 104 writeParam(SI1145_PARAM_ALSVISADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK); 105 // in high range mode (not normal signal) 106 writeParam(SI1145_PARAM_ALSVISADCMISC, SI1145_PARAM_ALSVISADCMISC_VISRANGE); 107 108 /************************/ 109 110 // measurement rate for auto 111 write8(SI1145_REG_MEASRATE0, 0xFF); // 255 * 31.25uS = 8ms 112 113 // auto run 114 write8(SI1145_REG_COMMAND, SI1145_PSALS_AUTO); 115 116 return true; 117 } 118 /** 119 * @brief Reset the sensor's registers to an initial state 120 * 121 */ 122 void Adafruit_SI1145::reset() { 123 write8(SI1145_REG_MEASRATE0, 0); 124 write8(SI1145_REG_MEASRATE1, 0); 125 write8(SI1145_REG_IRQEN, 0); 126 write8(SI1145_REG_IRQMODE1, 0); 127 write8(SI1145_REG_IRQMODE2, 0); 128 write8(SI1145_REG_INTCFG, 0); 129 write8(SI1145_REG_IRQSTAT, 0xFF); 130 131 write8(SI1145_REG_COMMAND, SI1145_RESET); 132 delay(10); 133 write8(SI1145_REG_HWKEY, 0x17); 134 135 delay(10); 136 } 137 138 ////////////////////////////////////////////////////// 139 140 /** 141 * @brief Get the current UV reading 142 * 143 * @return uint16_t The the UV index * 100 (divide by 100 to get the index) 144 */ 145 uint16_t Adafruit_SI1145::readUV(void) { return read16(0x2C); } 146 147 /** 148 * @brief Get the Visible & IR light levels 149 * 150 * @return uint16_t The Visible & IR light levels 151 */ 152 uint16_t Adafruit_SI1145::readVisible(void) { return read16(0x22); } 153 154 // returns IR light levels 155 /** 156 * @brief Get the Infrared light level 157 * 158 * @return uint16_t The Infrared light level 159 */ 160 uint16_t Adafruit_SI1145::readIR(void) { return read16(0x24); } 161 162 // returns "Proximity" - assumes an IR LED is attached to LED 163 /** 164 * @brief Gets the Proximity measurement - **Requires an attached IR LED** 165 * 166 * @return uint16_t The proximity measurement 167 */ 168 uint16_t Adafruit_SI1145::readProx(void) { return read16(0x26); } 169 170 /*********************************************************************/ 171 172 uint8_t Adafruit_SI1145::writeParam(uint8_t p, uint8_t v) { 173 // Serial.print("Param 0x"); Serial.print(p, HEX); 174 // Serial.print(" = 0x"); Serial.println(v, HEX); 175 176 write8(SI1145_REG_PARAMWR, v); 177 write8(SI1145_REG_COMMAND, p | SI1145_PARAM_SET); 178 return read8(SI1145_REG_PARAMRD); 179 } 180 181 uint8_t Adafruit_SI1145::readParam(uint8_t p) { 182 write8(SI1145_REG_COMMAND, p | SI1145_PARAM_QUERY); 183 return read8(SI1145_REG_PARAMRD); 184 } 185 186 /*********************************************************************/ 187 188 uint8_t Adafruit_SI1145::read8(uint8_t reg) { 189 uint8_t buffer[1] = {reg}; 190 i2c_dev->write_then_read(buffer, 1, buffer, 1); 191 return buffer[0]; 192 } 193 194 uint16_t Adafruit_SI1145::read16(uint8_t a) { 195 uint8_t buffer[2] = {a, 0}; 196 i2c_dev->write_then_read(buffer, 1, buffer, 2); 197 return ((uint16_t)buffer[0]) | ((uint16_t)buffer[1] << 8); 198 } 199 200 void Adafruit_SI1145::write8(uint8_t reg, uint8_t val) { 201 uint8_t buffer[2] = {reg, val}; 202 i2c_dev->write(buffer, 2); 203 }