Refactor sensor interface with extra files and function pointer

That makes it easier to enable/disable sensors.

Also added support for APDS9930
This commit is contained in:
Florian Eitel 2019-08-04 11:56:18 +02:00
parent abcfcd276c
commit be334245ff
No known key found for this signature in database
GPG key ID: 9987EAFEF6F686BB
24 changed files with 2832 additions and 138 deletions

View file

@ -10,6 +10,11 @@
// Enable/Disable features
//#define WEBUPDATER_FEATURE
#define BATTERY_POWERED
#define SENSOR_WIND
#define SENSOR_APDS9960
//#define SENSOR_APDS9930
#define SENSOR_BME280
#define SENSOR_BATTERY
const float HUMIDITY_FACTOR = 1.0;
const float LIGHT_FACTOR = 1.0;
@ -27,4 +32,3 @@ const char *INFLUXDB_PASS = "password";
String DEVICE_NAME = "devicename";
#endif

View file

@ -18,8 +18,6 @@
#include <WiFiClient.h> // WiFiClient
#include <WiFiManager.h> // WiFiManager
#include <ESP8266Influxdb.h> // https://github.com/hwwong/ESP8266Influxdb auchecken und den ordner in das arduino\library verzeichnis kopieren
#include <Adafruit_APDS9960.h> // Adafruit APDS9960 - https://www.makerfabs.com/index.php?route=product/product&product_id=281
#include <Adafruit_BME280.h> // BME280 - https://www.roboter-bausatz.de/1704/bmp280-barometer-luftdrucksensor?gclid=EAIaIQobChMIlpumj8Hp2wIVFWYbCh01PgmFEAQYAyABEgIwBvD_BwE
// Project includes
#include "config.h"
@ -49,18 +47,15 @@
//*************************************************************************//
float currentSensorData[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
const uint8_t VALUES = 8;
float currentSensorData[VALUES] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
float (*sensors[VALUES])() = {};
uint16_t update_sensor_cnt = 0;
uint16_t update_webserver_cnt = 0;
uint16_t energySavingIterations = 0;
WiFiManager wifiManager;
Influxdb influxdb(INFLUXDB_HOST, INFLUXDB_PORT);
Adafruit_APDS9960 apds;
Adafruit_BME280 bme;
bool apds_connected = false;
#ifdef WEBUPDATER_FEATURE
String localIP = "127.0.0.1";
@ -117,21 +112,36 @@ void setup() {
influxdb.opendb(INFLUXDB_DB, INFLUXDB_USER, INFLUXDB_PASS);
// Initialize and configure the sensors
//Light Sensor
if (apds.begin()) {
apds_connected = true;
apds.enableColor(true);
#ifdef SENSOR_APDS9930
if (sensor_apds9930_begin()) {
sensors[SENSOR_LIGHT] = &apds9930_light;
}
#endif
debug("APDS Connected!");
#ifdef SENSOR_APDS9960
if (sensor_apds9960_begin()) {
sensors[SENSOR_LIGHT] = &apds9930_light;
}
#endif
#ifdef SENSOR_BME280
//Temperature + pressure
bool status = bme.begin(BME_ADDRESS);
if (!status) {
debug("Could not find a valid BME280 sensor, check wiring!");
//#warning TODO: FIXME while (1);
if (sensor_bme280_begin(BME_ADDRESS)) {
sensors[SENSOR_TEMPERATURE] = &bme280_temperature;
sensors[SENSOR_HUMIDITY] = &bme280_humidity;
sensors[SENSOR_PRESSURE] = &bme280_pressure;
}
debug("BME Connected!");
#endif
#ifdef SENSOR_WIND
sensors[SENSOR_WINDSPEED] = &wind_speed;
#endif
#ifdef SENSOR_BATTERY
sensors[SENSOR_BAT_VOLTAGE] = &battery_voltage;
sensors[SENSOR_BATCHARGESTATE] = &battery_charging;
sensors[SENSOR_ESAVEMODE] = &isEnergySavingMode;
#endif
#ifdef WEBUPDATER_FEATURE
#ifndef BATTERY_POWERED
@ -166,7 +176,7 @@ void setup() {
#ifdef BATTERY_POWERED
void criticalBatCheck() {
float volt = getBatteryVoltage();
float volt = battery_voltage();
if (volt <= BAT_EMERGENCY_DEEPSLEEP_VOLTAGE) {
debug("Bat Voltage: " + String(volt) + " V");
debug("Low battery, going into deep sleep.");
@ -177,26 +187,6 @@ void criticalBatCheck() {
}
#endif
#ifdef BATTERY_POWERED
int energySavingMode() {
// Give the solar panel some time to load the cell to prevent
// flapping.
if (energySavingIterations > 0) {
energySavingIterations--;
return 1;
}
// Is the battery low?
if (currentSensorData[SENSOR_BAT_VOLTAGE] <= BAT_LOW_VOLTAGE) {
// Entering energy saving
energySavingIterations = ENERGY_SAVING_ITERATIONS;
return 1;
}
return 0;
}
#endif
void loop() {
#ifdef BATTERY_POWERED
@ -232,32 +222,25 @@ void _loop() {
}
#endif
update_sensor_cnt = 0;
currentSensorData[SENSOR_TEMPERATURE] = fetchTemperature();
currentSensorData[SENSOR_HUMIDITY] = fetchHumidity();
if (apds_connected) {
currentSensorData[SENSOR_LIGHT] = fetchLight();
}
currentSensorData[SENSOR_PRESSURE] = fetchPressure();
#ifdef BATTERY_POWERED
currentSensorData[SENSOR_BAT_VOLTAGE] = getBatteryVoltage();
currentSensorData[SENSOR_BATCHARGESTATE] = isBatCharging();
#else
currentSensorData[SENSOR_BAT_VOLTAGE] = 0xFFFFFFFF;
currentSensorData[SENSOR_BATCHARGESTATE] = 0xFFFFFFFF;
#endif
#ifdef BATTERY_POWERED
#ifdef defined(BATTERY_POWERED) && defined(SENSOR_WIND)
if (energySavingMode() == 1) {
// Disable expensive tasks
if (energySavingMode() == 0) {
sensors[SENSOR_WINDSPEED] = 0;
} else {
sensors[SENSOR_WINDSPEED] = &wind_speed;
}
#endif
currentSensorData[SENSOR_WINDSPEED] = fetchWindspeed();
currentSensorData[SENSOR_ESAVEMODE] = ENERGY_SAVE_MODE_DISABLED;
#ifdef BATTERY_POWERED
update_sensor_cnt = 0;
for (uint8_t i = 0; i < VALUES; i++) {
if (sensors[i]) {
currentSensorData[i] = sensors[i]();
} else {
currentSensorData[SENSOR_WINDSPEED] = 0xFFFFFFFF;
currentSensorData[SENSOR_ESAVEMODE] = ENERGY_SAVE_MODE_ENABLED;
currentSensorData[i] = 0xFFFFFFFF;
}
#endif
}
debug("");
debug("Current readings:");

View file

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View file

@ -0,0 +1,192 @@
#################
## SparkFun Useful stuff
#################
## AVR Development
*.eep
*.elf
*.lst
*.lss
*.sym
*.d
*.o
*.srec
*.map
## Notepad++ backup files
*.bak
## BOM files
*bom*
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#############
## Eagle
#############
# Ignore the board and schematic backup files
*.b#?
*.s#?
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Davide Depau
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,92 @@
APDS9930 Ambient Light and Proximity sensor
===========================================
This is a fork of the [library from Sparkfun for the APDS-9960 sensor](https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor). It has been adapted to read values from this other model.
[**Quick-start guide available here**](https://web.archive.org/web/20151224052223/http://davideddu.org/blog/posts/apds-9930-arduino-quickstart/)
[**Purchase an Avago APDS-9930 Breakout Board here**](http://www.dx.com/p/384037?Utm_rid=14976370&Utm_source=affiliate)
# DO NOT EMAIL ME IF YOU HAVE AN ISSUE
It will be deleted without reading. If you have an issue, [create an issue](https://github.com/Depau/APDS9930/issues) here on GitHub.
# Unmaintained
I'm not going to maintain this library any more. I will merge pull requests, though. Contributions are welcome. Just don't expect anything from me.
![Avago APDS-9930 Breakout Board](http://img.dxcdn.com/productimages/sku_384037_1.jpg)
**Note:** even though it says APDS-9960, it's an APDS-9930. That's how I ended up getting one of those. I wanted the RGB sensor. I found this crap in my mailbox. But I decided to write a library for it anyways ;)
Getting Started
---------------
* Download the Git repository as a ZIP ("Download ZIP" button)
* Unzip
* Copy the entire library directory (APDS-9930) to
\<Arduino installation directory\>/libraries
* Open the Arduino program
* Select File -> Examples -> APDS9930 -> GestureTest
* Plug in your Arduino and APDS-9930 with the following connections
*-OR-*
* Use the library manager
| Arduino Pin | APDS-9930 Board | Function |
|---|---|---|
| 3.3V | VCC | Power |
| GND | GND | Ground |
| A4 | SDA | I²C Data |
| A5 | SCL | I²C Clock |
| 2 | INT | Interrupt |
*P.S.: you already know you can't use this purple little thing with your 5V Arduino without a level shifter, right? :) In case you don't have a level shifter, you can detach the microcontroller from an Arduino Uno, reconnect the oscillator pins, the RX and TX pins, the reset and the LED/SCK pins back to the board with some jumper wires. You can then power the microcontroller from a 3.3V source (the 3V3 output on the board should work) and connect the sensor directly to the MCU. Look up "Arduino on Breadboard".*
* 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.
* **/extras** - Additional documentation for the user. These files are ignored by the IDE.
* **/src** - Source files for the library (.cpp, .h).
* **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE.
* **library.properties** - General library properties for the Arduino package manager.
Documentation
--------------
* **[Quickstart Guide](https://web.archive.org/web/20151224052223/http://davideddu.org/blog/posts/apds-9930-arduino-quickstart/)** - Basic hookup guide for the sensor.
* **[Product Repository](https://github.com/Davideddu/APDS9930)** - Main repository (including hardware files) for the APDS9930 ambient light and proximity sensor.
* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
Version History
---------------
* master - Adapted for use with APDS-9930
* [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
License Information
-------------------
This product is _**open source**_!
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. And Davide Depau :*

View file

@ -0,0 +1,180 @@
/****************************************************************
AmbientLightInterrupt.ino
APDS-9930 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
October 24, 2014
https://github.com/sparkfun/APDS-9930_RGB_and_Gesture_Sensor
Tests the ambient light interrupt abilities of the APDS-9930.
Configures the APDS-9930 over I2C and waits for an external
interrupt based on high or low light conditions. Try covering
the sensor with your hand or bringing the sensor close to a
bright light source. You might need to adjust the LIGHT_INT_HIGH
and LIGHT_INT_LOW values to get the interrupt to work correctly.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
13 - LED
Resources:
Include Wire.h and APDS9930.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.
****************************************************************/
#define DUMP_REGS
#include <Wire.h>
#include <APDS9930.h>
// Pins
#define APDS9930_INT 2 // Needs to be an interrupt pin
#define LED_PIN 13 // LED for showing interrupt
// Constants
#define LIGHT_INT_HIGH 1000 // High light level for interrupt
#define LIGHT_INT_LOW 10 // Low light level for interrupt
// Global variables
APDS9930 apds = APDS9930();
float ambient_light = 0;
uint16_t ch0 = 0;
uint16_t ch1 = 1;
volatile bool isr_flag = false;
uint16_t threshold = 0;
void setup() {
// Set LED as output
pinMode(LED_PIN, OUTPUT);
pinMode(APDS9930_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("----------------------------"));
Serial.println(F("APDS-9930 - Light Interrupts"));
Serial.println(F("----------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// Set high and low interrupt thresholds
if ( !apds.setLightIntLowThreshold(LIGHT_INT_LOW) ) {
Serial.println(F("Error writing low threshold"));
}
if ( !apds.setLightIntHighThreshold(LIGHT_INT_HIGH) ) {
Serial.println(F("Error writing high threshold"));
}
// Start running the APDS-9930 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
// Read high and low interrupt thresholds
if ( !apds.getLightIntLowThreshold(threshold) ) {
Serial.println(F("Error reading low threshold"));
} else {
Serial.print(F("Low Threshold: "));
Serial.println(threshold);
}
if ( !apds.getLightIntHighThreshold(threshold) ) {
Serial.println(F("Error reading high threshold"));
} else {
Serial.print(F("High Threshold: "));
Serial.println(threshold);
}
// Enable interrupts
if ( !apds.setAmbientLightIntEnable(1) ) {
Serial.println(F("Error enabling interrupts"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
// Wait for initialization and calibration to finish
delay(500);
}
void loop() {
// If interrupt occurs, print out the light levels
if ( isr_flag ) {
// Read the light levels (ambient, red, green, blue) and print
if ( !apds.readAmbientLightLux(ambient_light) ||
!apds.readCh0Light(ch0) ||
!apds.readCh1Light(ch1) ) {
Serial.println("Error reading light values");
} else {
Serial.print("Interrupt! Ambient: ");
Serial.print(ambient_light);
Serial.print(F(" Ch0: "));
Serial.print(ch0);
Serial.print(F(" Ch1: "));
Serial.println(ch1);
}
// Turn on LED for a half a second
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
// Reset flag and clear APDS-9930 interrupt (IMPORTANT!)
isr_flag = false;
if ( !apds.clearAmbientLightInt() ) {
Serial.println("Error clearing interrupt");
}
}
}
void interruptRoutine() {
isr_flag = true;
}

View file

@ -0,0 +1,113 @@
/****************************************************************
AmbientLightLED.ino
Tests the ambient light sensing abilities of the
APDS-9930. Configures APDS-9930 over I2C and polls the sensor for
ambient light levels, which are displayed over the
serial console.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
10 (pwm) LED anode
Distributed as-is; no warranty is given.
****************************************************************/
#define PWM_LED_PIN 10
#define DUMP_REGS
#include <Wire.h>
#include <APDS9930.h>
// Global Variables
APDS9930 apds = APDS9930();
float ambient_light = 0; // can also be an unsigned long
uint16_t ch0 = 0;
uint16_t ch1 = 1;
float max_light = 0;
void setup() {
//analogReference(EXTERNAL);
pinMode(PWM_LED_PIN, OUTPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("APDS-9930 - Ambient light sensor"));
Serial.println(F("--------------------------------"));
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// Start running the APDS-9930 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
// Wait for initialization and calibration to finish
delay(500);
}
void loop() {
// Read the light levels (ambient, red, green, blue)
if ( !apds.readAmbientLightLux(ambient_light) ||
!apds.readCh0Light(ch0) ||
!apds.readCh1Light(ch1) ) {
Serial.println(F("Error reading light values"));
} else {
Serial.print(F("Ambient: "));
Serial.print(ambient_light);
Serial.print(F(" Ch0: "));
Serial.print(ch0);
Serial.print(F(" Ch1: "));
Serial.println(ch1);
if ( ambient_light > max_light ) {
max_light = ambient_light;
}
ambient_light = map(ambient_light, 0, max_light, 0, 1023);
analogWrite(PWM_LED_PIN, ambient_light);
}
// Wait 1 second before next reading
delay(50);
}

View file

@ -0,0 +1,120 @@
/****************************************************************
AmbientLightSensor.ino
APDS-9930 Ambient light and proximity sensor
Davide Depau
December 11, 2015
https://github.com/Davideddu/APDS9930
Shawn Hymel @ SparkFun Electronics
October 15, 2014
https://github.com/sparkfun/APDS-9930_RGB_and_Gesture_Sensor
Tests thembient light sensing abilities of the
APDS-9930. Configures APDS-9930 over I2C and polls the sensor for
ambient light levels, which are displayed over the
serial console.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
Resources:
Include Wire.h and APDS-9930.h
Development environment specifics:
Written in Arduino 1.6.5
Tested with Arduino Uno and Mega.
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.
****************************************************************/
#define DUMP_REGS
#include <Wire.h>
#include <APDS9930.h>
// Global Variables
APDS9930 apds = APDS9930();
float ambient_light = 0; // can also be an unsigned long
uint16_t ch0 = 0;
uint16_t ch1 = 1;
void setup() {
//analogReference(EXTERNAL);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("APDS-9930 - Ambient light sensor"));
Serial.println(F("--------------------------------"));
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// Start running the APDS-9930 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
// Wait for initialization and calibration to finish
delay(500);
}
void loop() {
// Read the light levels (ambient, red, green, blue)
if ( !apds.readAmbientLightLux(ambient_light) ||
!apds.readCh0Light(ch0) ||
!apds.readCh1Light(ch1) ) {
Serial.println(F("Error reading light values"));
} else {
Serial.print(F("Ambient: "));
Serial.print(ambient_light);
Serial.print(F(" Ch0: "));
Serial.print(ch0);
Serial.print(F(" Ch1: "));
Serial.println(ch1);
}
// Wait 1 second before next reading
delay(1000);
}

View file

@ -0,0 +1,108 @@
/****************************************************************
AmbientLightToneAC.ino
Tests the ambient light sensing abilities of the
APDS-9930. Configures APDS-9930 over I2C and polls the sensor for
ambient light levels, which are displayed over the
serial console.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
Connect speakers to the correct pins. Check toneAC.h for more info.
Distributed as-is; no warranty is given.
****************************************************************/
#define DUMP_REGS
#include <Wire.h>
#include <APDS9930.h>
#include <toneAC.h>
// Global Variables
APDS9930 apds = APDS9930();
float ambient_light = 0; // can also be an unsigned long
uint16_t ch0 = 0;
uint16_t ch1 = 1;
float max_light = 0;
void setup() {
//analogReference(EXTERNAL);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("APDS-9930 - Ambient light sensor"));
Serial.println(F("--------------------------------"));
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// Start running the APDS-9930 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
// Wait for initialization and calibration to finish
delay(500);
}
void loop() {
// Read the light levels (ambient, red, green, blue)
if ( !apds.readAmbientLightLux(ambient_light) ||
!apds.readCh0Light(ch0) ||
!apds.readCh1Light(ch1) ) {
Serial.println(F("Error reading light values"));
} else {
Serial.print(F("Ambient: "));
Serial.print(ambient_light);
Serial.print(F(" Ch0: "));
Serial.print(ch0);
Serial.print(F(" Ch1: "));
Serial.println(ch1);
unsigned long freq = map(ch0, 0, 1024, 60, 16000);
toneAC(freq, 10, 50, true);
}
// Wait 1 second before next reading
delay(50);
}

View file

@ -0,0 +1,157 @@
/****************************************************************
ProximityInterrupt.ino
APDS-9930 Ambient light and proximity sensor
Davide Depau
December 11, 2015
https://github.com/Davideddu/APDS9930
Shawn Hymel @ SparkFun Electronics
October 24, 2014
https://github.com/sparkfun/APDS-9930_RGB_and_Gesture_Sensor
Tests the proximity interrupt abilities of the APDS-9930.
Configures the APDS-9930 over I2C and waits for an external
interrupt based on high or low proximity conditions. Move your
hand near the sensor and watch the LED on pin 13.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
13 - LED
Resources:
Include Wire.h and APDS9930.h
Development environment specifics:
Written in Arduino 1.6.5
Tested with Arduino Uno and Mega
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.
****************************************************************/
#define DUMP_REGS
#include <Wire.h>
#include <APDS9930.h>
// Pins
#define APDS9930_INT 2 // Needs to be an interrupt pin
#define LED_PIN 13 // LED for showing interrupt
// Constants
#define PROX_INT_HIGH 600 // Proximity level for interrupt
#define PROX_INT_LOW 0 // No far interrupt
// Global variables
APDS9930 apds = APDS9930();
uint16_t proximity_data = 0;
volatile bool isr_flag = false;
void setup() {
// Set LED as output
pinMode(LED_PIN, OUTPUT);
pinMode(APDS9930_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("------------------------------"));
Serial.println(F("APDS-9930 - ProximityInterrupt"));
Serial.println(F("------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// Adjust the Proximity sensor gain
if ( !apds.setProximityGain(PGAIN_2X) ) {
Serial.println(F("Something went wrong trying to set PGAIN"));
}
// Set proximity interrupt thresholds
if ( !apds.setProximityIntLowThreshold(PROX_INT_LOW) ) {
Serial.println(F("Error writing low threshold"));
}
if ( !apds.setProximityIntHighThreshold(PROX_INT_HIGH) ) {
Serial.println(F("Error writing high threshold"));
}
// Start running the APDS-9930 proximity sensor (interrupts)
if ( apds.enableProximitySensor(true) ) {
Serial.println(F("Proximity sensor is now running"));
} else {
Serial.println(F("Something went wrong during sensor init!"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
}
void loop() {
// If interrupt occurs, print out the proximity level
if ( isr_flag ) {
// Read proximity level and print it out
if ( !apds.readProximity(proximity_data) ) {
Serial.println("Error reading proximity value");
} else {
Serial.print("Proximity detected! Level: ");
Serial.println(proximity_data);
}
// Turn on LED for a half a second
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
// Reset flag and clear APDS-9930 interrupt (IMPORTANT!)
isr_flag = false;
if ( !apds.clearProximityInt() ) {
Serial.println("Error clearing interrupt");
}
}
}
void interruptRoutine() {
isr_flag = true;
}

View file

@ -0,0 +1,131 @@
/****************************************************************
ProximityLED.ino
Davide Depau
December 11, 2015
https://github.com/Davideddu/APDS9930
https://github.com/sparkfun/APDS-9930_RGB_and_Gesture_Sensor
Tests the proximity sensing abilities of the APDS-9930.
Configures the APDS-9930 over I2C and polls for the distance to
the object nearest the sensor, then turns on an LED accordingly.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
10 (PWM) LED Anode
Resources:
Include Wire.h and APDS9930.h
Development environment specifics:
Written in Sublime Text + Stino + Arduino 1.7.2
Tested with Arduino Uno + level shifter
This code is chocolateware; if you see me at the grocery store,
and you've found our code helpful, please buy us me a chocolate bar! :D
Distributed as-is; no warranty is given.
****************************************************************/
#define DUMP_REGS
#define PWM_LED_PIN 10
#include <Wire.h>
#include <APDS9930.h>
// Global Variables
APDS9930 apds = APDS9930();
uint16_t proximity_data = 0;
int proximity_max = 0;
void setup() {
//analogReference(EXTERNAL);
pinMode(PWM_LED_PIN, OUTPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("------------------------"));
Serial.println(F("APDS-9930 - ProximityLED"));
Serial.println(F("------------------------"));
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// Adjust the Proximity sensor gain
if ( !apds.setProximityGain(PGAIN_1X) ) {
Serial.println(F("Something went wrong trying to set PGAIN"));
}
// Start running the APDS-9930 proximity sensor (no interrupts)
if ( apds.enableProximitySensor(false) ) {
Serial.println(F("Proximity sensor is now running"));
} else {
Serial.println(F("Something went wrong during sensor init!"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
}
void loop() {
// Read the proximity value
if ( !apds.readProximity(proximity_data) ) {
Serial.println("Error reading proximity value");
} else {
Serial.print("Proximity: ");
Serial.print(proximity_data);
// This is an ugly hack to reduce sensor noise.
// You may want to adjust POFFSET instead.
/*
proximity_data -= 200;
if (proximity_data > 50000) {
proximity_data = 0;
}
if (proximity_data > proximity_max) {
proximity_max = proximity_data;
}
proximity_data = map(proximity_data, 0, proximity_max, 0, 1023);
*/
Serial.print(F(" Remapped: "));
Serial.println(proximity_data);
analogWrite(PWM_LED_PIN, proximity_data);
}
// Wait 250 ms before next reading
delay(10);
}

View file

@ -0,0 +1,113 @@
/****************************************************************
ProximitySensor.ino
APDS-9930 ambient light and proximity sensor
Davide Depau
December 11, 2015
https://github.com/Davideddu/APDS9930
Shawn Hymel @ SparkFun Electronics
October 28, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the proximity sensing abilities of the APDS-9930.
Configures the APDS-9930 over I2C and polls for the distance to
the object nearest the sensor.
Hardware Connections:
IMPORTANT: The APDS-9930 can only accept 3.3V!
Arduino Pin APDS-9930 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
Resources:
Include Wire.h and SparkFun_APDS-9930.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.
****************************************************************/
#define DUMP_REGS
#include <Wire.h>
#include <APDS9930.h>
// Global Variables
APDS9930 apds = APDS9930();
uint16_t proximity_data = 0;
void setup() {
//analogReference(EXTERNAL);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("---------------------------"));
Serial.println(F("APDS-9930 - ProximitySensor"));
Serial.println(F("---------------------------"));
// Initialize APDS-9930 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9930 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// // Adjust the Proximity sensor gain
// if ( !apds.setProximityGain(PGAIN_2X) ) {
// Serial.println(F("Something went wrong trying to set PGAIN"));
// }
// Start running the APDS-9930 proximity sensor (no interrupts)
if ( apds.enableProximitySensor(false) ) {
Serial.println(F("Proximity sensor is now running"));
} else {
Serial.println(F("Something went wrong during sensor init!"));
}
#ifdef DUMP_REGS
/* Register dump */
uint8_t reg;
uint8_t val;
for(reg = 0x00; reg <= 0x19; reg++) {
if( (reg != 0x10) && \
(reg != 0x11) )
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
}
void loop() {
// Read the proximity value
if ( !apds.readProximity(proximity_data) ) {
Serial.println("Error reading proximity value");
} else {
Serial.print("Proximity: ");
Serial.println(proximity_data);
}
// Wait 250 ms before next reading
delay(250);
}

View file

@ -0,0 +1,9 @@
name=APDS-9930 Ambient Light and Proximity Sensor
version=1.5.1
author=Davide Depau
maintainer=Davide Depau
sentence=Library for the Avago APDS-9930 sensor
paragraph=This library works with the breakout board for the Avago APDS-9930 proximity and light sensor
category=Sensors
url=https://github.com/Davideddu/APDS9930
architectures=*

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,231 @@
/**
* @file APDS-9930.h
* @brief Library for the SparkFun APDS-9930 breakout board
* @author Shawn Hymel (SparkFun Electronics)
*
* @copyright This code is public domain but you buy me a beer if you use
* this and we meet someday (Beerware license).
*
* This library interfaces the Avago APDS-9930 to Arduino over I2C. The library
* relies on the Arduino Wire (I2C) library. to use the library, instantiate an
* APDS9930 object, call init(), and call the appropriate functions.
*/
#ifndef APDS9930_H
#define APDS9930_H
#include <Arduino.h>
/* Debug */
#define DEBUG 0
/* APDS-9930 I2C address */
#define APDS9930_I2C_ADDR 0x39
/* Command register modes */
#define REPEATED_BYTE 0x80
#define AUTO_INCREMENT 0xA0
#define SPECIAL_FN 0xE0
/* Error code for returned values */
#define ERROR 0xFF
/* Acceptable device IDs */
#define APDS9930_ID_1 0x12
#define APDS9930_ID_2 0x39
/* Misc parameters */
#define FIFO_PAUSE_TIME 30 // Wait period (ms) between FIFO reads
/* APDS-9930 register addresses */
#define APDS9930_ENABLE 0x00
#define APDS9930_ATIME 0x01
#define APDS9930_PTIME 0x02
#define APDS9930_WTIME 0x03
#define APDS9930_AILTL 0x04
#define APDS9930_AILTH 0x05
#define APDS9930_AIHTL 0x06
#define APDS9930_AIHTH 0x07
#define APDS9930_PILTL 0x08
#define APDS9930_PILTH 0x09
#define APDS9930_PIHTL 0x0A
#define APDS9930_PIHTH 0x0B
#define APDS9930_PERS 0x0C
#define APDS9930_CONFIG 0x0D