Giter VIP home page Giter VIP logo

adafruit_apds9960's Introduction

Adafruit_APDS9960 Build Status

This is the Adafruit APDS9960 Proximity, Light, RGB, and Gesture sensor Library

Tested and works great with the Adafruit APDS9960 Board

This chip uses I2C to communicate, 2 pins are required to interface

Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!

Written by Dean Miller, Limor Fried for Adafruit Industries.
BSD license, check license.txt for more information All text above must be included in any redistribution

To install, use the Arduino Library Manager and search for "Adafruit APDS9960 Library" and install the library.

adafruit_apds9960's People

Contributors

adamjhowell avatar caternuson avatar deanm1278 avatar dodo5522 avatar evaherrada avatar hoffmannjan avatar ladyada avatar majorbreakfast avatar mark255bits avatar noisyfly avatar peacheym avatar per1234 avatar siddacious avatar szymonkaliski avatar tyeth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adafruit_apds9960's Issues

Adjust Proximity gain

Hi, how can I change Proximity Gain from default (1x I think) to 8x?

apds.setProxGain(APDS9960_PGAIN_8X); might do the job?

Thanks.

Gesture Sensing & Code Blocking

Is there any possibility to make the gesture sensing non-blocking? At the moment, when gestures are enabled and something is in close proximity of the sensor, everything in the program is blocked.
Assuming there's no blocking functions in the user's code, could a function, say, "apds.update()" that's running in the loop function achieve the same functionality without blocking everything else?
Is this a sensor hardware/firmware limitation or just the way the library was written?

calculateLux does not reflect APDS sensor documentation

  • Arduino board: ESP32

  • Arduino IDE version (found in Arduino -> About Arduino menu): 1.8.16

  • List the steps to reproduce the problem below:
    In any condition a call to apds.calculateLux returns incorrect results.
    You can reproduce this via:
    uint16_t lux = apds.calculateLux(r, g, b); or uint32_t lux = apds.calculateLux(r, g, b);

    The values used as RGB conversion factors in the library are not correct and do not reflect the irradiance responsivity described in
    APDS documentation. This results in the calculated lux values being completely wrong.

if my math is right, which it probably isn't totally;
double lux = (double(c) / (2360.0)) * 468.2344;
would work better, where c is the clear output 'count'. I used this as a basis for calculating lux given the 'clear' sensitivity
(here)

Sensor's loop take control of the main arduino loop ?

Hi,

Using the Adafruit_APDS9960, i noticed in the source code the following:

uint8_t Adafruit_APDS9960::readGesture(void) 
{
	uint8_t toRead, bytesRead;
	uint8_t buf[256];
	unsigned long t;
	uint8_t gestureReceived;
	while(1){
           ...

Why is there a while(1) there ?

This cause the main arduino loop to be stopped because of this while (or maybe i'm doing something wrong ?).

If i run the gesture sensor example, and add a println in the loop(), the print is displayed in the console until we activate the gesture sensor with the hand. Then, the loop is stuck, and the only events we got are from the while(1) loop.

I don't know if i'm clear (and sorry for my english). I wanted the sensor to be a global switch (on/off) to my program, but apparently, this cannot be done that way.

Thanks.

Sylvain.

ESP8266 - SparkFun_APDS9960.h:202:1: error: expected declaration before '}' token

The following error occur when compiling a sketch for ESP8266:

SparkFun_APDS9960.h:202:1: error: expected declaration before '}' token

The sketch is the following:

/****************************************************************
GestureTest.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
May 30, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor

Tests the gesture sensing abilities of the APDS-9960. Configures
APDS-9960 over I2C and waits for gesture events. Calculates the
direction of the swipe (up, down, left, right) and displays it
on a serial console. 

To perform a NEAR gesture, hold your hand
far above the sensor and move it close to the sensor (within 2
inches). Hold your hand there for at least 1 second and move it
away.

To perform a FAR gesture, hold your hand within 2 inches of the
sensor for at least 1 second and then move it above (out of
range) of the sensor.

Hardware Connections:

IMPORTANT: The APDS-9960 can only accept 3.3V!
 
 Arduino Pin  APDS-9960 Board  Function
 
 3.3V         VCC              Power
 GND          GND              Ground
 A4           SDA              I2C Data
 A5           SCL              I2C Clock
 2            INT              Interrupt

Resources:
Include Wire.h and SparkFun_APDS-9960.h

Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V

This 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!

Distributed as-is; no warranty is given.
****************************************************************/

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <SparkFun_APDS9960.h>

// Pins
#define APDS9960_INT    D3
#define MCU_SCL D1
#define MCU_SDA D2

// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;

void setup() {

  // Set interrupt pin as input
  pinMode(APDS9960_INT, INPUT);

  // Initialize Serial port
  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);

  Wire.begin(MCU_SDA, MCU_SCL);

  // Initialize APDS-9960 (configure I2C and initial values)
  if ( apds.init() ) {
    Serial.println(F("APDS-9960 initialization complete"));
  } else {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  
  // Start running the APDS-9960 gesture sensor engine
  if ( apds.enableGestureSensor(true) ) {
    Serial.println(F("Gesture sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during gesture sensor init!"));
  }
}

void loop() {
  if( isr_flag == 1 ) {
    detachInterrupt(0);
    handleGesture();
    isr_flag = 0;
    attachInterrupt(0, interruptRoutine, FALLING);
  }
}

void interruptRoutine() {
  isr_flag = 1;
}

void handleGesture() {
    if ( apds.isGestureAvailable() ) {
    switch ( apds.readGesture() ) {
      case DIR_UP:
        Serial.println("UP");
        break;
      case DIR_DOWN:
        Serial.println("DOWN");
        break;
      case DIR_LEFT:
        Serial.println("LEFT");
        break;
      case DIR_RIGHT:
        Serial.println("RIGHT");
        break;
      case DIR_NEAR:
        Serial.println("NEAR");
        break;
      case DIR_FAR:
        Serial.println("FAR");
        break;
      default:
        Serial.println("NONE");
    }
  }
}

Circuitpython

Hi there,

will there be a driver for circuitpython in the future?

Thanks and please continue with your good work!

Best regards from germany,
Pascal

gconf1::get() is incorrect.

Is:
uint8_t get(){
return (GFIFOTH << 7) | (GEXMSK << 5) | GEXPERS;
Should be:
uint8_t get(){
return (GFIFOTH << 6) | (GEXMSK << 2) | GEXPERS;

The Color Data returned is formatted incorrectly (i think)

getColorData() calls read16() which formats the device returned as a 16 bit integer.

return (ret[0] << 8) | ret[1];

The first byte is format as the High byte and the 2nd as the Low byte. The documentation for the device is the exact opposite.

The Arduino code has no option to use alternate pins on the micro contorller

I am porting my code from Circuit Python to Arduino C due to motor speed issues. Circuit Python allows you to use alternate pins for the SCL and SDA, I am currently using RX and TX. I have been diving into the source files and cannot find a way to change the pins unless I rewrite the Wire.h files.

Adding this functionality would allow the use of multiple 9960 sensors, but in my case, I am using a featherwing that is blocking any other sensor from using the same i2c bus.

Proximity and gesture at the same time doesn't work

My application needs proximity and gesture detection at the same time.
I tried to combine both exemples, and it just doesn't work.

If I take the proximity threshold interruption off, after the first gesture detection, the proximity valeu begans to return a constant value.

If I hold the proximity threshold in the firmware I got no return from the readings.

This is the adapted firmware:

#include "Adafruit_APDS9960.h"
Adafruit_APDS9960 apds;

#define INT_PIN 3

void setup() {
Serial.begin(115200);

if(!apds.begin()){
Serial.println("failed to initialize device! Please check your wiring.");
}
else Serial.println("Device initialized!");

//gesture mode will be entered once proximity mode senses something close
apds.enableProximity(true);
apds.enableGesture(true);

//apds.setProximityInterruptThreshold(0,50);
//apds.enableProximityInterrupt();
//pinMode(INT_PIN, INPUT_PULLUP);
}

// the loop function runs over and over again forever
void loop() {
//read a gesture from the device
uint8_t gesture = apds.readGesture();
if(gesture == APDS9960_DOWN) Serial.println("^");
if(gesture == APDS9960_UP) Serial.println("v");
if(gesture == APDS9960_LEFT) Serial.println("x");
if(gesture == APDS9960_RIGHT) Serial.println("o");
Serial.println(apds.readProximity());
//if (!digitalRead(INT_PIN)){
// apds.clearInterrupt();
//Serial.println(apds.readProximity());
//}
delay (300);
}

IR Pulse width

I'm making a smart node that integrates display, BME280 (temperature/humidity/preassure), TSOP 32238 (38kHz IR sensor) and the apds9960.

When i activate the geasure recognition or proximity sensor using

apds.enableProximity(true);
apds.enableGesture(true);

the APDS sensor starts to send IR pulses. I don't know the exact frequency of the IR pulses but the TSOP 32238 is picking them up.

I found in this datasheet that the pusles should be 62.5 kHz which is well above the range of the TSOP.

In the datasheet there is mentioned that you can influence the signal frequency and in code of this library there is

enum
{
	APDS9960_GPULSE_4US		= 0x00,
	APDS9960_GPULSE_8US		= 0x01,
	APDS9960_GPULSE_16US	= 0x02,
	APDS9960_GPULSE_32US	= 0x03,
};

and

boolean Adafruit_APDS9960::begin(uint16_t iTimeMS, apds9960AGain_t aGain, uint8_t addr) 
.
.
.
 
  _gpulse.GPLEN = APDS9960_GPULSE_32US;
  _gpulse.GPULSE = 9; //10 pulses
  this->write8(APDS9960_GPULSE, _gpulse.get());
.
.
.
}

So if i understand correctly the pulse width of 32US is arround 31kHz.

I will change the value manually in the lib and test later today if the signals collide and if it affects the signal of the IR sensor and let you know.

But could you add a possiblity to change the frequency to APDS9960_GPULSE_4US (250kHz) or a different value when calling begin?

esp32

does this work with the esp32? I have not been able to get the sensor to respond though i can get it to work on an Uno.

'calculateLux' unexpected overflow behavior due to use of uint16_t

  • Arduino board: ESP32

  • Arduino IDE version (found in Arduino -> About Arduino menu): 1.8.16

  • List the steps to reproduce the problem below:
    In dark conditions a call to apds.calculateLux inverts values and returns values at or near 65534.
    You can reproduced this via:
    uint16_t lux = apds.calculateLux(r, g, b); or uint32_t lux = apds.calculateLux(r, g, b);

    This is a straightforward fix and I can make a pull request if this repo is still being maintained.

Incorrect bit field definitions

Hello,

The Adafruit APDS_9960 library is unable to configures some sensor register incorrectly as some bit fields are incorrectly defined.
For example in Adafruit_APDS9960.h

/** Proxmity gain settings */
typedef enum {
  APDS9960_PGAIN_1X = 0x00, /**< 1x gain */
  APDS9960_PGAIN_2X = 0x04, /**< 2x gain */
  APDS9960_PGAIN_4X = 0x08, /**< 4x gain */
  APDS9960_PGAIN_8X = 0x0C  /**< 8x gain */
} apds9960PGain_t;

These values are already bit shifted as the PGAIN bit field uses the bits (3:2) of the register Control register One(0x8F).
But if for example one were to use the method setProxGain this will not correct configure as the struct _control get() function bit shiftes again the pgain bit field.
uint8_t get() { return (LDRIVE << 6) | (PGAIN << 2) | AGAIN; }
A possible solution could be change the enum definition to:

/** Proxmity gain settings */
typedef enum {
  APDS9960_PGAIN_1X = 0x00, /**< 1x gain */
  APDS9960_PGAIN_2X = 0x01, /**< 2x gain */
  APDS9960_PGAIN_4X = 0x02, /**< 4x gain */
  APDS9960_PGAIN_8X = 0x03  /**< 8x gain */
} apds9960PGain_t;

Which will solve the problem and be more alligned bit the APDS99600 datasheet as they define the bit field values without bit shifting.
image

The same bug is applicable to apds9960PPulseLen_t , apds9960LedDrive_t and apds9960LedBoost_t.
The values of the different enums should be 0x00, 0x01x 0x02 and 0x03.

Adjustment of the gesture detection

Hello,
I state the problem, that I want to achieve a gesture detection with a proximity adjustment.
The proximity value will not reach 0 and will be above 130 so no gesture is read. Is there anyone who could help me and is there a way to do so in the code?
I am using the gesture example right now and tested around with the setGestureGain and setADCGain functions with no result.
If I use the proximity mode, I got values between 130 and 255 so it is still working as intended.
Thank you for the answers.

#include "Adafruit_APDS9960.h"
Adafruit_APDS9960 apds;


// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(115200);

  
  if(!apds.begin()){
    Serial.println("failed to initialize device! Please check your wiring.");
  }
  else Serial.println("Device initialized!");

  //gesture mode will be entered once proximity mode senses something close
  //apds.enableProximity(true);
  apds.enableGesture(true);

  //apds.setGestureProximityThreshold(135);
  apds.setGestureGain(0x02); //sets gesture gain to 4x
  apds.setADCGain(0x03); //sets ambientlight gain to 64x

}



// the loop function runs over and over again forever
void loop() {
  //read a gesture from the device
    uint8_t gesture = apds.readGesture();
    if(gesture == APDS9960_DOWN) Serial.println("RIGHT");
    if(gesture == APDS9960_UP) Serial.println("RIGHT");
    if(gesture == APDS9960_LEFT) Serial.println("LEFT");
    if(gesture == APDS9960_RIGHT) Serial.println("LEFT");
}

Would you consider adding a lux demo?

I'm planning to buy the breakout and pop it on a breadboard with my micro:bit and a DragonTail - if you say no I'll try and ask for more documentation in the learn guide.

I have problems with RGB reader value and with de calculate LUX and Color temperature.

Hi Guys. I am working whit an APDS-9960, I am try obtain the LUX and Color temperature with Adafruit library, but the result that I obtein is not real. If I read with a luxmeter the result is very diferent, Do you have any Examples with tested code?

My test code is:
#include "Adafruit_APDS9960.h"
Adafruit_APDS9960 apds;

void setup() {
Serial.begin(115200);

if(!apds.begin()){
Serial.println("failed to initialize device! Please check your wiring.");
}
else Serial.println("Device initialized!");
//enable color sensign mode
apds.enableColor(true);
}

void loop() {
//create some variables to store the color data in
uint16_t r, g, b, c;
//wait for color data to be ready
while(!apds.colorDataReady()){
delay(5);
}
//get the data and print the different channels
apds.getColorData(&r, &g, &b, &c);
Serial.print("red: ");
Serial.print(r);
Serial.print(" green: ");
Serial.print(g);
Serial.print(" blue: ");
Serial.print(b);
Serial.print(" clear: ");
Serial.println(c);
Serial.println();
float luz=apds.calculateLux(r,g,b);
float color=apds.calculateColorTemperature(r,g,b);
Serial.print (" LUXES: ");
Serial.println (luz);
Serial.print (" Color: ");
Serial.println (color);
delay(500);
}
Regards. Seba

Use all sensors

Hi,
How can I use in same time all sensors: color sensor, gesture senor and proximity sensor?

The for loops in readGesture analyze the first sample repeatedly instead of all samples

https://github.com/adafruit/Adafruit_APDS9960/blob/master/Adafruit_APDS9960.cpp#L336

This code never used the loop variable in these two for loops so they are merely repeatedly using at the same sample in the FIFO multiple times instead of considering each sample as they should be. I believe you wanted to add i*4 to all of your buf indices or rework your for loop to something similar to for(int i=0; i<bytesRead; i+=4) and just use i as the buf index base.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.