diff --git a/README.md b/README.md index b5d3fb6..e4dc8d1 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,11 @@ -SparkFun APDS9960 RGB and Gesture Sensor Arduino Library +SparkFun APDS9960 RGB and Gesture Sensor Arduino Library -- Modified for esp8266 ========================================================= -![Avago APDS-9960 Breakout Board - SEN-12787 ](https://cdn.sparkfun.com/r/92-92/assets/parts/9/6/0/3/12787-01.jpg) +Made a few changes to get this to work with esp8266. -[*Avago APDS-9960 Breakout Board (SEN-12787)*](https://www.sparkfun.com/products/12787) +The main two are: +* Removing wire.begin() from SparkFun_APDS9960.cpp and moving it into the examples so that the pins it uses can be specified in your sketch -Getting Started ---------------- +* Changed the LED_BOOST_300 to LED_BOOST_100 in SparkFun_APDS9960.cpp as I couldn't get the gesture sensor to work without changing this -* Download the Git repository as a ZIP ("Download ZIP" button) -* Unzip -* Copy the entire library directory (APDS-9960_RGB_and_Gesture_Sensor_Arduino_Library -) to \/libraries -* Open the Arduino program -* Select File -> Examples -> SparkFun_APDS9960 -> GestureTest -* Plug in your Arduino and APDS-9960 with the following connections - -*-OR-* - -* Use the library manager - -| Arduino Pin | APDS-9960 Board | Function | -|---|---|---| -| 3.3V | VCC | Power | -| GND | GND | Ground | -| A4 | SDA | I2C Data | -| A5 | SCL | I2C Clock | -| 2 | INT | Interrupt | - -* Go to Tools -> Board and select your Arduino board -* Go to Tools -> Serial Port and select the COM port of your Arduino board -* Click "Upload" -* Go to Tools -> Serial Monitor -* Ensure the baud rate is set at 9600 baud -* Swipe your hand over the sensor in various directions! - -Repository Contents -------------------- - -* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. -* **/src** - Source files for the library (.cpp, .h). -* **library.properties** - General library properties for the Arduino package manager. - -Documentation --------------- - -* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. -* **[Product Repository](https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor)** - Main repository (including hardware files) for the SparkFun_APDS9960 RGB and Gesture Sensor. -* **[Hookup Guide](https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide)** - Basic hookup guide for the sensor. - -Products that use this Library ---------------------------------- - -* [SEN-12787](https://www.sparkfun.com/products/12787)- Avago APDS-9960 - -Version History ---------------- -* [V_1.4.1](https://github.com/sparkfun/SparkFun_APDS-9960_Sensor_Arduino_Library/tree/V_1.4.1) - Removing blank files, updating library.properties file. -* [V_1.4.0](https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor_Arduino_Library/tree/V_1.4.0) - Updated to new library structure -* V_1.3.0 - Implemented disableProximitySensor(). Thanks to jmg5150 for catching that! -* V_1.2.0 - Added pinMode line to GestureTest demo to fix interrupt bug with some Arduinos -* V_1.1.0 - Updated GestureTest demo to not freeze with fast swipes -* V_1.0.0: Initial release -* Ambient and RGB light sensing implemented -* Ambient light interrupts working -* Proximity sensing implemented -* Proximity interrupts working -* Gesture (UP, DOWN, LEFT, RIGHT, NEAR, FAR) sensing implemented - -License Information -------------------- - -This product is _**open source**_! - -The **code** is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! - -Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license. - -Distributed as-is; no warranty is given. - -- Your friends at SparkFun. +See Sparkfun's original library here https://github.com/sparkfun/SparkFun_APDS-9960_Sensor_Arduino_Library for usage. diff --git a/examples/AmbientLightInterrupt/AmbientLightInterrupt.ino b/examples/AmbientLightInterrupt/AmbientLightInterrupt.ino index 4f36c73..38f36fc 100644 --- a/examples/AmbientLightInterrupt/AmbientLightInterrupt.ino +++ b/examples/AmbientLightInterrupt/AmbientLightInterrupt.ino @@ -16,14 +16,14 @@ Hardware Connections: IMPORTANT: The APDS-9960 can only accept 3.3V! - Arduino Pin APDS-9960 Board Function + Wemos Pin APDS-9960 Board Function 3.3V VCC Power GND GND Ground - A4 SDA I2C Data - A5 SCL I2C Clock - 2 INT Interrupt - 13 - LED + D3 SDA I2C Data + D1 SCL I2C Clock + D6 INT Interrupt + D7 - LED Resources: Include Wire.h and SparkFun_APDS-9960.h @@ -37,14 +37,19 @@ employee) at the local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. + +Modified for ESP8266 by Jon Ulmer Nov 2016 ****************************************************************/ #include #include -// Pins -#define APDS9960_INT 2 // Needs to be an interrupt pin -#define LED_PIN 13 // LED for showing interrupt +// Pins on wemos D1 mini +#define APDS9960_INT D6 //AKA GPIO12 -- Interupt pin +#define APDS9960_SDA D3 //AKA GPIO0 +#define APDS9960_SCL D1 //AKA GPIO5 +#define LED_PIN D7 //AKA GPIO13 -- LED for showing interrupt + // Constants #define LIGHT_INT_HIGH 1000 // High light level for interrupt @@ -56,24 +61,27 @@ uint16_t ambient_light = 0; uint16_t red_light = 0; uint16_t green_light = 0; uint16_t blue_light = 0; -int isr_flag = 0; +volatile bool isr_flag = 0; uint16_t threshold = 0; void setup() { + + //Start I2C with pins defined above + Wire.begin(APDS9960_SDA,APDS9960_SCL); // Set LED as output pinMode(LED_PIN, OUTPUT); pinMode(APDS9960_INT, INPUT); // Initialize Serial port - Serial.begin(9600); + Serial.begin(115200); Serial.println(); Serial.println(F("-------------------------------------")); Serial.println(F("SparkFun APDS-9960 - Light Interrupts")); Serial.println(F("-------------------------------------")); // Initialize interrupt service routine - attachInterrupt(0, interruptRoutine, FALLING); + attachInterrupt(APDS9960_INT, interruptRoutine, FALLING); // Initialize APDS-9960 (configure I2C and initial values) if ( apds.init() ) { @@ -158,4 +166,4 @@ void loop() { void interruptRoutine() { isr_flag = 1; -} \ No newline at end of file +} diff --git a/examples/ColorSensor/ColorSensor.ino b/examples/ColorSensor/ColorSensor.ino index ac8f891..7ab7e8a 100644 --- a/examples/ColorSensor/ColorSensor.ino +++ b/examples/ColorSensor/ColorSensor.ino @@ -14,12 +14,12 @@ Hardware Connections: IMPORTANT: The APDS-9960 can only accept 3.3V! - Arduino Pin APDS-9960 Board Function + Wemos Pin APDS-9960 Board Function 3.3V VCC Power GND GND Ground - A4 SDA I2C Data - A5 SCL I2C Clock + D3 SDA I2C Data + D1 SCL I2C Clock Resources: Include Wire.h and SparkFun_APDS-9960.h @@ -33,11 +33,17 @@ employee) at the local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. + +Modified for ESP8266 by Jon Ulmer Nov 2016 ****************************************************************/ #include #include +// Pins on wemos D1 mini +#define APDS9960_SDA D3 //AKA GPIO0 +#define APDS9960_SCL D1 //AKA GPIO5 + // Global Variables SparkFun_APDS9960 apds = SparkFun_APDS9960(); uint16_t ambient_light = 0; @@ -46,9 +52,12 @@ uint16_t green_light = 0; uint16_t blue_light = 0; void setup() { + + //Start I2C with pins defined above + Wire.begin(APDS9960_SDA,APDS9960_SCL); // Initialize Serial port - Serial.begin(9600); + Serial.begin(115200); Serial.println(); Serial.println(F("--------------------------------")); Serial.println(F("SparkFun APDS-9960 - ColorSensor")); @@ -93,4 +102,4 @@ void loop() { // Wait 1 second before next reading delay(1000); -} \ No newline at end of file +} diff --git a/examples/GestureTest/GestureTest.ino b/examples/GestureTest/GestureTest.ino index ab36cfe..f392660 100644 --- a/examples/GestureTest/GestureTest.ino +++ b/examples/GestureTest/GestureTest.ino @@ -23,13 +23,14 @@ Hardware Connections: IMPORTANT: The APDS-9960 can only accept 3.3V! - Arduino Pin APDS-9960 Board Function +Wemos Pin APDS-9960 Board Function 3.3V VCC Power GND GND Ground - A4 SDA I2C Data - A5 SCL I2C Clock - 2 INT Interrupt + D3 SDA I2C Data + D1 SCL I2C Clock + D6 INT Interrupt + D7 - LED Resources: Include Wire.h and SparkFun_APDS-9960.h @@ -43,34 +44,40 @@ employee) at the local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. + +Modified for ESP8266 by Jon Ulmer Nov 2016 ****************************************************************/ #include #include -// Pins -#define APDS9960_INT 2 // Needs to be an interrupt pin - +// Pins on wemos D1 mini +#define APDS9960_INT D6 //AKA GPIO12 -- Interupt pin +#define APDS9960_SDA D3 //AKA GPIO0 +#define APDS9960_SCL D1 //AKA GPIO5 // Constants // Global Variables SparkFun_APDS9960 apds = SparkFun_APDS9960(); -int isr_flag = 0; +volatile bool isr_flag = 0; void setup() { + //Start I2C with pins defined above + Wire.begin(APDS9960_SDA,APDS9960_SCL); + // Set interrupt pin as input pinMode(APDS9960_INT, INPUT); // Initialize Serial port - Serial.begin(9600); + Serial.begin(115200); Serial.println(); Serial.println(F("--------------------------------")); Serial.println(F("SparkFun APDS-9960 - GestureTest")); Serial.println(F("--------------------------------")); // Initialize interrupt service routine - attachInterrupt(0, interruptRoutine, FALLING); + attachInterrupt(APDS9960_INT, interruptRoutine, FALLING); // Initialize APDS-9960 (configure I2C and initial values) if ( apds.init() ) { @@ -89,10 +96,10 @@ void setup() { void loop() { if( isr_flag == 1 ) { - detachInterrupt(0); + detachInterrupt(APDS9960_INT); handleGesture(); isr_flag = 0; - attachInterrupt(0, interruptRoutine, FALLING); + attachInterrupt(APDS9960_INT, interruptRoutine, FALLING); } } @@ -125,4 +132,4 @@ void handleGesture() { Serial.println("NONE"); } } -} \ No newline at end of file +} diff --git a/examples/ProximityInterrupt/ProximityInterrupt.ino b/examples/ProximityInterrupt/ProximityInterrupt.ino index e51f47c..4f9b3e6 100644 --- a/examples/ProximityInterrupt/ProximityInterrupt.ino +++ b/examples/ProximityInterrupt/ProximityInterrupt.ino @@ -14,14 +14,14 @@ Hardware Connections: IMPORTANT: The APDS-9960 can only accept 3.3V! - Arduino Pin APDS-9960 Board Function +Wemos Pin APDS-9960 Board Function 3.3V VCC Power GND GND Ground - A4 SDA I2C Data - A5 SCL I2C Clock - 2 INT Interrupt - 13 - LED + D3 SDA I2C Data + D1 SCL I2C Clock + D6 INT Interrupt + D7 - LED Resources: Include Wire.h and SparkFun_APDS-9960.h @@ -35,14 +35,18 @@ employee) at the local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. + +Modified for ESP8266 by Jon Ulmer Nov 2016 ****************************************************************/ #include #include -// Pins -#define APDS9960_INT 2 // Needs to be an interrupt pin -#define LED_PIN 13 // LED for showing interrupt +// Pins on wemos D1 mini +#define APDS9960_INT D6 //AKA GPIO12 -- Interupt pin +#define APDS9960_SDA D3 //AKA GPIO0 +#define APDS9960_SCL D1 //AKA GPIO5 +#define LED_PIN D7 //AKA GPIO13 -- LED for showing interrupt // Constants #define PROX_INT_HIGH 50 // Proximity level for interrupt @@ -51,23 +55,26 @@ Distributed as-is; no warranty is given. // Global variables SparkFun_APDS9960 apds = SparkFun_APDS9960(); uint8_t proximity_data = 0; -int isr_flag = 0; +volatile bool isr_flag = 0; void setup() { + + //Start I2C with pins defined above + Wire.begin(APDS9960_SDA,APDS9960_SCL); // Set LED as output pinMode(LED_PIN, OUTPUT); pinMode(APDS9960_INT, INPUT); // Initialize Serial port - Serial.begin(9600); + Serial.begin(115200); Serial.println(); Serial.println(F("---------------------------------------")); Serial.println(F("SparkFun APDS-9960 - ProximityInterrupt")); Serial.println(F("---------------------------------------")); // Initialize interrupt service routine - attachInterrupt(0, interruptRoutine, FALLING); + attachInterrupt(APDS9960_INT, interruptRoutine, FALLING); // Initialize APDS-9960 (configure I2C and initial values) if ( apds.init() ) { @@ -126,4 +133,4 @@ void loop() { void interruptRoutine() { isr_flag = 1; -} \ No newline at end of file +} diff --git a/examples/ProximitySensor/ProximitySensor.ino b/examples/ProximitySensor/ProximitySensor.ino index 38910d3..b2dea92 100644 --- a/examples/ProximitySensor/ProximitySensor.ino +++ b/examples/ProximitySensor/ProximitySensor.ino @@ -13,12 +13,12 @@ Hardware Connections: IMPORTANT: The APDS-9960 can only accept 3.3V! - Arduino Pin APDS-9960 Board Function + Wemos Pin APDS-9960 Board Function 3.3V VCC Power GND GND Ground - A4 SDA I2C Data - A5 SCL I2C Clock + D3 SDA I2C Data + D1 SCL I2C Clock Resources: Include Wire.h and SparkFun_APDS-9960.h @@ -32,19 +32,28 @@ employee) at the local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. + +Modified for ESP8266 by Jon Ulmer Nov 2016 ****************************************************************/ #include #include +// Pins on wemos D1 mini +#define APDS9960_SDA D3 //AKA GPIO0 +#define APDS9960_SCL D1 //AKA GPIO5 + // Global Variables SparkFun_APDS9960 apds = SparkFun_APDS9960(); uint8_t proximity_data = 0; void setup() { + + //Start I2C with pins defined above + Wire.begin(APDS9960_SDA,APDS9960_SCL); // Initialize Serial port - Serial.begin(9600); + Serial.begin(115200); Serial.println(); Serial.println(F("------------------------------------")); Serial.println(F("SparkFun APDS-9960 - ProximitySensor")); @@ -82,4 +91,4 @@ void loop() { // Wait 250 ms before next reading delay(250); -} \ No newline at end of file +} diff --git a/src/SparkFun_APDS9960.cpp b/src/SparkFun_APDS9960.cpp index f975839..9f00dd7 100644 --- a/src/SparkFun_APDS9960.cpp +++ b/src/SparkFun_APDS9960.cpp @@ -15,12 +15,12 @@ * Waiting for gesture: 14mA * Gesture in progress: 35mA */ - + #include #include - + #include "SparkFun_APDS9960.h" - + /** * @brief Constructor - Instantiates SparkFun_APDS9960 object */ @@ -28,17 +28,17 @@ SparkFun_APDS9960::SparkFun_APDS9960() { gesture_ud_delta_ = 0; gesture_lr_delta_ = 0; - + gesture_ud_count_ = 0; gesture_lr_count_ = 0; - + gesture_near_count_ = 0; gesture_far_count_ = 0; - + gesture_state_ = 0; gesture_motion_ = DIR_NONE; } - + /** * @brief Destructor */ @@ -57,8 +57,10 @@ bool SparkFun_APDS9960::init() uint8_t id; /* Initialize I2C */ - Wire.begin(); - + //Wire.begin(); + //Wire.begin(D3,D1); + + /* Read ID register and check against known values for APDS-9960 */ if( !wireReadDataByte(APDS9960_ID, id) ) { return false; @@ -66,12 +68,12 @@ bool SparkFun_APDS9960::init() if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2) ) { return false; } - + /* Set ENABLE register to 0 (disable all features) */ if( !setMode(ALL, OFF) ) { return false; } - + /* Set default values for ambient light and proximity registers */ if( !wireWriteDataByte(APDS9960_ATIME, DEFAULT_ATIME) ) { return false; @@ -121,7 +123,7 @@ bool SparkFun_APDS9960::init() if( !wireWriteDataByte(APDS9960_CONFIG3, DEFAULT_CONFIG3) ) { return false; } - + /* Set default values for gesture sense registers */ if( !setGestureEnterThresh(DEFAULT_GPENTH) ) { return false; @@ -162,12 +164,12 @@ bool SparkFun_APDS9960::init() if( !setGestureIntEnable(DEFAULT_GIEN) ) { return false; } - + #if 0 /* Gesture config register dump */ uint8_t reg; uint8_t val; - + for(reg = 0x80; reg <= 0xAF; reg++) { if( (reg != 0x82) && \ (reg != 0x8A) && \ @@ -206,12 +208,12 @@ bool SparkFun_APDS9960::init() uint8_t SparkFun_APDS9960::getMode() { uint8_t enable_value; - + /* Read current ENABLE register */ if( !wireReadDataByte(APDS9960_ENABLE, enable_value) ) { return ERROR; } - + return enable_value; } @@ -231,7 +233,7 @@ bool SparkFun_APDS9960::setMode(uint8_t mode, uint8_t enable) if( reg_val == ERROR ) { return false; } - + /* Change bit(s) in ENABLE register */ enable = enable & 0x01; if( mode >= 0 && mode <= 6 ) { @@ -247,12 +249,12 @@ bool SparkFun_APDS9960::setMode(uint8_t mode, uint8_t enable) reg_val = 0x00; } } - + /* Write value back to ENABLE register */ if( !wireWriteDataByte(APDS9960_ENABLE, reg_val) ) { return false; } - + return true; } @@ -264,7 +266,7 @@ bool SparkFun_APDS9960::setMode(uint8_t mode, uint8_t enable) */ bool SparkFun_APDS9960::enableLightSensor(bool interrupts) { - + /* Set default gain, interrupts, enable power, and enable sensor */ if( !setAmbientLightGain(DEFAULT_AGAIN) ) { return false; @@ -284,7 +286,7 @@ bool SparkFun_APDS9960::enableLightSensor(bool interrupts) if( !setMode(AMBIENT_LIGHT, 1) ) { return false; } - + return true; } @@ -302,7 +304,7 @@ bool SparkFun_APDS9960::disableLightSensor() if( !setMode(AMBIENT_LIGHT, 0) ) { return false; } - + return true; } @@ -336,7 +338,7 @@ bool SparkFun_APDS9960::enableProximitySensor(bool interrupts) if( !setMode(PROXIMITY, 1) ) { return false; } - + return true; } @@ -365,12 +367,12 @@ bool SparkFun_APDS9960::disableProximitySensor() */ bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) { - + /* Enable gesture mode Set ENABLE to 0 (power off) Set WTIME to 0xFF Set AUX to LED_BOOST_300 - Enable PON, WEN, PEN, GEN in ENABLE + Enable PON, WEN, PEN, GEN in ENABLE */ resetGestureParameters(); if( !wireWriteDataByte(APDS9960_WTIME, 0xFF) ) { @@ -379,7 +381,8 @@ bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) if( !wireWriteDataByte(APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ) { return false; } - if( !setLEDBoost(LED_BOOST_300) ) { + //Jon if( !setLEDBoost(LED_BOOST_300) ) { + if( !setLEDBoost(LED_BOOST_100) ) { return false; } if( interrupts ) { @@ -397,7 +400,7 @@ bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) if( !enablePower() ){ return false; } - if( !setMode(WAIT, 1) ) { + if( !setMode(WAITING_TIME, 1) ) { return false; } if( !setMode(PROXIMITY, 1) ) { @@ -406,7 +409,7 @@ bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) if( !setMode(GESTURE, 1) ) { return false; } - + return true; } @@ -427,7 +430,7 @@ bool SparkFun_APDS9960::disableGestureSensor() if( !setMode(GESTURE, 0) ) { return false; } - + return true; } @@ -439,15 +442,15 @@ bool SparkFun_APDS9960::disableGestureSensor() bool SparkFun_APDS9960::isGestureAvailable() { uint8_t val; - + /* Read value from GSTATUS register */ if( !wireReadDataByte(APDS9960_GSTATUS, val) ) { return ERROR; } - + /* Shift and mask out GVALID bit */ val &= APDS9960_GVALID; - + /* Return true/false based on GVALID bit */ if( val == 1) { return true; @@ -461,34 +464,37 @@ bool SparkFun_APDS9960::isGestureAvailable() * * @return Number corresponding to gesture. -1 on error. */ -int SparkFun_APDS9960::readGesture() +//Jon int SparkFun_APDS9960::readGesture() + int16_t SparkFun_APDS9960::readGesture() { uint8_t fifo_level = 0; uint8_t bytes_read = 0; uint8_t fifo_data[128]; uint8_t gstatus; - int motion; - int i; - + //Jon int motion; + //Jon int i; + uint16_t motion; + uint16_t i; + /* Make sure that power and gesture is on and data is valid */ if( !isGestureAvailable() || !(getMode() & 0b01000001) ) { return DIR_NONE; } - + /* Keep looping as long as gesture data is valid */ while(1) { - + /* Wait some time to collect next batch of FIFO data */ delay(FIFO_PAUSE_TIME); - + /* Get the contents of the STATUS register. Is data still valid? */ if( !wireReadDataByte(APDS9960_GSTATUS, gstatus) ) { return ERROR; } - + /* If we have valid data, read in FIFO */ if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) { - + /* Read the current FIFO level */ if( !wireReadDataByte(APDS9960_GFLVL, fifo_level) ) { return ERROR; @@ -501,8 +507,8 @@ int SparkFun_APDS9960::readGesture() /* If there's stuff in the FIFO, read it into our data block */ if( fifo_level > 0) { - bytes_read = wireReadDataBlock( APDS9960_GFIFO_U, - (uint8_t*)fifo_data, + bytes_read = wireReadDataBlock( APDS9960_GFIFO_U, + (uint8_t*)fifo_data, (fifo_level * 4) ); if( bytes_read == -1 ) { return ERROR; @@ -530,7 +536,7 @@ int SparkFun_APDS9960::readGesture() gesture_data_.index++; gesture_data_.total_gestures++; } - + #if DEBUG Serial.print("Up Data: "); for ( i = 0; i < gesture_data_.total_gestures; i++ ) { @@ -549,14 +555,14 @@ int SparkFun_APDS9960::readGesture() #endif } } - + /* Reset data */ gesture_data_.index = 0; gesture_data_.total_gestures = 0; } } } else { - + /* Determine best guessed gesture and clean up */ delay(FIFO_PAUSE_TIME); decodeGesture(); @@ -581,7 +587,7 @@ bool SparkFun_APDS9960::enablePower() if( !setMode(POWER, 1) ) { return false; } - + return true; } @@ -595,7 +601,7 @@ bool SparkFun_APDS9960::disablePower() if( !setMode(POWER, 0) ) { return false; } - + return true; } @@ -613,19 +619,19 @@ bool SparkFun_APDS9960::readAmbientLight(uint16_t &val) { uint8_t val_byte; val = 0; - + /* Read value from clear channel, low byte register */ if( !wireReadDataByte(APDS9960_CDATAL, val_byte) ) { return false; } val = val_byte; - + /* Read value from clear channel, high byte register */ if( !wireReadDataByte(APDS9960_CDATAH, val_byte) ) { return false; } val = val + ((uint16_t)val_byte << 8); - + return true; } @@ -639,22 +645,22 @@ bool SparkFun_APDS9960::readRedLight(uint16_t &val) { uint8_t val_byte; val = 0; - + /* Read value from clear channel, low byte register */ if( !wireReadDataByte(APDS9960_RDATAL, val_byte) ) { return false; } val = val_byte; - + /* Read value from clear channel, high byte register */ if( !wireReadDataByte(APDS9960_RDATAH, val_byte) ) { return false; } val = val + ((uint16_t)val_byte << 8); - + return true; } - + /** * @brief Reads the green light level as a 16-bit value * @@ -665,19 +671,19 @@ bool SparkFun_APDS9960::readGreenLight(uint16_t &val) { uint8_t val_byte; val = 0; - + /* Read value from clear channel, low byte register */ if( !wireReadDataByte(APDS9960_GDATAL, val_byte) ) { return false; } val = val_byte; - + /* Read value from clear channel, high byte register */ if( !wireReadDataByte(APDS9960_GDATAH, val_byte) ) { return false; } val = val + ((uint16_t)val_byte << 8); - + return true; } @@ -691,19 +697,19 @@ bool SparkFun_APDS9960::readBlueLight(uint16_t &val) { uint8_t val_byte; val = 0; - + /* Read value from clear channel, low byte register */ if( !wireReadDataByte(APDS9960_BDATAL, val_byte) ) { return false; } val = val_byte; - + /* Read value from clear channel, high byte register */ if( !wireReadDataByte(APDS9960_BDATAH, val_byte) ) { return false; } val = val + ((uint16_t)val_byte << 8); - + return true; } @@ -720,12 +726,12 @@ bool SparkFun_APDS9960::readBlueLight(uint16_t &val) bool SparkFun_APDS9960::readProximity(uint8_t &val) { val = 0; - + /* Read value from proximity data register */ if( !wireReadDataByte(APDS9960_PDATA, val) ) { return false; } - + return true; } @@ -740,16 +746,16 @@ void SparkFun_APDS9960::resetGestureParameters() { gesture_data_.index = 0; gesture_data_.total_gestures = 0; - + gesture_ud_delta_ = 0; gesture_lr_delta_ = 0; - + gesture_ud_count_ = 0; gesture_lr_count_ = 0; - + gesture_near_count_ = 0; gesture_far_count_ = 0; - + gesture_state_ = 0; gesture_motion_ = DIR_NONE; } @@ -769,6 +775,7 @@ bool SparkFun_APDS9960::processGestureData() uint8_t d_last = 0; uint8_t l_last = 0; uint8_t r_last = 0; + /* Jon int ud_ratio_first; int lr_ratio_first; int ud_ratio_last; @@ -776,23 +783,32 @@ bool SparkFun_APDS9960::processGestureData() int ud_delta; int lr_delta; int i; + */ + + int16_t ud_ratio_first; + int16_t lr_ratio_first; + int16_t ud_ratio_last; + int16_t lr_ratio_last; + int16_t ud_delta; + int16_t lr_delta; + int16_t i; /* If we have less than 4 total gestures, that's not enough */ if( gesture_data_.total_gestures <= 4 ) { return false; } - + /* Check to make sure our data isn't out of bounds */ if( (gesture_data_.total_gestures <= 32) && \ (gesture_data_.total_gestures > 0) ) { - + /* Find the first value in U/D/L/R above the threshold */ for( i = 0; i < gesture_data_.total_gestures; i++ ) { if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) && (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) && (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) && (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) { - + u_first = gesture_data_.u_data[i]; d_first = gesture_data_.d_data[i]; l_first = gesture_data_.l_data[i]; @@ -800,11 +816,11 @@ bool SparkFun_APDS9960::processGestureData() break; } } - + /* If one of the _first values is 0, then there is no good data */ if( (u_first == 0) || (d_first == 0) || \ (l_first == 0) || (r_first == 0) ) { - + return false; } /* Find the last value in U/D/L/R above the threshold */ @@ -824,7 +840,7 @@ bool SparkFun_APDS9960::processGestureData() (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) && (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) && (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) { - + u_last = gesture_data_.u_data[i]; d_last = gesture_data_.d_data[i]; l_last = gesture_data_.l_data[i]; @@ -833,13 +849,21 @@ bool SparkFun_APDS9960::processGestureData() } } } - + /* Catch to make sure we don't divide by 0 */ + if( ((u_first + d_first) == 0) || + ((l_first + r_first) == 0) || + ((u_last + d_last) == 0) || + ((l_last + r_last) == 0) ) { + + return false; + } + /* Calculate the first vs. last ratio of up/down and left/right */ ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first); lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first); ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last); lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last); - + #if DEBUG Serial.print(F("Last Values: ")); Serial.print(F("U:")); @@ -861,11 +885,11 @@ bool SparkFun_APDS9960::processGestureData() Serial.print(F(" LR La: ")); Serial.println(lr_ratio_last); #endif - + /* Determine the difference between the first and last ratios */ ud_delta = ud_ratio_last - ud_ratio_first; lr_delta = lr_ratio_last - lr_ratio_first; - + #if DEBUG Serial.print("Deltas: "); Serial.print("UD: "); @@ -877,7 +901,7 @@ bool SparkFun_APDS9960::processGestureData() /* Accumulate the UD and LR delta values */ gesture_ud_delta_ += ud_delta; gesture_lr_delta_ += lr_delta; - + #if DEBUG Serial.print("Accumulations: "); Serial.print("UD: "); @@ -885,7 +909,7 @@ bool SparkFun_APDS9960::processGestureData() Serial.print(" LR: "); Serial.println(gesture_lr_delta_); #endif - + /* Determine U/D gesture */ if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) { gesture_ud_count_ = 1; @@ -894,7 +918,7 @@ bool SparkFun_APDS9960::processGestureData() } else { gesture_ud_count_ = 0; } - + /* Determine L/R gesture */ if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) { gesture_lr_count_ = 1; @@ -903,18 +927,18 @@ bool SparkFun_APDS9960::processGestureData() } else { gesture_lr_count_ = 0; } - + /* Determine Near/Far gesture */ if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 0) ) { if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \ (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) { - + if( (ud_delta == 0) && (lr_delta == 0) ) { gesture_near_count_++; } else if( (ud_delta != 0) || (lr_delta != 0) ) { gesture_far_count_++; } - + if( (gesture_near_count_ >= 10) && (gesture_far_count_ >= 2) ) { if( (ud_delta == 0) && (lr_delta == 0) ) { gesture_state_ = NEAR_STATE; @@ -927,11 +951,11 @@ bool SparkFun_APDS9960::processGestureData() } else { if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \ (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) { - + if( (ud_delta == 0) && (lr_delta == 0) ) { gesture_near_count_++; } - + if( gesture_near_count_ >= 10 ) { gesture_ud_count_ = 0; gesture_lr_count_ = 0; @@ -940,7 +964,7 @@ bool SparkFun_APDS9960::processGestureData() } } } - + #if DEBUG Serial.print("UD_CT: "); Serial.print(gesture_ud_count_); @@ -952,7 +976,7 @@ bool SparkFun_APDS9960::processGestureData() Serial.println(gesture_far_count_); Serial.println("----------"); #endif - + return false; } @@ -971,7 +995,7 @@ bool SparkFun_APDS9960::decodeGesture() gesture_motion_ = DIR_FAR; return true; } - + /* Determine swipe direction */ if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) { gesture_motion_ = DIR_UP; @@ -1008,7 +1032,7 @@ bool SparkFun_APDS9960::decodeGesture() } else { return false; } - + return true; } @@ -1024,12 +1048,12 @@ bool SparkFun_APDS9960::decodeGesture() uint8_t SparkFun_APDS9960::getProxIntLowThresh() { uint8_t val; - + /* Read value from PILT register */ if( !wireReadDataByte(APDS9960_PILT, val) ) { val = 0; } - + return val; } @@ -1044,7 +1068,7 @@ bool SparkFun_APDS9960::setProxIntLowThresh(uint8_t threshold) if( !wireWriteDataByte(APDS9960_PILT, threshold) ) { return false; } - + return true; } @@ -1056,12 +1080,12 @@ bool SparkFun_APDS9960::setProxIntLowThresh(uint8_t threshold) uint8_t SparkFun_APDS9960::getProxIntHighThresh() { uint8_t val; - + /* Read value from PIHT register */ if( !wireReadDataByte(APDS9960_PIHT, val) ) { val = 0; } - + return val; } @@ -1076,7 +1100,7 @@ bool SparkFun_APDS9960::setProxIntHighThresh(uint8_t threshold) if( !wireWriteDataByte(APDS9960_PIHT, threshold) ) { return false; } - + return true; } @@ -1094,15 +1118,15 @@ bool SparkFun_APDS9960::setProxIntHighThresh(uint8_t threshold) uint8_t SparkFun_APDS9960::getLEDDrive() { uint8_t val; - + /* Read value from CONTROL register */ if( !wireReadDataByte(APDS9960_CONTROL, val) ) { return ERROR; } - + /* Shift and mask out LED drive bits */ val = (val >> 6) & 0b00000011; - + return val; } @@ -1121,23 +1145,23 @@ uint8_t SparkFun_APDS9960::getLEDDrive() bool SparkFun_APDS9960::setLEDDrive(uint8_t drive) { uint8_t val; - + /* Read value from CONTROL register */ if( !wireReadDataByte(APDS9960_CONTROL, val) ) { return false; } - + /* Set bits in register to given value */ drive &= 0b00000011; drive = drive << 6; val &= 0b00111111; val |= drive; - + /* Write register value back into CONTROL register */ if( !wireWriteDataByte(APDS9960_CONTROL, val) ) { return false; } - + return true; } @@ -1155,15 +1179,15 @@ bool SparkFun_APDS9960::setLEDDrive(uint8_t drive) uint8_t SparkFun_APDS9960::getProximityGain() { uint8_t val; - + /* Read value from CONTROL register */ if( !wireReadDataByte(APDS9960_CONTROL, val) ) { return ERROR; } - + /* Shift and mask out PDRIVE bits */ val = (val >> 2) & 0b00000011; - + return val; } @@ -1182,23 +1206,23 @@ uint8_t SparkFun_APDS9960::getProximityGain() bool SparkFun_APDS9960::setProximityGain(uint8_t drive) { uint8_t val; - + /* Read value from CONTROL register */ if( !wireReadDataByte(APDS9960_CONTROL, val) ) { return false; } - + /* Set bits in register to given value */ drive &= 0b00000011; drive = drive << 2; val &= 0b11110011; val |= drive; - + /* Write register value back into CONTROL register */ if( !wireWriteDataByte(APDS9960_CONTROL, val) ) { return false; } - + return true; } @@ -1216,15 +1240,15 @@ bool SparkFun_APDS9960::setProximityGain(uint8_t drive) uint8_t SparkFun_APDS9960::getAmbientLightGain() { uint8_t val; - + /* Read value from CONTROL register */ if( !wireReadDataByte(APDS9960_CONTROL, val) ) { return ERROR; } - + /* Shift and mask out ADRIVE bits */ val &= 0b00000011; - + return val; } @@ -1243,28 +1267,28 @@ uint8_t SparkFun_APDS9960::getAmbientLightGain() bool SparkFun_APDS9960::setAmbientLightGain(uint8_t drive) { uint8_t val; - + /* Read value from CONTROL register */ if( !wireReadDataByte(APDS9960_CONTROL, val) ) { return false; } - + /* Set bits in register to given value */ drive &= 0b00000011; val &= 0b11111100; val |= drive; - + /* Write register value back into CONTROL register */ if( !wireWriteDataByte(APDS9960_CONTROL, val) ) { return false; } - + return true; } /** * @brief Get the current LED boost value - * + * * Value Boost Current * 0 100% * 1 150% @@ -1276,15 +1300,15 @@ bool SparkFun_APDS9960::setAmbientLightGain(uint8_t drive) uint8_t SparkFun_APDS9960::getLEDBoost() { uint8_t val; - + /* Read value from CONFIG2 register */ if( !wireReadDataByte(APDS9960_CONFIG2, val) ) { return ERROR; } - + /* Shift and mask out LED_BOOST bits */ val = (val >> 4) & 0b00000011; - + return val; } @@ -1303,26 +1327,26 @@ uint8_t SparkFun_APDS9960::getLEDBoost() bool SparkFun_APDS9960::setLEDBoost(uint8_t boost) { uint8_t val; - + /* Read value from CONFIG2 register */ if( !wireReadDataByte(APDS9960_CONFIG2, val) ) { return false; } - + /* Set bits in register to given value */ boost &= 0b00000011; boost = boost << 4; val &= 0b11001111; val |= boost; - + /* Write register value back into CONFIG2 register */ if( !wireWriteDataByte(APDS9960_CONFIG2, val) ) { return false; } - + return true; -} - +} + /** * @brief Gets proximity gain compensation enable * @@ -1331,15 +1355,15 @@ bool SparkFun_APDS9960::setLEDBoost(uint8_t boost) uint8_t SparkFun_APDS9960::getProxGainCompEnable() { uint8_t val; - + /* Read value from CONFIG3 register */ if( !wireReadDataByte(APDS9960_CONFIG3, val) ) { return ERROR; } - + /* Shift and mask out PCMP bits */ val = (val >> 5) & 0b00000001; - + return val; } @@ -1352,23 +1376,23 @@ uint8_t SparkFun_APDS9960::getProxGainCompEnable() bool SparkFun_APDS9960::setProxGainCompEnable(uint8_t enable) { uint8_t val; - + /* Read value from CONFIG3 register */ if( !wireReadDataByte(APDS9960_CONFIG3, val) ) { return false; } - + /* Set bits in register to given value */ enable &= 0b00000001; enable = enable << 5; val &= 0b11011111; val |= enable; - + /* Write register value back into CONFIG3 register */ if( !wireWriteDataByte(APDS9960_CONFIG3, val) ) { return false; } - + return true; } @@ -1387,15 +1411,15 @@ uint8_t SparkFun_APDS9960::getProxGainCompEnable() uint8_t SparkFun_APDS9960::getProxPhotoMask() { uint8_t val; - + /* Read value from CONFIG3 register */ if( !wireReadDataByte(APDS9960_CONFIG3, val) ) { return ERROR; } - + /* Mask out photodiode enable mask bits */ val &= 0b00001111; - + return val; } @@ -1415,22 +1439,22 @@ uint8_t SparkFun_APDS9960::getProxPhotoMask() bool SparkFun_APDS9960::setProxPhotoMask(uint8_t mask) { uint8_t val; - + /* Read value from CONFIG3 register */ if( !wireReadDataByte(APDS9960_CONFIG3, val) ) { return false; } - + /* Set bits in register to given value */ mask &= 0b00001111; val &= 0b11110000; val |= mask; - + /* Write register value back into CONFIG3 register */ if( !wireWriteDataByte(APDS9960_CONFIG3, val) ) { return false; } - + return true; } @@ -1442,12 +1466,12 @@ bool SparkFun_APDS9960::setProxPhotoMask(uint8_t mask) uint8_t SparkFun_APDS9960::getGestureEnterThresh() { uint8_t val; - + /* Read value from GPENTH register */ if( !wireReadDataByte(APDS9960_GPENTH, val) ) { val = 0; } - + return val; } @@ -1462,7 +1486,7 @@ bool SparkFun_APDS9960::setGestureEnterThresh(uint8_t threshold) if( !wireWriteDataByte(APDS9960_GPENTH, threshold) ) { return false; } - + return true; } @@ -1474,12 +1498,12 @@ bool SparkFun_APDS9960::setGestureEnterThresh(uint8_t threshold) uint8_t SparkFun_APDS9960::getGestureExitThresh() { uint8_t val; - + /* Read value from GEXTH register */ if( !wireReadDataByte(APDS9960_GEXTH, val) ) { val = 0; } - + return val; } @@ -1494,7 +1518,7 @@ bool SparkFun_APDS9960::setGestureExitThresh(uint8_t threshold) if( !wireWriteDataByte(APDS9960_GEXTH, threshold) ) { return false; } - + return true; } @@ -1512,15 +1536,15 @@ bool SparkFun_APDS9960::setGestureExitThresh(uint8_t threshold) uint8_t SparkFun_APDS9960::getGestureGain() { uint8_t val; - + /* Read value from GCONF2 register */ if( !wireReadDataByte(APDS9960_GCONF2, val) ) { return ERROR; } - + /* Shift and mask out GGAIN bits */ val = (val >> 5) & 0b00000011; - + return val; } @@ -1539,23 +1563,23 @@ uint8_t SparkFun_APDS9960::getGestureGain() bool SparkFun_APDS9960::setGestureGain(uint8_t gain) { uint8_t val; - + /* Read value from GCONF2 register */ if( !wireReadDataByte(APDS9960_GCONF2, val) ) { return false; } - + /* Set bits in register to given value */ gain &= 0b00000011; gain = gain << 5; val &= 0b10011111; val |= gain; - + /* Write register value back into GCONF2 register */ if( !wireWriteDataByte(APDS9960_GCONF2, val) ) { return false; } - + return true; } @@ -1573,15 +1597,15 @@ bool SparkFun_APDS9960::setGestureGain(uint8_t gain) uint8_t SparkFun_APDS9960::getGestureLEDDrive() { uint8_t val; - + /* Read value from GCONF2 register */ if( !wireReadDataByte(APDS9960_GCONF2, val) ) { return ERROR; } - + /* Shift and mask out GLDRIVE bits */ val = (val >> 3) & 0b00000011; - + return val; } @@ -1600,23 +1624,23 @@ uint8_t SparkFun_APDS9960::getGestureLEDDrive() bool SparkFun_APDS9960::setGestureLEDDrive(uint8_t drive) { uint8_t val; - + /* Read value from GCONF2 register */ if( !wireReadDataByte(APDS9960_GCONF2, val) ) { return false; } - + /* Set bits in register to given value */ drive &= 0b00000011; drive = drive << 3; val &= 0b11100111; val |= drive; - + /* Write register value back into GCONF2 register */ if( !wireWriteDataByte(APDS9960_GCONF2, val) ) { return false; } - + return true; } @@ -1638,15 +1662,15 @@ bool SparkFun_APDS9960::setGestureLEDDrive(uint8_t drive) uint8_t SparkFun_APDS9960::getGestureWaitTime() { uint8_t val; - + /* Read value from GCONF2 register */ if( !wireReadDataByte(APDS9960_GCONF2, val) ) { return ERROR; } - + /* Mask out GWTIME bits */ val &= 0b00000111; - + return val; } @@ -1669,22 +1693,22 @@ uint8_t SparkFun_APDS9960::getGestureWaitTime() bool SparkFun_APDS9960::setGestureWaitTime(uint8_t time) { uint8_t val; - + /* Read value from GCONF2 register */ if( !wireReadDataByte(APDS9960_GCONF2, val) ) { return false; } - + /* Set bits in register to given value */ time &= 0b00000111; val &= 0b11111000; val |= time; - + /* Write register value back into GCONF2 register */ if( !wireWriteDataByte(APDS9960_GCONF2, val) ) { return false; } - + return true; } @@ -1698,19 +1722,19 @@ bool SparkFun_APDS9960::getLightIntLowThreshold(uint16_t &threshold) { uint8_t val_byte; threshold = 0; - + /* Read value from ambient light low threshold, low byte register */ if( !wireReadDataByte(APDS9960_AILTL, val_byte) ) { return false; } threshold = val_byte; - + /* Read value from ambient light low threshold, high byte register */ if( !wireReadDataByte(APDS9960_AILTH, val_byte) ) { return false; } threshold = threshold + ((uint16_t)val_byte << 8); - + return true; } @@ -1724,21 +1748,21 @@ bool SparkFun_APDS9960::setLightIntLowThreshold(uint16_t threshold) { uint8_t val_low; uint8_t val_high; - + /* Break 16-bit threshold into 2 8-bit values */ val_low = threshold & 0x00FF; val_high = (threshold & 0xFF00) >> 8; - + /* Write low byte */ if( !wireWriteDataByte(APDS9960_AILTL, val_low) ) { return false; } - + /* Write high byte */ if( !wireWriteDataByte(APDS9960_AILTH, val_high) ) { return false; } - + return true; } @@ -1752,19 +1776,19 @@ bool SparkFun_APDS9960::getLightIntHighThreshold(uint16_t &threshold) { uint8_t val_byte; threshold = 0; - + /* Read value from ambient light high threshold, low byte register */ if( !wireReadDataByte(APDS9960_AIHTL, val_byte) ) { return false; } threshold = val_byte; - + /* Read value from ambient light high threshold, high byte register */ if( !wireReadDataByte(APDS9960_AIHTH, val_byte) ) { return false; } threshold = threshold + ((uint16_t)val_byte << 8); - + return true; } @@ -1778,21 +1802,21 @@ bool SparkFun_APDS9960::setLightIntHighThreshold(uint16_t threshold) { uint8_t val_low; uint8_t val_high; - + /* Break 16-bit threshold into 2 8-bit values */ val_low = threshold & 0x00FF; val_high = (threshold & 0xFF00) >> 8; - + /* Write low byte */ if( !wireWriteDataByte(APDS9960_AIHTL, val_low) ) { return false; } - + /* Write high byte */ if( !wireWriteDataByte(APDS9960_AIHTH, val_high) ) { return false; } - + return true; } @@ -1805,12 +1829,12 @@ bool SparkFun_APDS9960::setLightIntHighThreshold(uint16_t threshold) bool SparkFun_APDS9960::getProximityIntLowThreshold(uint8_t &threshold) { threshold = 0; - + /* Read value from proximity low threshold register */ if( !wireReadDataByte(APDS9960_PILT, threshold) ) { return false; } - + return true; } @@ -1822,15 +1846,15 @@ bool SparkFun_APDS9960::getProximityIntLowThreshold(uint8_t &threshold) */ bool SparkFun_APDS9960::setProximityIntLowThreshold(uint8_t threshold) { - + /* Write threshold value to register */ if( !wireWriteDataByte(APDS9960_PILT, threshold) ) { return false; } - + return true; } - + /** * @brief Gets the high threshold for proximity interrupts * @@ -1840,12 +1864,12 @@ bool SparkFun_APDS9960::setProximityIntLowThreshold(uint8_t threshold) bool SparkFun_APDS9960::getProximityIntHighThreshold(uint8_t &threshold) { threshold = 0; - + /* Read value from proximity low threshold register */ if( !wireReadDataByte(APDS9960_PIHT, threshold) ) { return false; } - + return true; } @@ -1857,12 +1881,12 @@ bool SparkFun_APDS9960::getProximityIntHighThreshold(uint8_t &threshold) */ bool SparkFun_APDS9960::setProximityIntHighThreshold(uint8_t threshold) { - + /* Write threshold value to register */ if( !wireWriteDataByte(APDS9960_PIHT, threshold) ) { return false; } - + return true; } @@ -1874,15 +1898,15 @@ bool SparkFun_APDS9960::setProximityIntHighThreshold(uint8_t threshold) uint8_t SparkFun_APDS9960::getAmbientLightIntEnable() { uint8_t val; - + /* Read value from ENABLE register */ if( !wireReadDataByte(APDS9960_ENABLE, val) ) { return ERROR; } - + /* Shift and mask out AIEN bit */ val = (val >> 4) & 0b00000001; - + return val; } @@ -1895,23 +1919,23 @@ uint8_t SparkFun_APDS9960::getAmbientLightIntEnable() bool SparkFun_APDS9960::setAmbientLightIntEnable(uint8_t enable) { uint8_t val; - + /* Read value from ENABLE register */ if( !wireReadDataByte(APDS9960_ENABLE, val) ) { return false; } - + /* Set bits in register to given value */ enable &= 0b00000001; enable = enable << 4; val &= 0b11101111; val |= enable; - + /* Write register value back into ENABLE register */ if( !wireWriteDataByte(APDS9960_ENABLE, val) ) { return false; } - + return true; } @@ -1923,15 +1947,15 @@ bool SparkFun_APDS9960::setAmbientLightIntEnable(uint8_t enable) uint8_t SparkFun_APDS9960::getProximityIntEnable() { uint8_t val; - + /* Read value from ENABLE register */ if( !wireReadDataByte(APDS9960_ENABLE, val) ) { return ERROR; } - + /* Shift and mask out PIEN bit */ val = (val >> 5) & 0b00000001; - + return val; } @@ -1944,23 +1968,23 @@ uint8_t SparkFun_APDS9960::getProximityIntEnable() bool SparkFun_APDS9960::setProximityIntEnable(uint8_t enable) { uint8_t val; - + /* Read value from ENABLE register */ if( !wireReadDataByte(APDS9960_ENABLE, val) ) { return false; } - + /* Set bits in register to given value */ enable &= 0b00000001; enable = enable << 5; val &= 0b11011111; val |= enable; - + /* Write register value back into ENABLE register */ if( !wireWriteDataByte(APDS9960_ENABLE, val) ) { return false; } - + return true; } @@ -1972,15 +1996,15 @@ bool SparkFun_APDS9960::setProximityIntEnable(uint8_t enable) uint8_t SparkFun_APDS9960::getGestureIntEnable() { uint8_t val; - + /* Read value from GCONF4 register */ if( !wireReadDataByte(APDS9960_GCONF4, val) ) { return ERROR; } - + /* Shift and mask out GIEN bit */ val = (val >> 1) & 0b00000001; - + return val; } @@ -1993,23 +2017,23 @@ uint8_t SparkFun_APDS9960::getGestureIntEnable() bool SparkFun_APDS9960::setGestureIntEnable(uint8_t enable) { uint8_t val; - + /* Read value from GCONF4 register */ if( !wireReadDataByte(APDS9960_GCONF4, val) ) { return false; } - + /* Set bits in register to given value */ enable &= 0b00000001; enable = enable << 1; val &= 0b11111101; val |= enable; - + /* Write register value back into GCONF4 register */ if( !wireWriteDataByte(APDS9960_GCONF4, val) ) { return false; } - + return true; } @@ -2024,7 +2048,7 @@ bool SparkFun_APDS9960::clearAmbientLightInt() if( !wireReadDataByte(APDS9960_AICLEAR, throwaway) ) { return false; } - + return true; } @@ -2039,7 +2063,7 @@ bool SparkFun_APDS9960::clearProximityInt() if( !wireReadDataByte(APDS9960_PICLEAR, throwaway) ) { return false; } - + return true; } @@ -2051,15 +2075,15 @@ bool SparkFun_APDS9960::clearProximityInt() uint8_t SparkFun_APDS9960::getGestureMode() { uint8_t val; - + /* Read value from GCONF4 register */ if( !wireReadDataByte(APDS9960_GCONF4, val) ) { return ERROR; } - + /* Mask out GMODE bit */ val &= 0b00000001; - + return val; } @@ -2072,22 +2096,22 @@ uint8_t SparkFun_APDS9960::getGestureMode() bool SparkFun_APDS9960::setGestureMode(uint8_t mode) { uint8_t val; - + /* Read value from GCONF4 register */ if( !wireReadDataByte(APDS9960_GCONF4, val) ) { return false; } - + /* Set bits in register to given value */ mode &= 0b00000001; val &= 0b11111110; val |= mode; - + /* Write register value back into GCONF4 register */ if( !wireWriteDataByte(APDS9960_GCONF4, val) ) { return false; } - + return true; } @@ -2108,7 +2132,7 @@ bool SparkFun_APDS9960::wireWriteByte(uint8_t val) if( Wire.endTransmission() != 0 ) { return false; } - + return true; } @@ -2139,11 +2163,13 @@ bool SparkFun_APDS9960::wireWriteDataByte(uint8_t reg, uint8_t val) * @param[in] len the length (in bytes) of the data to write * @return True if successful write operation. False otherwise. */ -bool SparkFun_APDS9960::wireWriteDataBlock( uint8_t reg, - uint8_t *val, - unsigned int len) +bool SparkFun_APDS9960::wireWriteDataBlock( uint8_t reg, + uint8_t *val, +//Jon unsigned int len) + uint16_t len) { - unsigned int i; + //Jon unsigned int i; + uint16_t i; Wire.beginTransmission(APDS9960_I2C_ADDR); Wire.write(reg); @@ -2166,12 +2192,16 @@ bool SparkFun_APDS9960::wireWriteDataBlock( uint8_t reg, */ bool SparkFun_APDS9960::wireReadDataByte(uint8_t reg, uint8_t &val) { - + /* Indicate which register we want to read from */ if (!wireWriteByte(reg)) { return false; } - + + // Jon SH: Short delay to improve stability of read from the APDS9960 + // without this Wire.requestFrom appears to not return. + delayMicroseconds(100); + /* Read from register */ Wire.requestFrom(APDS9960_I2C_ADDR, 1); while (Wire.available()) { @@ -2189,17 +2219,19 @@ bool SparkFun_APDS9960::wireReadDataByte(uint8_t reg, uint8_t &val) * @param[in] len number of bytes to read * @return Number of bytes read. -1 on read error. */ -int SparkFun_APDS9960::wireReadDataBlock( uint8_t reg, - uint8_t *val, - unsigned int len) + //Jon int SparkFun_APDS9960::wireReadDataBlock( uint8_t reg, +int16_t SparkFun_APDS9960::wireReadDataBlock( uint8_t reg, + uint8_t *val, +//Jon unsigned int len) + uint16_t len) { unsigned char i = 0; - + /* Indicate which register we want to read from */ if (!wireWriteByte(reg)) { return -1; } - + /* Read block data */ Wire.requestFrom(APDS9960_I2C_ADDR, len); while (Wire.available()) { @@ -2211,4 +2243,4 @@ int SparkFun_APDS9960::wireReadDataBlock( uint8_t reg, } return i; -} \ No newline at end of file +} diff --git a/src/SparkFun_APDS9960.h b/src/SparkFun_APDS9960.h index ac92c7d..7ead49b 100644 --- a/src/SparkFun_APDS9960.h +++ b/src/SparkFun_APDS9960.h @@ -10,7 +10,7 @@ * relies on the Arduino Wire (I2C) library. to use the library, instantiate an * APDS9960 object, call init(), and call the appropriate functions. */ - + #ifndef SparkFun_APDS9960_H #define SparkFun_APDS9960_H @@ -32,7 +32,7 @@ /* Acceptable device IDs */ #define APDS9960_ID_1 0xAB -#define APDS9960_ID_2 0x9C +#define APDS9960_ID_2 0x9C /* Misc parameters */ #define FIFO_PAUSE_TIME 30 // Wait period (ms) between FIFO reads @@ -106,7 +106,7 @@ #define POWER 0 #define AMBIENT_LIGHT 1 #define PROXIMITY 2 -#define WAIT 3 +#define WAITING_TIME 3 #define AMBIENT_LIGHT_INT 4 #define PROXIMITY_INT 5 #define GESTURE 6 @@ -140,7 +140,7 @@ #define LED_BOOST_100 0 #define LED_BOOST_150 1 #define LED_BOOST_200 2 -#define LED_BOOST_300 3 +#define LED_BOOST_300 3 /* Gesture wait time values */ #define GWTIME_0MS 0 @@ -158,7 +158,7 @@ #define DEFAULT_PROX_PPULSE 0x87 // 16us, 8 pulses #define DEFAULT_GESTURE_PPULSE 0x89 // 16us, 10 pulses #define DEFAULT_POFFSET_UR 0 // 0 offset -#define DEFAULT_POFFSET_DL 0 // 0 offset +#define DEFAULT_POFFSET_DL 0 // 0 offset #define DEFAULT_CONFIG1 0x60 // No 12x wait (WTIME) factor #define DEFAULT_LDRIVE LED_DRIVE_100MA #define DEFAULT_PGAIN PGAIN_4X @@ -168,13 +168,15 @@ #define DEFAULT_AILT 0xFFFF // Force interrupt for calibration #define DEFAULT_AIHT 0 #define DEFAULT_PERS 0x11 // 2 consecutive prox or ALS for int. -#define DEFAULT_CONFIG2 0x01 // No saturation interrupts or LED boost +#define DEFAULT_CONFIG2 0x01 // No saturation interrupts or LED boost #define DEFAULT_CONFIG3 0 // Enable all photodiodes, no SAI #define DEFAULT_GPENTH 40 // Threshold for entering gesture mode -#define DEFAULT_GEXTH 30 // Threshold for exiting gesture mode +#define DEFAULT_GEXTH 30 // Threshold for exiting gesture mode #define DEFAULT_GCONF1 0x40 // 4 gesture events for int., 1 for exit #define DEFAULT_GGAIN GGAIN_4X -#define DEFAULT_GLDRIVE LED_DRIVE_100MA +//#define DEFAULT_GGAIN GGAIN_2X +//#define DEFAULT_GLDRIVE LED_DRIVE_100MA +#define DEFAULT_GLDRIVE LED_DRIVE_25MA #define DEFAULT_GWTIME GWTIME_2_8MS #define DEFAULT_GOFFSET 0 // No offset scaling for gesture mode #define DEFAULT_GPULSE 0xC9 // 32us, 10 pulses @@ -195,7 +197,7 @@ enum { /* State definitions */ enum { - NA_STATE, + APDS_NA_STATE, NEAR_STATE, FAR_STATE, ALL_STATE @@ -223,11 +225,11 @@ class SparkFun_APDS9960 { bool init(); uint8_t getMode(); bool setMode(uint8_t mode, uint8_t enable); - + /* Turn the APDS-9960 on and off */ bool enablePower(); bool disablePower(); - + /* Enable or disable specific sensors */ bool enableLightSensor(bool interrupts = false); bool disableLightSensor(); @@ -235,13 +237,13 @@ class SparkFun_APDS9960 { bool disableProximitySensor(); bool enableGestureSensor(bool interrupts = true); bool disableGestureSensor(); - + /* LED drive strength control */ uint8_t getLEDDrive(); bool setLEDDrive(uint8_t drive); uint8_t getGestureLEDDrive(); bool setGestureLEDDrive(uint8_t drive); - + /* Gain control */ uint8_t getAmbientLightGain(); bool setAmbientLightGain(uint8_t gain); @@ -249,19 +251,19 @@ class SparkFun_APDS9960 { bool setProximityGain(uint8_t gain); uint8_t getGestureGain(); bool setGestureGain(uint8_t gain); - + /* Get and set light interrupt thresholds */ bool getLightIntLowThreshold(uint16_t &threshold); bool setLightIntLowThreshold(uint16_t threshold); bool getLightIntHighThreshold(uint16_t &threshold); bool setLightIntHighThreshold(uint16_t threshold); - + /* Get and set proximity interrupt thresholds */ bool getProximityIntLowThreshold(uint8_t &threshold); bool setProximityIntLowThreshold(uint8_t threshold); bool getProximityIntHighThreshold(uint8_t &threshold); bool setProximityIntHighThreshold(uint8_t threshold); - + /* Get and set interrupt enables */ uint8_t getAmbientLightIntEnable(); bool setAmbientLightIntEnable(uint8_t enable); @@ -269,24 +271,25 @@ class SparkFun_APDS9960 { bool setProximityIntEnable(uint8_t enable); uint8_t getGestureIntEnable(); bool setGestureIntEnable(uint8_t enable); - + /* Clear interrupts */ bool clearAmbientLightInt(); bool clearProximityInt(); - + /* Ambient light methods */ bool readAmbientLight(uint16_t &val); bool readRedLight(uint16_t &val); bool readGreenLight(uint16_t &val); bool readBlueLight(uint16_t &val); - + /* Proximity methods */ bool readProximity(uint8_t &val); - + /* Gesture methods */ bool isGestureAvailable(); - int readGesture(); - + //Jon int readGesture(); + int16_t readGesture(); + private: /* Gesture processing */ @@ -299,27 +302,27 @@ class SparkFun_APDS9960 { bool setProxIntLowThresh(uint8_t threshold); uint8_t getProxIntHighThresh(); bool setProxIntHighThresh(uint8_t threshold); - + /* LED Boost Control */ uint8_t getLEDBoost(); bool setLEDBoost(uint8_t boost); - + /* Proximity photodiode select */ uint8_t getProxGainCompEnable(); bool setProxGainCompEnable(uint8_t enable); uint8_t getProxPhotoMask(); bool setProxPhotoMask(uint8_t mask); - + /* Gesture threshold control */ uint8_t getGestureEnterThresh(); bool setGestureEnterThresh(uint8_t threshold); uint8_t getGestureExitThresh(); bool setGestureExitThresh(uint8_t threshold); - + /* Gesture LED, gain, and time control */ uint8_t getGestureWaitTime(); bool setGestureWaitTime(uint8_t time); - + /* Gesture mode */ uint8_t getGestureMode(); bool setGestureMode(uint8_t mode); @@ -327,12 +330,15 @@ class SparkFun_APDS9960 { /* Raw I2C Commands */ bool wireWriteByte(uint8_t val); bool wireWriteDataByte(uint8_t reg, uint8_t val); - bool wireWriteDataBlock(uint8_t reg, uint8_t *val, unsigned int len); + // Jon bool wireWriteDataBlock(uint8_t reg, uint8_t *val, unsigned int len); + bool wireWriteDataBlock(uint8_t reg, uint8_t *val, uint16_t len); bool wireReadDataByte(uint8_t reg, uint8_t &val); - int wireReadDataBlock(uint8_t reg, uint8_t *val, unsigned int len); + // Jon int wireReadDataBlock(uint8_t reg, uint8_t *val, unsigned int len); + int16_t wireReadDataBlock(uint8_t reg, uint8_t *val, uint16_t len); /* Members */ gesture_data_type gesture_data_; + /* Jon int gesture_ud_delta_; int gesture_lr_delta_; int gesture_ud_count_; @@ -341,6 +347,15 @@ class SparkFun_APDS9960 { int gesture_far_count_; int gesture_state_; int gesture_motion_; + */ + int16_t gesture_ud_delta_; + int16_t gesture_lr_delta_; + int16_t gesture_ud_count_; + int16_t gesture_lr_count_; + int16_t gesture_near_count_; + int16_t gesture_far_count_; + int16_t gesture_state_; + int16_t gesture_motion_; }; -#endif \ No newline at end of file +#endif