Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TS_DISCO_F746NG LCD_DISCO_F746NG BSP_DISCO_F746NG BUTTON_GROUP
Adafruit_APDS9960.cpp
00001 /*! 00002 * @file Adafruit_APDS9960.cpp 00003 * 00004 * @mainpage Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor 00005 * 00006 * @section author Author 00007 * 00008 * Ladyada, Dean Miller (Adafruit Industries) 00009 * 00010 * @section license License 00011 * 00012 * Software License Agreement (BSD License) 00013 * 00014 * Copyright (c) 2017, Adafruit Industries 00015 * All rights reserved. 00016 * 00017 * Redistribution and use in source and binary forms, with or without 00018 * modification, are permitted provided that the following conditions are met: 00019 * 1. Redistributions of source code must retain the above copyright 00020 * notice, this list of conditions and the following disclaimer. 00021 * 2. Redistributions in binary form must reproduce the above copyright 00022 * notice, this list of conditions and the following disclaimer in the 00023 * documentation and/or other materials provided with the distribution. 00024 * 3. Neither the name of the copyright holders nor the 00025 * names of its contributors may be used to endorse or promote products 00026 * derived from this software without specific prior written permission. 00027 * 00028 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 00029 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00030 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00031 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 00032 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00033 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00035 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00036 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00037 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 #ifdef __AVR 00041 #include <avr/pgmspace.h> 00042 #elif defined(ESP8266) 00043 #include <pgmspace.h> 00044 #endif 00045 #include <math.h> 00046 #include <stdlib.h> 00047 00048 #include "Adafruit_APDS9960.h " 00049 00050 /*! 00051 * @brief Implements missing powf function 00052 * @param x 00053 * Base number 00054 * @param y 00055 * Exponent 00056 * @return x raised to the power of y 00057 */ 00058 /* 00059 float powf(const float x, const float y) { 00060 return (float)(pow((double)x, (double)y)); 00061 } 00062 */ 00063 00064 /*! 00065 * @brief Enables the device 00066 * Disables the device (putting it in lower power sleep mode) 00067 * @param en 00068 * Enable (True/False) 00069 */ 00070 void Adafruit_APDS9960::enable(boolean en) { 00071 _enable.PON = en; 00072 this->write8(APDS9960_ENABLE, _enable.get()); 00073 } 00074 00075 /*! 00076 * @brief Initializes I2C and configures the sensor 00077 * @param iTimeMS 00078 * Integration time 00079 * @param aGain 00080 * Gain 00081 * @param addr 00082 * I2C address 00083 * @param *theWire 00084 * Wire object 00085 * @return True if initialization was successful, otherwise false. 00086 */ 00087 boolean Adafruit_APDS9960::begin(I2C *theWire, uint16_t iTimeMS, apds9960AGain_t aGain, 00088 uint8_t addr) { 00089 _wire = theWire; 00090 _i2c_init(); 00091 _i2caddr = addr; 00092 00093 /* Make sure we're actually connected */ 00094 uint8_t x = read8(APDS9960_ID); 00095 if (x != 0xAB) { 00096 return false; 00097 _pc->printf("TESTCPP %d", x); 00098 } 00099 00100 /* Set default integration time and gain */ 00101 setADCIntegrationTime(iTimeMS); 00102 setADCGain(aGain); 00103 00104 // disable everything to start 00105 enableGesture(false); 00106 enableProximity(false); 00107 enableColor(false); 00108 00109 disableColorInterrupt(); 00110 disableProximityInterrupt(); 00111 clearInterrupt(); 00112 00113 /* Note: by default, the device is in power down mode on bootup */ 00114 enable(false); 00115 wait_us(10000); 00116 enable(true); 00117 wait_us(10000); 00118 00119 // default to all gesture dimensions 00120 setGestureDimensions(APDS9960_DIMENSIONS_ALL); 00121 setGestureFIFOThreshold(APDS9960_GFIFO_4); 00122 setGestureGain(APDS9960_GGAIN_4); 00123 setGestureProximityThreshold(50); 00124 resetCounts(); 00125 00126 _gpulse.GPLEN = APDS9960_GPULSE_32US; 00127 _gpulse.GPULSE = 9; // 10 pulses 00128 this->write8(APDS9960_GPULSE, _gpulse.get()); 00129 00130 return true; 00131 } 00132 00133 /*! 00134 * @brief Sets the integration time for the ADC of the APDS9960, in millis 00135 * @param iTimeMS 00136 * Integration time 00137 */ 00138 void Adafruit_APDS9960::setADCIntegrationTime(uint16_t iTimeMS) { 00139 float temp; 00140 00141 // convert ms into 2.78ms increments 00142 temp = iTimeMS; 00143 temp /= 2.78; 00144 temp = 256 - temp; 00145 if (temp > 255) 00146 temp = 255; 00147 if (temp < 0) 00148 temp = 0; 00149 00150 /* Update the timing register */ 00151 write8(APDS9960_ATIME, (uint8_t)temp); 00152 } 00153 00154 /*! 00155 * @brief Returns the integration time for the ADC of the APDS9960, in millis 00156 * @return Integration time 00157 */ 00158 float Adafruit_APDS9960::getADCIntegrationTime() { 00159 float temp; 00160 00161 temp = read8(APDS9960_ATIME); 00162 00163 // convert to units of 2.78 ms 00164 temp = 256 - temp; 00165 temp *= 2.78; 00166 return temp; 00167 } 00168 00169 /*! 00170 * @brief Adjusts the color/ALS gain on the APDS9960 (adjusts the sensitivity 00171 * to light) 00172 * @param aGain 00173 * Gain 00174 */ 00175 void Adafruit_APDS9960::setADCGain(apds9960AGain_t aGain) { 00176 _control.AGAIN = aGain; 00177 00178 /* Update the timing register */ 00179 write8(APDS9960_CONTROL, _control.get()); 00180 } 00181 00182 /*! 00183 * @brief Returns the ADC gain 00184 * @return ADC gain 00185 */ 00186 apds9960AGain_t Adafruit_APDS9960::getADCGain() { 00187 return (apds9960AGain_t)(read8(APDS9960_CONTROL) & 0x03); 00188 } 00189 00190 /*! 00191 * @brief Adjusts the Proximity gain on the APDS9960 00192 * @param pGain 00193 * Gain 00194 */ 00195 void Adafruit_APDS9960::setProxGain(apds9960PGain_t pGain) { 00196 _control.PGAIN = pGain; 00197 00198 /* Update the timing register */ 00199 write8(APDS9960_CONTROL, _control.get()); 00200 } 00201 00202 /*! 00203 * @brief Returns the Proximity gain on the APDS9960 00204 * @return Proxmity gain 00205 */ 00206 apds9960PGain_t Adafruit_APDS9960::getProxGain() { 00207 return (apds9960PGain_t)(read8(APDS9960_CONTROL) & 0x0C); 00208 } 00209 00210 /*! 00211 * @brief Sets number of proxmity pulses 00212 * @param pLen 00213 * Pulse Length 00214 * @param pulses 00215 * Number of pulses 00216 */ 00217 void Adafruit_APDS9960::setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses) { 00218 if (pulses < 1) 00219 pulses = 1; 00220 if (pulses > 64) 00221 pulses = 64; 00222 pulses--; 00223 00224 _ppulse.PPLEN = pLen; 00225 _ppulse.PPULSE = pulses; 00226 00227 write8(APDS9960_PPULSE, _ppulse.get()); 00228 } 00229 00230 /*! 00231 * @brief Enable proximity readings on APDS9960 00232 * @param en 00233 * Enable (True/False) 00234 */ 00235 void Adafruit_APDS9960::enableProximity(boolean en) { 00236 _enable.PEN = en; 00237 00238 write8(APDS9960_ENABLE, _enable.get()); 00239 } 00240 00241 /*! 00242 * @brief Enable proximity interrupts 00243 */ 00244 void Adafruit_APDS9960::enableProximityInterrupt() { 00245 _enable.PIEN = 1; 00246 write8(APDS9960_ENABLE, _enable.get()); 00247 clearInterrupt(); 00248 } 00249 00250 /*! 00251 * @brief Disable proximity interrupts 00252 */ 00253 void Adafruit_APDS9960::disableProximityInterrupt() { 00254 _enable.PIEN = 0; 00255 write8(APDS9960_ENABLE, _enable.get()); 00256 } 00257 00258 /*! 00259 * @brief Set proxmity interrupt thresholds 00260 * @param low 00261 * Low threshold 00262 * @param high 00263 * High threshold 00264 * @param persistance 00265 * Persistance 00266 */ 00267 void Adafruit_APDS9960::setProximityInterruptThreshold(uint8_t low, 00268 uint8_t high, 00269 uint8_t persistance) { 00270 write8(APDS9960_PILT, low); 00271 write8(APDS9960_PIHT, high); 00272 00273 if (persistance > 7) 00274 persistance = 7; 00275 _pers.PPERS = persistance; 00276 write8(APDS9960_PERS, _pers.get()); 00277 } 00278 00279 /*! 00280 * @brief Returns proxmity interrupt status 00281 * @return True if enabled, false otherwise. 00282 */ 00283 bool Adafruit_APDS9960::getProximityInterrupt() { 00284 _status.set(this->read8(APDS9960_STATUS)); 00285 return _status.PINT; 00286 }; 00287 00288 /*! 00289 * @brief Read proximity data 00290 * @return Proximity 00291 */ 00292 uint8_t Adafruit_APDS9960::readProximity() { return read8(APDS9960_PDATA); } 00293 00294 /*! 00295 * @brief Returns validity status of a gesture 00296 * @return Status (True/False) 00297 */ 00298 bool Adafruit_APDS9960::gestureValid() { 00299 _gstatus.set(this->read8(APDS9960_GSTATUS)); 00300 return _gstatus.GVALID; 00301 } 00302 00303 /*! 00304 * @brief Sets gesture dimensions 00305 * @param dims 00306 * Dimensions (APDS9960_DIMENSIONS_ALL, APDS9960_DIMENSIONS_UP_DOWM, 00307 * APDS9960_DIMENSIONS_UP_DOWN, APGS9960_DIMENSIONS_LEFT_RIGHT) 00308 */ 00309 void Adafruit_APDS9960::setGestureDimensions(uint8_t dims) { 00310 _gconf3.GDIMS = dims; 00311 this->write8(APDS9960_GCONF3, _gconf3.get()); 00312 } 00313 00314 /*! 00315 * @brief Sets gesture FIFO Threshold 00316 * @param thresh 00317 * Threshold (APDS9960_GFIFO_1, APDS9960_GFIFO_4, APDS9960_GFIFO_8, 00318 * APDS9960_GFIFO_16) 00319 */ 00320 void Adafruit_APDS9960::setGestureFIFOThreshold(uint8_t thresh) { 00321 _gconf1.GFIFOTH = thresh; 00322 this->write8(APDS9960_GCONF1, _gconf1.get()); 00323 } 00324 00325 /*! 00326 * @brief Sets gesture sensor gain 00327 * @param gain 00328 * Gain (APDS9960_GAIN_1, APDS9960_GAIN_2, APDS9960_GAIN_4, 00329 * APDS9960_GAIN_8) 00330 */ 00331 void Adafruit_APDS9960::setGestureGain(uint8_t gain) { 00332 _gconf2.GGAIN = gain; 00333 this->write8(APDS9960_GCONF2, _gconf2.get()); 00334 } 00335 00336 /*! 00337 * @brief Sets gesture sensor threshold 00338 * @param thresh 00339 * Threshold 00340 */ 00341 void Adafruit_APDS9960::setGestureProximityThreshold(uint8_t thresh) { 00342 this->write8(APDS9960_GPENTH, thresh); 00343 } 00344 00345 /*! 00346 * @brief Sets gesture sensor offset 00347 * @param offset_up 00348 * Up offset 00349 * @param offset_down 00350 * Down offset 00351 * @param offset_left 00352 * Left offset 00353 * @param offset_right 00354 * Right offset 00355 */ 00356 void Adafruit_APDS9960::setGestureOffset(uint8_t offset_up, uint8_t offset_down, 00357 uint8_t offset_left, 00358 uint8_t offset_right) { 00359 this->write8(APDS9960_GOFFSET_U, offset_up); 00360 this->write8(APDS9960_GOFFSET_D, offset_down); 00361 this->write8(APDS9960_GOFFSET_L, offset_left); 00362 this->write8(APDS9960_GOFFSET_R, offset_right); 00363 } 00364 00365 /*! 00366 * @brief Enable gesture readings on APDS9960 00367 * @param en 00368 * Enable (True/False) 00369 */ 00370 void Adafruit_APDS9960::enableGesture(boolean en) { 00371 if (!en) { 00372 _gconf4.GMODE = 0; 00373 write8(APDS9960_GCONF4, _gconf4.get()); 00374 } 00375 _enable.GEN = en; 00376 write8(APDS9960_ENABLE, _enable.get()); 00377 resetCounts(); 00378 } 00379 00380 /*! 00381 * @brief Resets gesture counts 00382 */ 00383 void Adafruit_APDS9960::resetCounts() { 00384 gestCnt = 0; 00385 UCount = 0; 00386 DCount = 0; 00387 LCount = 0; 00388 RCount = 0; 00389 } 00390 00391 /*! 00392 * @brief Reads gesture 00393 * @return Received gesture (APDS9960_DOWN APDS9960_UP, APDS9960_LEFT 00394 * APDS9960_RIGHT) 00395 */ 00396 uint8_t Adafruit_APDS9960::readGesture() { 00397 uint8_t toRead; 00398 uint8_t buf[256]; 00399 unsigned long t = 0; 00400 uint8_t gestureReceived; 00401 while (1) { 00402 int up_down_diff = 0; 00403 int left_right_diff = 0; 00404 gestureReceived = 0; 00405 if (!gestureValid()) 00406 return 0; 00407 00408 wait_us(30000); 00409 toRead = this->read8(APDS9960_GFLVL); 00410 00411 // produces sideffects needed for readGesture to work 00412 this->read(APDS9960_GFIFO_U, buf, toRead); 00413 00414 if (abs((int)buf[0] - (int)buf[1]) > 13) 00415 up_down_diff += (int)buf[0] - (int)buf[1]; 00416 00417 if (abs((int)buf[2] - (int)buf[3]) > 13) 00418 left_right_diff += (int)buf[2] - (int)buf[3]; 00419 00420 if (up_down_diff != 0) { 00421 if (up_down_diff < 0) { 00422 if (DCount > 0) { 00423 gestureReceived = APDS9960_UP; 00424 } else 00425 UCount++; 00426 } else if (up_down_diff > 0) { 00427 if (UCount > 0) { 00428 gestureReceived = APDS9960_DOWN; 00429 } else 00430 DCount++; 00431 } 00432 } 00433 00434 if (left_right_diff != 0) { 00435 if (left_right_diff < 0) { 00436 if (RCount > 0) { 00437 gestureReceived = APDS9960_LEFT; 00438 } else 00439 LCount++; 00440 } else if (left_right_diff > 0) { 00441 if (LCount > 0) { 00442 gestureReceived = APDS9960_RIGHT; 00443 } else 00444 RCount++; 00445 } 00446 } 00447 00448 00449 if (up_down_diff != 0 || left_right_diff != 0){ 00450 t = clock_ms(); 00451 } 00452 00453 if (gestureReceived || clock_ms() - t > 300) { 00454 resetCounts(); 00455 return gestureReceived; 00456 } 00457 00458 } 00459 } 00460 00461 /*! 00462 * @brief Set LED brightness for proximity/gesture 00463 * @param drive 00464 * LED Drive 00465 * @param boost 00466 * LED Boost 00467 */ 00468 void Adafruit_APDS9960::setLED(apds9960LedDrive_t drive, 00469 apds9960LedBoost_t boost) { 00470 // set BOOST 00471 _config2.LED_BOOST = boost; 00472 write8(APDS9960_CONFIG2, _config2.get()); 00473 00474 _control.LDRIVE = drive; 00475 write8(APDS9960_CONTROL, _control.get()); 00476 } 00477 00478 /*! 00479 * @brief Enable color readings on APDS9960 00480 * @param en 00481 * Enable (True/False) 00482 */ 00483 void Adafruit_APDS9960::enableColor(boolean en) { 00484 _enable.AEN = en; 00485 write8(APDS9960_ENABLE, _enable.get()); 00486 } 00487 00488 /*! 00489 * @brief Returns status of color data 00490 * @return True if color data ready, False otherwise 00491 */ 00492 bool Adafruit_APDS9960::colorDataReady() { 00493 _status.set(this->read8(APDS9960_STATUS)); 00494 return _status.AVALID; 00495 } 00496 00497 /*! 00498 * @brief Reads the raw red, green, blue and clear channel values 00499 * @param *r 00500 * Red value 00501 * @param *g 00502 * Green value 00503 * @param *b 00504 * Blue value 00505 * @param *c 00506 * Clear channel value 00507 */ 00508 void Adafruit_APDS9960::getColorData(uint16_t *r, uint16_t *g, uint16_t *b, 00509 uint16_t *c) { 00510 00511 *c = read16R(APDS9960_CDATAL); 00512 *r = read16R(APDS9960_RDATAL); 00513 *g = read16R(APDS9960_GDATAL); 00514 *b = read16R(APDS9960_BDATAL); 00515 } 00516 00517 /*! 00518 * @brief Converts the raw R/G/B values to color temperature in degrees Kelvin 00519 * @param r 00520 * Red value 00521 * @param g 00522 * Green value 00523 * @param b 00524 * Blue value 00525 * @return Color temperature 00526 */ 00527 uint16_t Adafruit_APDS9960::calculateColorTemperature(uint16_t r, uint16_t g, 00528 uint16_t b) { 00529 float X, Y, Z; /* RGB to XYZ correlation */ 00530 float xc, yc; /* Chromaticity co-ordinates */ 00531 float n; /* McCamy's formula */ 00532 float cct; 00533 00534 /* 1. Map RGB values to their XYZ counterparts. */ 00535 /* Based on 6500K fluorescent, 3000K fluorescent */ 00536 /* and 60W incandescent values for a wide range. */ 00537 /* Note: Y = Illuminance or lux */ 00538 X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b); 00539 Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b); 00540 Z = (-0.68202F * r) + (0.77073F * g) + (0.56332F * b); 00541 00542 /* 2. Calculate the chromaticity co-ordinates */ 00543 xc = (X) / (X + Y + Z); 00544 yc = (Y) / (X + Y + Z); 00545 00546 /* 3. Use McCamy's formula to determine the CCT */ 00547 n = (xc - 0.3320F) / (0.1858F - yc); 00548 00549 /* Calculate the final CCT */ 00550 cct = 00551 (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F; 00552 00553 /* Return the results in degrees Kelvin */ 00554 return (uint16_t)cct; 00555 } 00556 00557 /*! 00558 * @brief Calculate ambient light values 00559 * @param r 00560 * Red value 00561 * @param g 00562 * Green value 00563 * @param b 00564 * Blue value 00565 * @return LUX value 00566 */ 00567 uint16_t Adafruit_APDS9960::calculateLux(uint16_t r, uint16_t g, uint16_t b) { 00568 float illuminance; 00569 00570 /* This only uses RGB ... how can we integrate clear or calculate lux */ 00571 /* based exclusively on clear since this might be more reliable? */ 00572 illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b); 00573 00574 return (uint16_t)illuminance; 00575 } 00576 00577 /*! 00578 * @brief Enables color interrupt 00579 */ 00580 void Adafruit_APDS9960::enableColorInterrupt() { 00581 _enable.AIEN = 1; 00582 write8(APDS9960_ENABLE, _enable.get()); 00583 } 00584 00585 /*! 00586 * @brief Disables color interrupt 00587 */ 00588 void Adafruit_APDS9960::disableColorInterrupt() { 00589 _enable.AIEN = 0; 00590 write8(APDS9960_ENABLE, _enable.get()); 00591 } 00592 00593 /*! 00594 * @brief Clears interrupt 00595 */ 00596 void Adafruit_APDS9960::clearInterrupt() { 00597 this->write(APDS9960_AICLEAR, NULL, 0); 00598 } 00599 00600 /*! 00601 * @brief Sets interrupt limits 00602 * @param low 00603 * Low limit 00604 * @param high 00605 * High limit 00606 */ 00607 void Adafruit_APDS9960::setIntLimits(uint16_t low, uint16_t high) { 00608 write8(APDS9960_AILTIL, low & 0xFF); 00609 write8(APDS9960_AILTH, low >> 8); 00610 write8(APDS9960_AIHTL, high & 0xFF); 00611 write8(APDS9960_AIHTH, high >> 8); 00612 } 00613 00614 /*! 00615 * @brief Writes specified value to given register 00616 * @param reg 00617 * Register to write to 00618 * @param value 00619 * Value to write 00620 */ 00621 void Adafruit_APDS9960::write8(byte reg, byte value) { 00622 this->write(reg, &value, 1); 00623 } 00624 00625 /*! 00626 * @brief Reads 8 bits from specified register 00627 * @param reg 00628 * Register to write to 00629 * @return Value in register 00630 */ 00631 uint8_t Adafruit_APDS9960::read8(byte reg) { 00632 uint8_t ret; 00633 this->read(reg, &ret, 1); 00634 00635 return ret; 00636 } 00637 00638 /*! 00639 * @brief Reads 32 bits from specified register 00640 * @param reg 00641 * Register to write to 00642 * @return Value in register 00643 */ 00644 uint32_t Adafruit_APDS9960::read32(uint8_t reg) { 00645 uint8_t ret[4]; 00646 uint32_t ret32; 00647 this->read(reg, ret, 4); 00648 ret32 = ret[3]; 00649 ret32 |= (uint32_t)ret[2] << 8; 00650 ret32 |= (uint32_t)ret[1] << 16; 00651 ret32 |= (uint32_t)ret[0] << 24; 00652 return ret32; 00653 } 00654 00655 /*! 00656 * @brief Reads 16 bites from specified register 00657 * @param reg 00658 * Register to write to 00659 * @return Value in register 00660 */ 00661 uint16_t Adafruit_APDS9960::read16(uint8_t reg) { 00662 uint8_t ret[2]; 00663 this->read(reg, ret, 2); 00664 00665 return (ret[0] << 8) | ret[1]; 00666 } 00667 00668 /*! 00669 * @brief Reads 16 bites from specified register 00670 * @param reg 00671 * Register to write to 00672 * @return Value in register 00673 */ 00674 uint16_t Adafruit_APDS9960::read16R(uint8_t reg) { 00675 uint8_t ret[2]; 00676 this->read(reg, ret, 2); 00677 00678 return (ret[1] << 8) | ret[0]; 00679 } 00680 00681 /*! 00682 * @brief Begins I2C communication 00683 */ 00684 void Adafruit_APDS9960::_i2c_init() { 00685 //_wire->begin(); // on mbed, we are already master if using the I2C class instead of I2CSlave class 00686 } 00687 00688 /*! 00689 * @brief Reads num bytes from specified register into a given buffer 00690 * @param reg 00691 * Register 00692 * @param *buf 00693 * Buffer 00694 * @param num 00695 * Number of bytes 00696 * @return Position after reading 00697 */ 00698 uint8_t Adafruit_APDS9960::read(uint8_t reg, uint8_t *buf, uint8_t num) { 00699 uint8_t pos = 0; 00700 bool eof = false; 00701 00702 // on arduino we need to read in 32 byte chunks 00703 //while (pos < num && !eof) { 00704 00705 //uint8_t read_now = min(32, num - pos); 00706 /* 00707 _wire->beginTransmission((uint8_t)_i2caddr); 00708 _wire->write((uint8_t)reg + pos); 00709 _wire->endTransmission(); 00710 00711 _wire->requestFrom((uint8_t)_i2caddr, read_now); 00712 */ 00713 00714 //_wire->start(); 00715 //_wire->write((uint8_t)_i2caddr); 00716 //_wire->write((uint8_t)reg); 00717 //_wire->stop(); 00718 00719 _wire->write((uint8_t)_i2caddr, (char *)®, 1, true); 00720 00721 _wire->read((uint8_t)_i2caddr, (char *) buf, num); 00722 00723 00724 /* 00725 for (int i = 0; i < read_now; i++) { 00726 if (!_wire->available()) { 00727 eof = true; 00728 break; 00729 } 00730 buf[pos] = _wire->read(); 00731 pos++; 00732 } 00733 */ 00734 //} 00735 00736 return num; 00737 } 00738 00739 /*! 00740 * @brief Writes num bytes from specified buffer into a given register 00741 * @param reg 00742 * Register 00743 * @param *buf 00744 * Buffer 00745 * @param num 00746 * Number of bytes 00747 */ 00748 void Adafruit_APDS9960::write(uint8_t reg, uint8_t *buf, uint8_t num) { 00749 /* 00750 _wire->beginTransmission((uint8_t)_i2caddr); 00751 _wire->write((uint8_t)reg); 00752 _wire->write((uint8_t *)buf, num); 00753 _wire->endTransmission(); 00754 */ 00755 00756 _wire->start(); 00757 _wire->write((uint8_t)_i2caddr); 00758 _wire->write((uint8_t)reg); 00759 00760 for(int i=0; i < num; i++){ // on parcours le "tableau" buf 00761 uint8_t value = *(buf+i); // on récupere la valeur à l'emplacement "i" du tableau 00762 _wire->write(value); // j'écris la valeur du tableau à l'emplacement "i" sur le bus i2c. 00763 } 00764 00765 _wire->stop(); 00766 00767 00768 }
Generated on Fri Jul 22 2022 06:03:14 by
1.7.2