mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
added support for the TSL2591 Sensor based on Adafruit Library (#661)
* initial support for TSL2591 sensor * return lux, visible, ir and full light separately * better plugin init * check sensor initialization before reading it.. * incorporated a few pending fixes for the adafruit library * minor typo
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software< /span>
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and
|
||||
* extended sensor support to include color, voltage and current */
|
||||
|
||||
#ifndef _ADAFRUIT_SENSOR_H
|
||||
#define _ADAFRUIT_SENSOR_H
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#include "Print.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
/* Intentionally modeled after sensors.h in the Android API:
|
||||
* https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */
|
||||
|
||||
/* Constants */
|
||||
#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
|
||||
#define SENSORS_GRAVITY_MOON (1.6F) /**< The moon's gravity in m/s^2 */
|
||||
#define SENSORS_GRAVITY_SUN (275.0F) /**< The sun's gravity in m/s^2 */
|
||||
#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
|
||||
#define SENSORS_MAGFIELD_EARTH_MAX (60.0F) /**< Maximum magnetic field on Earth's surface */
|
||||
#define SENSORS_MAGFIELD_EARTH_MIN (30.0F) /**< Minimum magnetic field on Earth's surface */
|
||||
#define SENSORS_PRESSURE_SEALEVELHPA (1013.25F) /**< Average sea level pressure is 1013.25 hPa */
|
||||
#define SENSORS_DPS_TO_RADS (0.017453293F) /**< Degrees/s to rad/s multiplier */
|
||||
#define SENSORS_GAUSS_TO_MICROTESLA (100) /**< Gauss to micro-Tesla multiplier */
|
||||
|
||||
/** Sensor types */
|
||||
typedef enum
|
||||
{
|
||||
SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
|
||||
SENSOR_TYPE_MAGNETIC_FIELD = (2),
|
||||
SENSOR_TYPE_ORIENTATION = (3),
|
||||
SENSOR_TYPE_GYROSCOPE = (4),
|
||||
SENSOR_TYPE_LIGHT = (5),
|
||||
SENSOR_TYPE_PRESSURE = (6),
|
||||
SENSOR_TYPE_PROXIMITY = (8),
|
||||
SENSOR_TYPE_GRAVITY = (9),
|
||||
SENSOR_TYPE_LINEAR_ACCELERATION = (10), /**< Acceleration not including gravity */
|
||||
SENSOR_TYPE_ROTATION_VECTOR = (11),
|
||||
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
|
||||
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
|
||||
SENSOR_TYPE_VOLTAGE = (15),
|
||||
SENSOR_TYPE_CURRENT = (16),
|
||||
SENSOR_TYPE_COLOR = (17)
|
||||
} sensors_type_t;
|
||||
|
||||
/** struct sensors_vec_s is used to return a vector in a common format. */
|
||||
typedef struct {
|
||||
union {
|
||||
float v[3];
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
/* Orientation sensors */
|
||||
struct {
|
||||
float roll; /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -90°<=roll<=90° */
|
||||
float pitch; /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180°<=pitch<=180°) */
|
||||
float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359° */
|
||||
};
|
||||
};
|
||||
int8_t status;
|
||||
uint8_t reserved[3];
|
||||
} sensors_vec_t;
|
||||
|
||||
/** struct sensors_color_s is used to return color data in a common format. */
|
||||
typedef struct {
|
||||
union {
|
||||
float c[3];
|
||||
/* RGB color space */
|
||||
struct {
|
||||
float r; /**< Red component */
|
||||
float g; /**< Green component */
|
||||
float b; /**< Blue component */
|
||||
};
|
||||
};
|
||||
uint32_t rgba; /**< 24-bit RGBA value */
|
||||
} sensors_color_t;
|
||||
|
||||
/* Sensor event (36 bytes) */
|
||||
/** struct sensor_event_s is used to provide a single sensor event in a common format. */
|
||||
typedef struct
|
||||
{
|
||||
int32_t version; /**< must be sizeof(struct sensors_event_t) */
|
||||
int32_t sensor_id; /**< unique sensor identifier */
|
||||
int32_t type; /**< sensor type */
|
||||
int32_t reserved0; /**< reserved */
|
||||
int32_t timestamp; /**< time is in milliseconds */
|
||||
union
|
||||
{
|
||||
float data[4];
|
||||
sensors_vec_t acceleration; /**< acceleration values are in meter per second per second (m/s^2) */
|
||||
sensors_vec_t magnetic; /**< magnetic vector values are in micro-Tesla (uT) */
|
||||
sensors_vec_t orientation; /**< orientation values are in degrees */
|
||||
sensors_vec_t gyro; /**< gyroscope values are in rad/s */
|
||||
float temperature; /**< temperature is in degrees centigrade (Celsius) */
|
||||
float distance; /**< distance in centimeters */
|
||||
float light; /**< light in SI lux units */
|
||||
float pressure; /**< pressure in hectopascal (hPa) */
|
||||
float relative_humidity; /**< relative humidity in percent */
|
||||
float current; /**< current in milliamps (mA) */
|
||||
float voltage; /**< voltage in volts (V) */
|
||||
sensors_color_t color; /**< color in RGB component values */
|
||||
};
|
||||
} sensors_event_t;
|
||||
|
||||
/* Sensor details (40 bytes) */
|
||||
/** struct sensor_s is used to describe basic information about a specific sensor. */
|
||||
typedef struct
|
||||
{
|
||||
char name[12]; /**< sensor name */
|
||||
int32_t version; /**< version of the hardware + driver */
|
||||
int32_t sensor_id; /**< unique sensor identifier */
|
||||
int32_t type; /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
|
||||
float max_value; /**< maximum value of this sensor's value in SI units */
|
||||
float min_value; /**< minimum value of this sensor's value in SI units */
|
||||
float resolution; /**< smallest difference between two values reported by this sensor */
|
||||
int32_t min_delay; /**< min delay in microseconds between events. zero = not a constant rate */
|
||||
} sensor_t;
|
||||
|
||||
class Adafruit_Sensor {
|
||||
public:
|
||||
// Constructor(s)
|
||||
Adafruit_Sensor() {}
|
||||
virtual ~Adafruit_Sensor() {}
|
||||
|
||||
// These must be defined by the subclass
|
||||
virtual void enableAutoRange(bool enabled) {};
|
||||
virtual bool getEvent(sensors_event_t*) = 0;
|
||||
virtual void getSensor(sensor_t*) = 0;
|
||||
|
||||
private:
|
||||
bool _autoRange;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,221 @@
|
||||
# Adafruit Unified Sensor Driver #
|
||||
|
||||
Many small embedded systems exist to collect data from sensors, analyse the data, and either take an appropriate action or send that sensor data to another system for processing.
|
||||
|
||||
One of the many challenges of embedded systems design is the fact that parts you used today may be out of production tomorrow, or system requirements may change and you may need to choose a different sensor down the road.
|
||||
|
||||
Creating new drivers is a relatively easy task, but integrating them into existing systems is both error prone and time consuming since sensors rarely use the exact same units of measurement.
|
||||
|
||||
By reducing all data to a single **sensors\_event\_t** 'type' and settling on specific, **standardised SI units** for each sensor family the same sensor types return values that are comparable with any other similar sensor. This enables you to switch sensor models with very little impact on the rest of the system, which can help mitigate some of the risks and problems of sensor availability and code reuse.
|
||||
|
||||
The unified sensor abstraction layer is also useful for data-logging and data-transmission since you only have one well-known type to log or transmit over the air or wire.
|
||||
|
||||
## Unified Sensor Drivers ##
|
||||
|
||||
The following drivers are based on the Adafruit Unified Sensor Driver:
|
||||
|
||||
**Accelerometers**
|
||||
- [Adafruit\_ADXL345](https://github.com/adafruit/Adafruit_ADXL345)
|
||||
- [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
|
||||
- [Adafruit\_MMA8451\_Library](https://github.com/adafruit/Adafruit_MMA8451_Library)
|
||||
|
||||
**Gyroscope**
|
||||
- [Adafruit\_L3GD20\_U](https://github.com/adafruit/Adafruit_L3GD20_U)
|
||||
|
||||
**Light**
|
||||
- [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561)
|
||||
- [Adafruit\_TSL2591\_Library](https://github.com/adafruit/Adafruit_TSL2591_Library)
|
||||
|
||||
**Magnetometers**
|
||||
- [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
|
||||
- [Adafruit\_HMC5883\_Unified](https://github.com/adafruit/Adafruit_HMC5883_Unified)
|
||||
|
||||
**Barometric Pressure**
|
||||
- [Adafruit\_BMP085\_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified)
|
||||
- [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library)
|
||||
|
||||
**Humidity & Temperature**
|
||||
- [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library)
|
||||
|
||||
**Orientation**
|
||||
- [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055)
|
||||
|
||||
## How Does it Work? ##
|
||||
|
||||
Any driver that supports the Adafruit unified sensor abstraction layer will implement the Adafruit\_Sensor base class. There are two main typedefs and one enum defined in Adafruit_Sensor.h that are used to 'abstract' away the sensor details and values:
|
||||
|
||||
**Sensor Types (sensors\_type\_t)**
|
||||
|
||||
These pre-defined sensor types are used to properly handle the two related typedefs below, and allows us determine what types of units the sensor uses, etc.
|
||||
|
||||
```
|
||||
/** Sensor types */
|
||||
typedef enum
|
||||
{
|
||||
SENSOR_TYPE_ACCELEROMETER = (1),
|
||||
SENSOR_TYPE_MAGNETIC_FIELD = (2),
|
||||
SENSOR_TYPE_ORIENTATION = (3),
|
||||
SENSOR_TYPE_GYROSCOPE = (4),
|
||||
SENSOR_TYPE_LIGHT = (5),
|
||||
SENSOR_TYPE_PRESSURE = (6),
|
||||
SENSOR_TYPE_PROXIMITY = (8),
|
||||
SENSOR_TYPE_GRAVITY = (9),
|
||||
SENSOR_TYPE_LINEAR_ACCELERATION = (10),
|
||||
SENSOR_TYPE_ROTATION_VECTOR = (11),
|
||||
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
|
||||
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
|
||||
SENSOR_TYPE_VOLTAGE = (15),
|
||||
SENSOR_TYPE_CURRENT = (16),
|
||||
SENSOR_TYPE_COLOR = (17)
|
||||
} sensors_type_t;
|
||||
```
|
||||
|
||||
**Sensor Details (sensor\_t)**
|
||||
|
||||
This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer.
|
||||
|
||||
```
|
||||
/* Sensor details (40 bytes) */
|
||||
/** struct sensor_s is used to describe basic information about a specific sensor. */
|
||||
typedef struct
|
||||
{
|
||||
char name[12];
|
||||
int32_t version;
|
||||
int32_t sensor_id;
|
||||
int32_t type;
|
||||
float max_value;
|
||||
float min_value;
|
||||
float resolution;
|
||||
int32_t min_delay;
|
||||
} sensor_t;
|
||||
```
|
||||
|
||||
The individual fields are intended to be used as follows:
|
||||
|
||||
- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2")
|
||||
- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver
|
||||
- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network
|
||||
- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h
|
||||
- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit)
|
||||
- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit)
|
||||
- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit)
|
||||
- **min\_delay**: The minimum delay in microseconds between two sensor events, or '0' if there is no constant sensor rate
|
||||
|
||||
**Sensor Data/Events (sensors\_event\_t)**
|
||||
|
||||
This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales.
|
||||
|
||||
```
|
||||
/* Sensor event (36 bytes) */
|
||||
/** struct sensor_event_s is used to provide a single sensor event in a common format. */
|
||||
typedef struct
|
||||
{
|
||||
int32_t version;
|
||||
int32_t sensor_id;
|
||||
int32_t type;
|
||||
int32_t reserved0;
|
||||
int32_t timestamp;
|
||||
union
|
||||
{
|
||||
float data[4];
|
||||
sensors_vec_t acceleration;
|
||||
sensors_vec_t magnetic;
|
||||
sensors_vec_t orientation;
|
||||
sensors_vec_t gyro;
|
||||
float temperature;
|
||||
float distance;
|
||||
float light;
|
||||
float pressure;
|
||||
float relative_humidity;
|
||||
float current;
|
||||
float voltage;
|
||||
sensors_color_t color;
|
||||
};
|
||||
} sensors_event_t;
|
||||
```
|
||||
It includes the following fields:
|
||||
|
||||
- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future
|
||||
- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network (must match the sensor\_id value in the corresponding sensor\_t enum above!)
|
||||
- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h
|
||||
- **timestamp**: time in milliseconds when the sensor value was read
|
||||
- **data[4]**: An array of four 32-bit values that allows us to encapsulate any type of sensor data via a simple union (further described below)
|
||||
|
||||
**Required Functions**
|
||||
|
||||
In addition to the two standard types and the sensor type enum, all drivers based on Adafruit_Sensor must also implement the following two functions:
|
||||
|
||||
```
|
||||
bool getEvent(sensors_event_t*);
|
||||
```
|
||||
Calling this function will populate the supplied sensors\_event\_t reference with the latest available sensor data. You should call this function as often as you want to update your data.
|
||||
|
||||
```
|
||||
void getSensor(sensor_t*);
|
||||
```
|
||||
Calling this function will provide some basic information about the sensor (the sensor name, driver version, min and max values, etc.
|
||||
|
||||
**Standardised SI values for sensors\_event\_t**
|
||||
|
||||
A key part of the abstraction layer is the standardisation of values on SI units of a particular scale, which is accomplished via the data[4] union in sensors\_event\_t above. This 16 byte union includes fields for each main sensor type, and uses the following SI units and scales:
|
||||
|
||||
- **acceleration**: values are in **meter per second per second** (m/s^2)
|
||||
- **magnetic**: values are in **micro-Tesla** (uT)
|
||||
- **orientation**: values are in **degrees**
|
||||
- **gyro**: values are in **rad/s**
|
||||
- **temperature**: values in **degrees centigrade** (Celsius)
|
||||
- **distance**: values are in **centimeters**
|
||||
- **light**: values are in **SI lux** units
|
||||
- **pressure**: values are in **hectopascal** (hPa)
|
||||
- **relative\_humidity**: values are in **percent**
|
||||
- **current**: values are in **milliamps** (mA)
|
||||
- **voltage**: values are in **volts** (V)
|
||||
- **color**: values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format
|
||||
|
||||
## The Unified Driver Abstraction Layer in Practice ##
|
||||
|
||||
Using the unified sensor abstraction layer is relatively easy once a compliant driver has been created.
|
||||
|
||||
Every compliant sensor can now be read using a single, well-known 'type' (sensors\_event\_t), and there is a standardised way of interrogating a sensor about its specific capabilities (via sensor\_t).
|
||||
|
||||
An example of reading the [TSL2561](https://github.com/adafruit/Adafruit_TSL2561) light sensor can be seen below:
|
||||
|
||||
```
|
||||
Adafruit_TSL2561 tsl = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345);
|
||||
...
|
||||
/* Get a new sensor event */
|
||||
sensors_event_t event;
|
||||
tsl.getEvent(&event);
|
||||
|
||||
/* Display the results (light is measured in lux) */
|
||||
if (event.light)
|
||||
{
|
||||
Serial.print(event.light); Serial.println(" lux");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If event.light = 0 lux the sensor is probably saturated
|
||||
and no reliable data could be generated! */
|
||||
Serial.println("Sensor overload");
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, we can get the basic technical capabilities of this sensor with the following code:
|
||||
|
||||
```
|
||||
sensor_t sensor;
|
||||
|
||||
sensor_t sensor;
|
||||
tsl.getSensor(&sensor);
|
||||
|
||||
/* Display the sensor details */
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Sensor: "); Serial.println(sensor.name);
|
||||
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
|
||||
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
|
||||
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
|
||||
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
|
||||
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit Unified Sensor
|
||||
version=1.0.2
|
||||
author=Adafruit <info@adafruit.com>
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Required for all Adafruit Unified Sensor based libraries.
|
||||
paragraph=A unified sensor abstraction layer used by many Adafruit sensor libraries.
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_Sensor
|
||||
architectures=*
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
@@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
@@ -0,0 +1,504 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_TSL2591.cpp
|
||||
@author KT0WN (adafruit.com)
|
||||
|
||||
This is a library for the Adafruit TSL2591 breakout board
|
||||
This library works with the Adafruit TSL2591 breakout
|
||||
----> https://www.adafruit.com/products/1980
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These chips use I2C to communicate
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2014 Adafruit Industries
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
#include <pgmspace.h>
|
||||
#else
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#if defined(__AVR__)
|
||||
#include <util/delay.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
Adafruit_TSL2591::Adafruit_TSL2591(int32_t sensorID)
|
||||
{
|
||||
_initialized = false;
|
||||
_integration = TSL2591_INTEGRATIONTIME_100MS;
|
||||
_gain = TSL2591_GAIN_MED;
|
||||
_sensorID = sensorID;
|
||||
|
||||
// we cant do wire initialization till later, because we havent loaded Wire yet
|
||||
}
|
||||
|
||||
boolean Adafruit_TSL2591::begin(void)
|
||||
{
|
||||
Wire.begin();
|
||||
|
||||
/*
|
||||
for (uint8_t i=0; i<0x20; i++)
|
||||
{
|
||||
uint8_t id = read8(0x12);
|
||||
Serial.print("$"); Serial.print(i, HEX);
|
||||
Serial.print(" = 0x"); Serial.println(read8(i), HEX);
|
||||
}
|
||||
*/
|
||||
|
||||
uint8_t id = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID);
|
||||
if (id == 0x50 )
|
||||
{
|
||||
// Serial.println("Found Adafruit_TSL2591");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
|
||||
// Set default integration time and gain
|
||||
setTiming(_integration);
|
||||
setGain(_gain);
|
||||
|
||||
// Note: by default, the device is in power down mode on bootup
|
||||
disable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::enable(void)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the device by setting the control bit to 0x01
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN | TSL2591_ENABLE_AIEN | TSL2591_ENABLE_NPIEN);
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::disable(void)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the device by setting the control bit to 0x00
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF);
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::setGain(tsl2591Gain_t gain)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
_gain = gain;
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
|
||||
disable();
|
||||
}
|
||||
|
||||
tsl2591Gain_t Adafruit_TSL2591::getGain()
|
||||
{
|
||||
return _gain;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
_integration = integration;
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
|
||||
disable();
|
||||
}
|
||||
|
||||
tsl2591IntegrationTime_t Adafruit_TSL2591::getTiming()
|
||||
{
|
||||
return _integration;
|
||||
}
|
||||
|
||||
float Adafruit_TSL2591::calculateLuxf(uint16_t ch0, uint16_t ch1)
|
||||
{
|
||||
float atime, again;
|
||||
float cpl, lux1, lux2, lux;
|
||||
uint32_t chan0, chan1;
|
||||
|
||||
// Check for overflow conditions first
|
||||
if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF))
|
||||
{
|
||||
// Signal an overflow
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Note: This algorithm is based on preliminary coefficients
|
||||
// provided by AMS and may need to be updated in the future
|
||||
|
||||
switch (_integration)
|
||||
{
|
||||
case TSL2591_INTEGRATIONTIME_100MS :
|
||||
atime = 100.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_200MS :
|
||||
atime = 200.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_300MS :
|
||||
atime = 300.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_400MS :
|
||||
atime = 400.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_500MS :
|
||||
atime = 500.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_600MS :
|
||||
atime = 600.0F;
|
||||
break;
|
||||
default: // 100ms
|
||||
atime = 100.0F;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW :
|
||||
again = 1.0F;
|
||||
break;
|
||||
case TSL2591_GAIN_MED :
|
||||
again = 25.0F;
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH :
|
||||
again = 428.0F;
|
||||
break;
|
||||
case TSL2591_GAIN_MAX :
|
||||
again = 9876.0F;
|
||||
break;
|
||||
default:
|
||||
again = 1.0F;
|
||||
break;
|
||||
}
|
||||
|
||||
// cpl = (ATIME * AGAIN) / DF
|
||||
cpl = (atime * again) / TSL2591_LUX_DF;
|
||||
|
||||
lux1 = (((float) ch0 - (float) ch1)) * (1.0F - ((float) ch1 / (float) ch0)) / cpl;//( (float)ch0 - (TSL2591_LUX_COEFB * (float)ch1) ) / cpl;
|
||||
lux2 = ((TSL2591_LUX_COEFC * (float) ch0) - (TSL2591_LUX_COEFD * (float) ch1)) / cpl;
|
||||
lux = lux1 > lux2 ? lux1 : lux2;
|
||||
|
||||
// Alternate lux calculation
|
||||
//lux = ( (float)ch0 - ( 1.7F * (float)ch1 ) ) / cpl;
|
||||
|
||||
// Signal I2C had no errors
|
||||
return lux;
|
||||
}
|
||||
|
||||
uint32_t Adafruit_TSL2591::calculateLux(uint16_t ch0, uint16_t ch1)
|
||||
{
|
||||
return (uint32_t) calculateLuxf(ch0, ch1);
|
||||
}
|
||||
|
||||
uint32_t Adafruit_TSL2591::getFullLuminosity (void)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the device
|
||||
enable();
|
||||
|
||||
// Wait x ms for ADC to complete
|
||||
for (uint8_t d=0; d<=_integration; d++)
|
||||
{
|
||||
delay(120);
|
||||
}
|
||||
|
||||
uint32_t x;
|
||||
uint16_t y;
|
||||
y |= read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
|
||||
x = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
|
||||
x <<= 16;
|
||||
x |= y;
|
||||
|
||||
disable();
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16_t Adafruit_TSL2591::getLuminosity (uint8_t channel)
|
||||
{
|
||||
uint32_t x = getFullLuminosity();
|
||||
|
||||
if (channel == TSL2591_FULLSPECTRUM)
|
||||
{
|
||||
// Reads two byte value from channel 0 (visible + infrared)
|
||||
return (x & 0xFFFF);
|
||||
}
|
||||
else if (channel == TSL2591_INFRARED)
|
||||
{
|
||||
// Reads two byte value from channel 1 (infrared)
|
||||
return (x >> 16);
|
||||
}
|
||||
else if (channel == TSL2591_VISIBLE)
|
||||
{
|
||||
// Reads all and subtracts out just the visible!
|
||||
return ( (x & 0xFFFF) - (x >> 16));
|
||||
}
|
||||
|
||||
// unknown channel!
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAILTL, lowerThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAILTH, lowerThreshold >> 8);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAIHTL, upperThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAIHTH, upperThreshold >> 8);
|
||||
disable();
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold, tsl2591Persist_t persist)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_PERSIST_FILTER, persist);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AILTL, lowerThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AILTH, lowerThreshold >> 8);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AIHTL, upperThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AIHTH, upperThreshold >> 8);
|
||||
disable();
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::clearInterrupt()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
write8(TSL2591_CLEAR_INT);
|
||||
disable();
|
||||
}
|
||||
|
||||
|
||||
uint8_t Adafruit_TSL2591::getStatus()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the device
|
||||
enable();
|
||||
uint8_t x;
|
||||
x = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_STATUS);
|
||||
disable();
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint8_t Adafruit_TSL2591::read8(uint8_t reg)
|
||||
{
|
||||
uint8_t x;
|
||||
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(TSL2591_ADDR, 1);
|
||||
#if ARDUINO >= 100
|
||||
x = Wire.read();
|
||||
#else
|
||||
x = Wire.receive();
|
||||
#endif
|
||||
// while (! Wire.available());
|
||||
// return Wire.read();
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16_t Adafruit_TSL2591::read16(uint8_t reg)
|
||||
{
|
||||
uint16_t x;
|
||||
uint16_t t;
|
||||
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(TSL2591_ADDR, 2);
|
||||
#if ARDUINO >= 100
|
||||
t = Wire.read();
|
||||
x = Wire.read();
|
||||
#else
|
||||
t = Wire.receive();
|
||||
x = Wire.receive();
|
||||
#endif
|
||||
x <<= 8;
|
||||
x |= t;
|
||||
return x;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::write8 (uint8_t reg, uint8_t value)
|
||||
{
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
Wire.write(value);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
Wire.send(value);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_TSL2591::write8 (uint8_t reg)
|
||||
{
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent sensor event
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_TSL2591::getEvent(sensors_event_t *event)
|
||||
{
|
||||
uint16_t ir, full;
|
||||
uint32_t lum = getFullLuminosity();
|
||||
/* Early silicon seems to have issues when there is a sudden jump in */
|
||||
/* light levels. :( To work around this for now sample the sensor 2x */
|
||||
lum = getFullLuminosity();
|
||||
ir = lum >> 16;
|
||||
full = lum & 0xFFFF;
|
||||
|
||||
/* Clear the event */
|
||||
memset(event, 0, sizeof(sensors_event_t));
|
||||
|
||||
event->version = sizeof(sensors_event_t);
|
||||
event->sensor_id = _sensorID;
|
||||
event->type = SENSOR_TYPE_LIGHT;
|
||||
event->timestamp = millis();
|
||||
|
||||
/* Calculate the actual lux value */
|
||||
/* 0 = sensor overflow (too much light) */
|
||||
event->light = calculateLux(full, ir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the sensor_t data
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TSL2591::getSensor(sensor_t *sensor)
|
||||
{
|
||||
/* Clear the sensor_t object */
|
||||
memset(sensor, 0, sizeof(sensor_t));
|
||||
|
||||
/* Insert the sensor name in the fixed length char array */
|
||||
strncpy (sensor->name, "TSL2591", sizeof(sensor->name) - 1);
|
||||
sensor->name[sizeof(sensor->name)- 1] = 0;
|
||||
sensor->version = 1;
|
||||
sensor->sensor_id = _sensorID;
|
||||
sensor->type = SENSOR_TYPE_LIGHT;
|
||||
sensor->min_delay = 0;
|
||||
sensor->max_value = 88000.0;
|
||||
sensor->min_value = 0.0;
|
||||
sensor->resolution = 1.0;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_TSL2591.h
|
||||
@author KT0WN (adafruit.com)
|
||||
|
||||
This is a library for the Adafruit TSL2591 breakout board
|
||||
This library works with the Adafruit TSL2591 breakout
|
||||
----> https://www.adafruit.com/products/1980
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These chips use I2C to communicate
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2014 Adafruit Industries
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _TSL2591_H_
|
||||
#define _TSL2591_H_
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#define TSL2591_VISIBLE (2) // channel 0 - channel 1
|
||||
#define TSL2591_INFRARED (1) // channel 1
|
||||
#define TSL2591_FULLSPECTRUM (0) // channel 0
|
||||
|
||||
#define TSL2591_ADDR (0x29)
|
||||
#define TSL2591_READBIT (0x01)
|
||||
|
||||
#define TSL2591_COMMAND_BIT (0xA0) // 1010 0000: bits 7 and 5 for 'command normal'
|
||||
#define TSL2591_CLEAR_INT (0xE7)
|
||||
#define TSL2591_TEST_INT (0xE4)
|
||||
#define TSL2591_WORD_BIT (0x20) // 1 = read/write word (rather than byte)
|
||||
#define TSL2591_BLOCK_BIT (0x10) // 1 = using block read/write
|
||||
|
||||
#define TSL2591_ENABLE_POWEROFF (0x00)
|
||||
#define TSL2591_ENABLE_POWERON (0x01)
|
||||
#define TSL2591_ENABLE_AEN (0x02) // ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.
|
||||
#define TSL2591_ENABLE_AIEN (0x10) // ALS Interrupt Enable. When asserted permits ALS interrupts to be generated, subject to the persist filter.
|
||||
#define TSL2591_ENABLE_NPIEN (0x80) // No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter
|
||||
|
||||
#define TSL2591_LUX_DF (408.0F)
|
||||
#define TSL2591_LUX_COEFB (1.64F) // CH0 coefficient
|
||||
#define TSL2591_LUX_COEFC (0.59F) // CH1 coefficient A
|
||||
#define TSL2591_LUX_COEFD (0.86F) // CH2 coefficient B
|
||||
|
||||
enum
|
||||
{
|
||||
TSL2591_REGISTER_ENABLE = 0x00,
|
||||
TSL2591_REGISTER_CONTROL = 0x01,
|
||||
TSL2591_REGISTER_THRESHOLD_AILTL = 0x04, // ALS low threshold lower byte
|
||||
TSL2591_REGISTER_THRESHOLD_AILTH = 0x05, // ALS low threshold upper byte
|
||||
TSL2591_REGISTER_THRESHOLD_AIHTL = 0x06, // ALS high threshold lower byte
|
||||
TSL2591_REGISTER_THRESHOLD_AIHTH = 0x07, // ALS high threshold upper byte
|
||||
TSL2591_REGISTER_THRESHOLD_NPAILTL = 0x08, // No Persist ALS low threshold lower byte
|
||||
TSL2591_REGISTER_THRESHOLD_NPAILTH = 0x09, // etc
|
||||
TSL2591_REGISTER_THRESHOLD_NPAIHTL = 0x0A,
|
||||
TSL2591_REGISTER_THRESHOLD_NPAIHTH = 0x0B,
|
||||
TSL2591_REGISTER_PERSIST_FILTER = 0x0C,
|
||||
TSL2591_REGISTER_PACKAGE_PID = 0x11,
|
||||
TSL2591_REGISTER_DEVICE_ID = 0x12,
|
||||
TSL2591_REGISTER_DEVICE_STATUS = 0x13,
|
||||
TSL2591_REGISTER_CHAN0_LOW = 0x14,
|
||||
TSL2591_REGISTER_CHAN0_HIGH = 0x15,
|
||||
TSL2591_REGISTER_CHAN1_LOW = 0x16,
|
||||
TSL2591_REGISTER_CHAN1_HIGH = 0x17
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TSL2591_INTEGRATIONTIME_100MS = 0x00,
|
||||
TSL2591_INTEGRATIONTIME_200MS = 0x01,
|
||||
TSL2591_INTEGRATIONTIME_300MS = 0x02,
|
||||
TSL2591_INTEGRATIONTIME_400MS = 0x03,
|
||||
TSL2591_INTEGRATIONTIME_500MS = 0x04,
|
||||
TSL2591_INTEGRATIONTIME_600MS = 0x05,
|
||||
}
|
||||
tsl2591IntegrationTime_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// bit 7:4: 0
|
||||
TSL2591_PERSIST_EVERY = 0x00, // Every ALS cycle generates an interrupt
|
||||
TSL2591_PERSIST_ANY = 0x01, // Any value outside of threshold range
|
||||
TSL2591_PERSIST_2 = 0x02, // 2 consecutive values out of range
|
||||
TSL2591_PERSIST_3 = 0x03, // 3 consecutive values out of range
|
||||
TSL2591_PERSIST_5 = 0x04, // 5 consecutive values out of range
|
||||
TSL2591_PERSIST_10 = 0x05, // 10 consecutive values out of range
|
||||
TSL2591_PERSIST_15 = 0x06, // 15 consecutive values out of range
|
||||
TSL2591_PERSIST_20 = 0x07, // 20 consecutive values out of range
|
||||
TSL2591_PERSIST_25 = 0x08, // 25 consecutive values out of range
|
||||
TSL2591_PERSIST_30 = 0x09, // 30 consecutive values out of range
|
||||
TSL2591_PERSIST_35 = 0x0A, // 35 consecutive values out of range
|
||||
TSL2591_PERSIST_40 = 0x0B, // 40 consecutive values out of range
|
||||
TSL2591_PERSIST_45 = 0x0C, // 45 consecutive values out of range
|
||||
TSL2591_PERSIST_50 = 0x0D, // 50 consecutive values out of range
|
||||
TSL2591_PERSIST_55 = 0x0E, // 55 consecutive values out of range
|
||||
TSL2591_PERSIST_60 = 0x0F, // 60 consecutive values out of range
|
||||
}
|
||||
tsl2591Persist_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TSL2591_GAIN_LOW = 0x00, // low gain (1x)
|
||||
TSL2591_GAIN_MED = 0x10, // medium gain (25x)
|
||||
TSL2591_GAIN_HIGH = 0x20, // medium gain (428x)
|
||||
TSL2591_GAIN_MAX = 0x30, // max gain (9876x)
|
||||
}
|
||||
tsl2591Gain_t;
|
||||
|
||||
class Adafruit_TSL2591 : public Adafruit_Sensor
|
||||
{
|
||||
public:
|
||||
Adafruit_TSL2591(int32_t sensorID = -1);
|
||||
|
||||
boolean begin ( void );
|
||||
void enable ( void );
|
||||
void disable ( void );
|
||||
void write8 ( uint8_t r);
|
||||
void write8 ( uint8_t r, uint8_t v );
|
||||
uint16_t read16 ( uint8_t reg );
|
||||
uint8_t read8 ( uint8_t reg );
|
||||
|
||||
uint32_t calculateLux ( uint16_t ch0, uint16_t ch1 );
|
||||
float calculateLuxf ( uint16_t ch0, uint16_t ch1 );
|
||||
void setGain ( tsl2591Gain_t gain );
|
||||
void setTiming ( tsl2591IntegrationTime_t integration );
|
||||
uint16_t getLuminosity (uint8_t channel );
|
||||
uint32_t getFullLuminosity ( );
|
||||
|
||||
tsl2591IntegrationTime_t getTiming();
|
||||
tsl2591Gain_t getGain();
|
||||
|
||||
// Interrupt
|
||||
void clearInterrupt(void);
|
||||
void registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold);
|
||||
void registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold, tsl2591Persist_t persist);
|
||||
uint8_t getStatus();
|
||||
|
||||
/* Unified Sensor API Functions */
|
||||
bool getEvent ( sensors_event_t* );
|
||||
void getSensor ( sensor_t* );
|
||||
|
||||
private:
|
||||
tsl2591IntegrationTime_t _integration;
|
||||
tsl2591Gain_t _gain;
|
||||
int32_t _sensorID;
|
||||
|
||||
boolean _initialized;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
This is an Arduino library for the TSL2591 digital luminosity (light) sensors.
|
||||
|
||||
Pick one up at http://www.adafruit.com/products/1980
|
||||
|
||||
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TSL2591. Check that the Adafruit_TSL2591 folder contains Adafruit_TSL2591.cpp and Adafruit_TSL2591.h
|
||||
|
||||
Place the Adafruit_TSL2591 library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.
|
||||
|
||||
You'll also need the Adafruit_Sensor library from https://github.com/adafruit/Adafruit_Sensor
|
||||
@@ -0,0 +1,200 @@
|
||||
/* TSL2591 Digital Light Sensor */
|
||||
/* Dynamic Range: 600M:1 */
|
||||
/* Maximum Lux: 88K */
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
// Example for demonstrating the TSL2591 library - public domain!
|
||||
|
||||
// connect SCL to analog 5
|
||||
// connect SDA to analog 4
|
||||
// connect Vin to 3.3-5V DC
|
||||
// connect GROUND to common ground
|
||||
|
||||
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Displays some basic information on this sensor from the unified
|
||||
sensor API sensor_t type (see Adafruit_Sensor for more information)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void displaySensorDetails(void)
|
||||
{
|
||||
sensor_t sensor;
|
||||
tsl.getSensor(&sensor);
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.print (F("Sensor: ")); Serial.println(sensor.name);
|
||||
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
|
||||
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
|
||||
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
|
||||
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
|
||||
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F(" lux"));
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.println(F(""));
|
||||
delay(500);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Configures the gain and integration time for the TSL2591
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void configureSensor(void)
|
||||
{
|
||||
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
|
||||
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
|
||||
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
|
||||
|
||||
// Changing the integration time gives you a longer time over which to sense light
|
||||
// longer timelines are slower, but are good in very low light situtations!
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
|
||||
|
||||
/* Display the gain and integration time for reference sake */
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.print (F("Gain: "));
|
||||
tsl2591Gain_t gain = tsl.getGain();
|
||||
switch(gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW:
|
||||
Serial.println(F("1x (Low)"));
|
||||
break;
|
||||
case TSL2591_GAIN_MED:
|
||||
Serial.println(F("25x (Medium)"));
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH:
|
||||
Serial.println(F("428x (High)"));
|
||||
break;
|
||||
case TSL2591_GAIN_MAX:
|
||||
Serial.println(F("9876x (Max)"));
|
||||
break;
|
||||
}
|
||||
Serial.print (F("Timing: "));
|
||||
Serial.print((tsl.getTiming() + 1) * 100, DEC);
|
||||
Serial.println(F(" ms"));
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.println(F(""));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Program entry point for the Arduino sketch
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
Serial.println(F("Starting Adafruit TSL2591 Test!"));
|
||||
|
||||
if (tsl.begin())
|
||||
{
|
||||
Serial.println(F("Found a TSL2591 sensor"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No sensor found ... check your wiring?"));
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Display some basic information on this sensor */
|
||||
displaySensorDetails();
|
||||
|
||||
/* Configure the sensor */
|
||||
configureSensor();
|
||||
|
||||
// Now we're ready to get readings ... move on to loop()!
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Shows how to perform a basic read on visible, full spectrum or
|
||||
infrared light (returns raw 16-bit ADC values)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void simpleRead(void)
|
||||
{
|
||||
// Simple data read example. Just read the infrared, fullspecrtrum diode
|
||||
// or 'visible' (difference between the two) channels.
|
||||
// This can take 100-600 milliseconds! Uncomment whichever of the following you want to read
|
||||
uint16_t x = tsl.getLuminosity(TSL2591_VISIBLE);
|
||||
//uint16_t x = tsl.getLuminosity(TSL2591_FULLSPECTRUM);
|
||||
//uint16_t x = tsl.getLuminosity(TSL2591_INFRARED);
|
||||
|
||||
Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
|
||||
Serial.print(F("Luminosity: "));
|
||||
Serial.println(x, DEC);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Show how to read IR and Full Spectrum at once and convert to lux
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void advancedRead(void)
|
||||
{
|
||||
// More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
|
||||
// That way you can do whatever math and comparisons you want!
|
||||
uint32_t lum = tsl.getFullLuminosity();
|
||||
uint16_t ir, full;
|
||||
ir = lum >> 16;
|
||||
full = lum & 0xFFFF;
|
||||
Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
|
||||
Serial.print(F("IR: ")); Serial.print(ir); Serial.print(F(" "));
|
||||
Serial.print(F("Full: ")); Serial.print(full); Serial.print(F(" "));
|
||||
Serial.print(F("Visible: ")); Serial.print(full - ir); Serial.print(F(" "));
|
||||
Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Performs a read using the Adafruit Unified Sensor API.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void unifiedSensorAPIRead(void)
|
||||
{
|
||||
/* Get a new sensor event */
|
||||
sensors_event_t event;
|
||||
tsl.getEvent(&event);
|
||||
|
||||
/* Display the results (light is measured in lux) */
|
||||
Serial.print(F("[ ")); Serial.print(event.timestamp); Serial.print(F(" ms ] "));
|
||||
if ((event.light == 0) |
|
||||
(event.light > 4294966000.0) |
|
||||
(event.light <-4294966000.0))
|
||||
{
|
||||
/* If event.light = 0 lux the sensor is probably saturated */
|
||||
/* and no reliable data could be generated! */
|
||||
/* if event.light is +/- 4294967040 there was a float over/underflow */
|
||||
Serial.println(F("Invalid data (adjust gain or timing)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(event.light); Serial.println(F(" lux"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Arduino loop function, called once 'setup' is complete (your own code
|
||||
should go here)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void loop(void)
|
||||
{
|
||||
//simpleRead();
|
||||
advancedRead();
|
||||
// unifiedSensorAPIRead();
|
||||
|
||||
delay(500);
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/* TSL2591 Digital Light Sensor, example with (simple) interrupt support */
|
||||
/* Dynamic Range: 600M:1 */
|
||||
/* Maximum Lux: 88K */
|
||||
|
||||
/* This example shows how the interrupt system on the TLS2591
|
||||
* can be used to detect a meaningful change in light levels.
|
||||
*
|
||||
* Two thresholds can be set:
|
||||
*
|
||||
* Lower Threshold - Any light sample on CHAN0 below this value
|
||||
* will trigger an interrupt
|
||||
* Upper Threshold - Any light sample on CHAN0 above this value
|
||||
* will trigger an interrupt
|
||||
*
|
||||
* If CHAN0 (full light) crosses below the low threshold specified,
|
||||
* or above the higher threshold, an interrupt is asserted on the interrupt
|
||||
* pin. The use of the HW pin is optional, though, since the change can
|
||||
* also be detected in software by looking at the status byte via
|
||||
* tsl.getStatus().
|
||||
*
|
||||
* An optional third parameter can be used in the .registerInterrupt
|
||||
* function to indicate the number of samples that must stay outside
|
||||
* the threshold window before the interrupt fires, providing some basic
|
||||
* debouncing of light level data.
|
||||
*
|
||||
* For example, the following code will fire an interrupt on any and every
|
||||
* sample outside the window threshold (meaning a sample below 100 or above
|
||||
* 1500 on CHAN0 or FULL light):
|
||||
*
|
||||
* tsl.registerInterrupt(100, 1500, TSL2591_PERSIST_ANY);
|
||||
*
|
||||
* This code would require five consecutive changes before the interrupt
|
||||
* fires though (see tls2591Persist_t in Adafruit_TLS2591.h for possible
|
||||
* values):
|
||||
*
|
||||
* tsl.registerInterrupt(100, 1500, TSL2591_PERSIST_5);
|
||||
*/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
// Example for demonstrating the TSL2591 library - public domain!
|
||||
|
||||
// connect SCL to analog 5
|
||||
// connect SDA to analog 4
|
||||
// connect Vin to 3.3-5V DC
|
||||
// connect GROUND to common ground
|
||||
|
||||
// Interrupt thresholds and persistance
|
||||
#define TLS2591_INT_THRESHOLD_LOWER (100)
|
||||
#define TLS2591_INT_THRESHOLD_UPPER (1500)
|
||||
//#define TLS2591_INT_PERSIST (TSL2591_PERSIST_ANY) // Fire on any valid change
|
||||
#define TLS2591_INT_PERSIST (TSL2591_PERSIST_60) // Require at least 60 samples to fire
|
||||
|
||||
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Displays some basic information on this sensor from the unified
|
||||
sensor API sensor_t type (see Adafruit_Sensor for more information)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void displaySensorDetails(void)
|
||||
{
|
||||
sensor_t sensor;
|
||||
tsl.getSensor(&sensor);
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Sensor: "); Serial.println(sensor.name);
|
||||
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
|
||||
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
|
||||
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
|
||||
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
|
||||
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
delay(500);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Configures the gain and integration time for the TSL2591
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void configureSensor(void)
|
||||
{
|
||||
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
|
||||
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
|
||||
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
|
||||
|
||||
// Changing the integration time gives you a longer time over which to sense light
|
||||
// longer timelines are slower, but are good in very low light situtations!
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
|
||||
|
||||
/* Display the gain and integration time for reference sake */
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Gain: ");
|
||||
tsl2591Gain_t gain = tsl.getGain();
|
||||
switch (gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW:
|
||||
Serial.println("1x (Low)");
|
||||
break;
|
||||
case TSL2591_GAIN_MED:
|
||||
Serial.println("25x (Medium)");
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH:
|
||||
Serial.println("428x (High)");
|
||||
break;
|
||||
case TSL2591_GAIN_MAX:
|
||||
Serial.println("9876x (Max)");
|
||||
break;
|
||||
}
|
||||
Serial.print ("Timing: ");
|
||||
Serial.print((tsl.getTiming() + 1) * 100, DEC);
|
||||
Serial.println(" ms");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
|
||||
/* Setup the SW interrupt to trigger between 100 and 1500 lux */
|
||||
/* Threshold values are defined at the top of this sketch */
|
||||
tsl.clearInterrupt();
|
||||
tsl.registerInterrupt(TLS2591_INT_THRESHOLD_LOWER,
|
||||
TLS2591_INT_THRESHOLD_UPPER,
|
||||
TLS2591_INT_PERSIST);
|
||||
|
||||
/* Display the interrupt threshold window */
|
||||
Serial.print("Interrupt Threshold Window: -");
|
||||
Serial.print(TLS2591_INT_THRESHOLD_LOWER, DEC);
|
||||
Serial.print(" to +");
|
||||
Serial.println(TLS2591_INT_THRESHOLD_LOWER, DEC);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Program entry point for the Arduino sketch
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
// Enable this line for Flora, Zero and Feather boards with no FTDI chip
|
||||
// Waits for the serial port to connect before sending data out
|
||||
// while (!Serial) { delay(1); }
|
||||
|
||||
Serial.println("Starting Adafruit TSL2591 interrupt Test!");
|
||||
|
||||
if (tsl.begin())
|
||||
{
|
||||
Serial.println("Found a TSL2591 sensor");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("No sensor found ... check your wiring?");
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Display some basic information on this sensor */
|
||||
displaySensorDetails();
|
||||
|
||||
/* Configure the sensor (including the interrupt threshold) */
|
||||
configureSensor();
|
||||
|
||||
// Now we're ready to get readings ... move on to loop()!
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Show how to read IR and Full Spectrum at once and convert to lux
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void advancedRead(void)
|
||||
{
|
||||
// More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
|
||||
// That way you can do whatever math and comparisons you want!
|
||||
uint32_t lum = tsl.getFullLuminosity();
|
||||
uint16_t ir, full;
|
||||
ir = lum >> 16;
|
||||
full = lum & 0xFFFF;
|
||||
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.print("IR: "); Serial.print(ir); Serial.print(" ");
|
||||
Serial.print("Full: "); Serial.print(full); Serial.print(" ");
|
||||
Serial.print("Visible: "); Serial.print(full - ir); Serial.print(" ");
|
||||
Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir));
|
||||
}
|
||||
|
||||
|
||||
void getStatus(void)
|
||||
{
|
||||
uint8_t x = tsl.getStatus();
|
||||
// bit 4: ALS Interrupt occured
|
||||
// bit 5: No-persist Interrupt occurence
|
||||
if (x & 0x10) {
|
||||
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.println("ALS Interrupt occured");
|
||||
}
|
||||
if (x & 0x20) {
|
||||
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.println("No-persist Interrupt occured");
|
||||
}
|
||||
|
||||
// Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.print("Status: ");
|
||||
Serial.println(x, BIN);
|
||||
tsl.clearInterrupt();
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Arduino loop function, called once 'setup' is complete (your own code
|
||||
should go here)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void loop(void)
|
||||
{
|
||||
advancedRead();
|
||||
getStatus();
|
||||
delay(500);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit TSL2591 Library
|
||||
version=1.0.2
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Library for the TSL2591 digital luminosity (light) sensors.
|
||||
paragraph=Library for the TSL2591 digital luminosity (light) sensors.
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_TSL2591_Library
|
||||
architectures=*
|
||||
@@ -0,0 +1,265 @@
|
||||
//#######################################################################################################
|
||||
//######################## Plugin 074 TSL2591 I2C Lux/IR Sensor #########################################
|
||||
//#######################################################################################################
|
||||
//
|
||||
// by: https://github.com/krikk
|
||||
// this plugin is based on the adafruit library
|
||||
// written based on version 1.0.2 from https://github.com/adafruit/Adafruit_TSL2591_Library
|
||||
// does need Adafruit Sensors Library
|
||||
// added lux calculation improvement https://github.com/adafruit/Adafruit_TSL2591_Library/issues/14
|
||||
// added fix for issue https://github.com/adafruit/Adafruit_TSL2591_Library/issues/17
|
||||
|
||||
#ifdef PLUGIN_BUILD_TESTING
|
||||
|
||||
#define PLUGIN_074
|
||||
#define PLUGIN_ID_074 74
|
||||
#define PLUGIN_NAME_074 "Light/Lux - TSL2591 [TESTING]"
|
||||
#define PLUGIN_VALUENAME1_074 "Lux"
|
||||
#define PLUGIN_VALUENAME2_074 "Full"
|
||||
#define PLUGIN_VALUENAME3_074 "Visible"
|
||||
#define PLUGIN_VALUENAME4_074 "IR"
|
||||
|
||||
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
#ifndef CONFIG
|
||||
#define CONFIG(n) (Settings.TaskDevicePluginConfig[event->TaskIndex][n])
|
||||
#endif
|
||||
|
||||
Adafruit_TSL2591 tsl;
|
||||
boolean TSL2591_initialized = false;
|
||||
|
||||
boolean Plugin_074(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
|
||||
switch (function)
|
||||
{
|
||||
case PLUGIN_DEVICE_ADD:
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_074;
|
||||
Device[deviceCount].Type = DEVICE_TYPE_I2C;
|
||||
Device[deviceCount].Ports = 0;
|
||||
Device[deviceCount].VType = SENSOR_TYPE_QUAD;
|
||||
Device[deviceCount].PullUpOption = false;
|
||||
Device[deviceCount].InverseLogicOption = false;
|
||||
Device[deviceCount].FormulaOption = true;
|
||||
Device[deviceCount].ValueCount = 4;
|
||||
Device[deviceCount].SendDataOption = true;
|
||||
Device[deviceCount].TimerOption = true;
|
||||
Device[deviceCount].TimerOptional = false;
|
||||
Device[deviceCount].GlobalSyncOption = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICENAME:
|
||||
{
|
||||
string = F(PLUGIN_NAME_074);
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEVALUENAMES:
|
||||
{
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_074));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_074));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_074));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_074));
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
int optionValues[1] = { TSL2591_ADDR };
|
||||
addFormSelectorI2C(string, F("plugin_074_i2c_addr"), 1, optionValues, TSL2591_ADDR); //Only for display I2C address
|
||||
|
||||
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
|
||||
|
||||
String optionsMode[6] = { F("100ms"), F("200ms"), F("300ms"), F("400ms"), F("500ms"), F("600ms") };
|
||||
addFormSelector(string, F("Integration Time"), F("plugin_074_itime"), 6, optionsMode, NULL, CONFIG(1));
|
||||
|
||||
|
||||
// TSL2591_GAIN_LOW = 0x00, // low gain (1x)
|
||||
// TSL2591_GAIN_MED = 0x10, // medium gain (25x)
|
||||
// TSL2591_GAIN_HIGH = 0x20, // medium gain (428x)
|
||||
// TSL2591_GAIN_MAX = 0x30, // max gain (9876x)
|
||||
|
||||
String optionsGain[4] = {
|
||||
F("low gain (1x)"),
|
||||
F("medium gain (25x)"),
|
||||
F("medium gain (428x)"),
|
||||
F("max gain (9876x)") };
|
||||
addFormSelector(string, F("Value Mapping"), F("plugin_074_gain"), 4, optionsGain, NULL, CONFIG(2));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_SAVE:
|
||||
{
|
||||
//CONFIG(0) = getFormItemInt(F("plugin_074_i2c_addr"));
|
||||
CONFIG(1) = getFormItemInt(F("plugin_074_itime"));
|
||||
CONFIG(2) = getFormItemInt(F("plugin_074_gain"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
|
||||
|
||||
if (tsl.begin())
|
||||
{
|
||||
String log = F("TSL2591: Address: 0x");
|
||||
log += String(TSL2591_ADDR,HEX);
|
||||
|
||||
|
||||
// Changing the integration time gives you a longer time over which to sense light
|
||||
// longer timelines are slower, but are good in very low light situtations!
|
||||
switch (CONFIG(1))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
{
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log += F(": Integration Time: ");
|
||||
log += String((tsl.getTiming() + 1) * 100, DEC);
|
||||
log += F(" ms");
|
||||
|
||||
|
||||
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||
switch (CONFIG(2))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
{
|
||||
tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
tsl.setGain(TSL2591_GAIN_MAX); // 9876x gain
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Display the gain and integration time for reference sake */
|
||||
log += (F(" Gain: "));
|
||||
tsl2591Gain_t gain = tsl.getGain();
|
||||
switch(gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW:
|
||||
log += F("1x (Low)");
|
||||
break;
|
||||
case TSL2591_GAIN_MED:
|
||||
log += F("25x (Medium)");
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH:
|
||||
log += F("428x (High)");
|
||||
break;
|
||||
case TSL2591_GAIN_MAX:
|
||||
log += F("9876x (Max)");
|
||||
break;
|
||||
}
|
||||
|
||||
TSL2591_initialized = true;
|
||||
addLog(LOG_LEVEL_INFO,log);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
TSL2591_initialized = false;
|
||||
addLog(LOG_LEVEL_ERROR,F("TSL2591: No sensor found ... check your wiring?"));
|
||||
}
|
||||
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_READ:
|
||||
{
|
||||
if (TSL2591_initialized)
|
||||
{
|
||||
// Simple data read example. Just read the infrared, fullspecrtrum diode
|
||||
// or 'visible' (difference between the two) channels.
|
||||
// This can take 100-600 milliseconds! Uncomment whichever of the following you want to read
|
||||
float lux, full, visible, ir;
|
||||
visible = tsl.getLuminosity(TSL2591_VISIBLE);
|
||||
ir = tsl.getLuminosity(TSL2591_INFRARED);
|
||||
full = tsl.getLuminosity(TSL2591_FULLSPECTRUM);
|
||||
lux = tsl.calculateLuxf(full, ir); // get LUX
|
||||
|
||||
UserVar[event->BaseVarIndex + 0] = lux;
|
||||
UserVar[event->BaseVarIndex + 1] = full;
|
||||
UserVar[event->BaseVarIndex + 2] = visible;
|
||||
UserVar[event->BaseVarIndex + 3] = ir;
|
||||
|
||||
String log = F("TSL2591: Lux: ");
|
||||
log += String(lux);
|
||||
log += F(" Full: ");
|
||||
log += String(full);
|
||||
log += F(" Visible: ");
|
||||
log += String(visible);
|
||||
log += F(" IR: ");
|
||||
log += String(ir);
|
||||
addLog(LOG_LEVEL_INFO,log);
|
||||
}
|
||||
else {
|
||||
addLog(LOG_LEVEL_ERROR,F("TSL2591: Sensor not initialized!?"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user