Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: add driver for APDS99XX ambient light and proximity sensors #10420

Merged
merged 4 commits into from
Mar 11, 2020

Conversation

gschorcht
Copy link
Contributor

Contribution description

This PR adds a driver for Broadcom APDS99XX ambient light and proximity sensor series. It supports the following sensors:

Sensor Driver variant Proximitiy [counts] Ambient light [counts] RGB [counts] Illuminance [Lux]
APDS9900 apds9900 x x - x
APDS9901 apds9901 x x - x
APDS9930 apds9930 x x - x
APDS9950 apds9950 x x x -
APDS9960 apds9960 x x x -

The driver variants for the various sensors are defined as pseudomodules. To use the driver, the sensor used must be specified by the application by one of these pseudomodules, e.g.,

USEMODULE += apds9900

The driver functionality is divided in two parts:

  • Basic driver apds99xx
    The base driver apds99xx only supports a basic set of functions and has therefore a smaller size. The procedure for retrieving new data is polling. Ambient light and proximity sensing are supported.

  • Fully functional driver apds99xx_full
    The fully functional driver apds99xx_full supports all the features supported by the base driver, as well as all other sensor features, including interrupts and their configuration. Data-ready interrupts can be used to retrieve data. In addition, threshold interrupts can be used and configured.

For each of the two driver variants there is a corresponding test application: tests/driver_apds99xx and tests/driver_apds99xx_full.

The basic driver apds99xx is automatically enabled when the driver variant for the used sensor is specicied.

Testing procedure

To test the driver, the test application can be used without interrupts as following

USEMODULE=apds9960 make flash -C ```tests/driver_apds99xx``` BOARD=...

or with interrupt

USEMODULE=apds9960 make flash -C ```tests/driver_apds99xx``` BOARD=...

where the sensor used has be specified accordingly in the USEMODULE statement.

Issues/PRs references

Fixes issue #10164

@gschorcht gschorcht added Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: drivers Area: Device drivers labels Nov 17, 2018
@gschorcht gschorcht added the Area: SAUL Area: Sensor/Actuator Uber Layer label Nov 18, 2018
@aabadie aabadie added this to the Release 2019.01 milestone Dec 3, 2018
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
Copy link
Contributor

@leandrolanzieri leandrolanzieri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! Here are some comments, I'm still reviewing it though, it's a pretty big driver. I will also try to get a sensor to test this.

drivers/apds99xx/apds99xx.c Outdated Show resolved Hide resolved
drivers/apds99xx/apds99xx.c Outdated Show resolved Hide resolved
#else
EXEC_RET(_reg_write(dev, APDS99XX_REG_PPCOUNT, &dev->params.prx_pulses, 1));
EXEC_RET(_update_reg(dev, APDS99XX_REG_CONTROL, APDS99XX_REG_PDIODE, 2));
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and above, please add the comment of the corresponding tag (/* MODULE_APDS9960 */)

__func__, d->params.dev, APDS99XX_I2C_ADDRESS, ## __VA_ARGS__);

#define EXEC_RET(f) { \
int _r; \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better not to assign the value to _r inside of the if statement. Also, is the intermediate variable really needed here and below?

Copy link
Contributor Author

@gschorcht gschorcht Dec 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review.

It would be better not to assign the value to _r inside of the if statement.

I'm wondering why? What is the reason.

Also, is the intermediate variable really needed here and below?

Yes, if we want to print out the error code in the debug message.
But more important, we have to return the error code we got from executed function in case of error.

drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
Copy link
Contributor

@leandrolanzieri leandrolanzieri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some little comments, otherwise looks good. I don't think I will be getting the sensor in time for testing this for the feature freeze. @aabadie any chances you could?

drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
drivers/apds99xx/apds99xx.c Outdated Show resolved Hide resolved
drivers/include/apds99xx.h Outdated Show resolved Hide resolved
@obgm
Copy link
Contributor

obgm commented Dec 20, 2018

FWIW: I am currently running the provided tests with an APDS 9960. Both, the basic (polling) version as well as the int-controlled version seem to work as expected. (Did not check the color values, though.)

@gschorcht
Copy link
Contributor Author

@leandrolanzieri Thanks for reviewing.

@ArtaFakhari
Copy link

Hello Everyone
Does the APDS-9960 work reliably on RIOT-OS?

double ga = 0.49; /* glas or lens attenuation factor */
double b = 1.862;
double c = 0.746;
double d = 1.291;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you multiply them all by 1000, you wouldn't need to use double here, no?

@aabadie
Copy link
Contributor

aabadie commented Feb 3, 2020

Please rebase, I have the hardware to test this PR (apds9960) :)

@aabadie aabadie self-assigned this Mar 9, 2020
@aabadie
Copy link
Contributor

aabadie commented Mar 9, 2020

Also: please rebase :)

@aabadie
Copy link
Contributor

aabadie commented Mar 9, 2020

I could test this PR on the adafruit-clue board (after some rebase and fix of conflicts). This board embeds an apds9960 variant. Here is what I get:

  • tests/driver_apds99xx works like a charm
  • tests/driver_apds99xx_full doesn't seem to work: no interrupt is generated when I get my hand close to the proximity sensor. I configured the interrupt pin following the board schematic, so it should work. Any idea what could be the cause @gschorcht ?

@gschorcht
Copy link
Contributor Author

  • tests/driver_apds99xx_full doesn't seem to work: no interrupt is generated when I get my hand close to the proximity sensor. I configured the interrupt pin following the board schematic, so it should work. Any idea what could be the cause @gschorcht ?

@aabadie Do you see ALS measurements?

ambient = 639 [cnts]
red = 208 [cnts], green = 295 [cnts], blue = 263 [cnts]
+-------------------------------------+

If yes, interrupts are working since these measurements use the data ready interrupt. The proximity interrupt is triggered, when the proximity value exceeds 200 counts. This happens at a distance of about 2 cm. In that case, the output also shows the proximity value, for example:

proximity = 205 [cnts]
+-------------------------------------+
ambient = 322 [cnts]
red = 95 [cnts], green = 168 [cnts], blue = 135 [cnts]
+-------------------------------------+

@gschorcht
Copy link
Contributor Author

gschorcht commented Mar 10, 2020

@aabadie @smlng Thanks for reviewing. I have rebased the PR and hopefully addressed all your remarks.

@aabadie
Copy link
Contributor

aabadie commented Mar 10, 2020

I have rebased the PR and hopefully addressed all your remarks.

Thanks! I'll have a look and test again tomorrow.

@aabadie
Copy link
Contributor

aabadie commented Mar 11, 2020

Tested this PR again this morning on adafruit-clue and I can't have the interrupt based test application to work. If I comment out the mutex_lock, messages are displayed as expected: the proximity value is only displayed when I put my finger close to the sensor (which means the interrupt source bit is set).
So there's something wrong with the interrupt pin: I have no idea what could be the problem. I suspect something with the board: there are white leds that are on when waiting for the interrupt and they go down when an interrupt occurs.

I trust you that this test is working anyway.

drivers/Makefile.dep Outdated Show resolved Hide resolved
@gschorcht
Copy link
Contributor Author

Tested this PR again this morning on adafruit-clue and I can't have the interrupt based test application to work. If I comment out the mutex_lock, messages are displayed as expected: the proximity value is only displayed when I put my finger close to the sensor (which means the interrupt source bit is set).
So there's something wrong with the interrupt pin: I have no idea what could be the problem. I suspect something with the board: there are white leds that are on when waiting for the interrupt and they go down when an interrupt occurs.

The Adafruit-Clue seems to be a very interesting board. According to the schematic P0.09 should be the APDS_IRQ pin. GPIO_IN_PU mode is supported according to nrf5240 product specification. Might it be a problem that the pin could also be used as NFC1 pin, something that has to be considered during initialization? The WHITE_LED signal is controlled by P0.10/NFC2. Might it be that the pins are mixed up?

@aabadie
Copy link
Contributor

aabadie commented Mar 11, 2020

Might it be that the pins are mixed up?

I had the same idea and tried to invert the pins but it didn't work either. I won't block this PR because of this anyway.

@aabadie
Copy link
Contributor

aabadie commented Mar 11, 2020

I think we are good with this one. @gschorcht, please squash!

@aabadie aabadie added CI: run tests If set, CI server will run tests on hardware for the labeled PR CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Mar 11, 2020
Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK!

@aabadie aabadie merged commit 1e80376 into RIOT-OS:master Mar 11, 2020
@gschorcht
Copy link
Contributor Author

Thank you all for reviewing and testing.

BTW, I hope I can implement the gesture recognition function of APDS9960 in next week. I will provide it as separate PR.

@gschorcht gschorcht deleted the drivers_apds99xx branch March 11, 2020 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers Area: SAUL Area: Sensor/Actuator Uber Layer CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.