Luminosity sensor by Texas Advanced Optoelectronic Solutions Inc.. Device combines one broadband photodiode (visible plus infrared) and one infrared-responding photodiode. Sets Gain x1 and 402mS as default.

Dependents:   MusicBoxForFathersDay FTHR_SensorHub Affich_Lum_Moist Projetv0 ... more

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Fri Sep 21 22:57:07 2018 +0000
Parent:
4:05d322353720
Commit message:
based on Adafruit program and keep interface functions

Changed in this revision

Original/Adafruit_Sensor_h.txt Show annotated file Show diff for this revision Revisions of this file
Original/Adafruit_TSL2561_U_cpp.txt Show annotated file Show diff for this revision Revisions of this file
Original/Adafruit_TSL2561_U_h.txt Show annotated file Show diff for this revision Revisions of this file
Original/sensorapi_ino.txt Show annotated file Show diff for this revision Revisions of this file
TSL2561.cpp Show annotated file Show diff for this revision Revisions of this file
TSL2561.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Original/Adafruit_Sensor_h.txt	Fri Sep 21 22:57:07 2018 +0000
@@ -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
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Original/Adafruit_TSL2561_U_cpp.txt	Fri Sep 21 22:57:07 2018 +0000
@@ -0,0 +1,575 @@
+/*!
+ * @file Adafruit_TSL2561_U.cpp
+ *
+ * @mainpage Adafruit TSL2561 Light/Lux sensor driver
+ *
+ * @section intro_sec Introduction
+ *
+ * This is the documentation for Adafruit's TSL2561 driver for the
+ * Arduino platform.  It is designed specifically to work with the
+ * Adafruit TSL2561 breakout: http://www.adafruit.com/products/439
+ *
+ * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
+ * to interface with the breakout.
+ *
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * @section dependencies Dependencies
+ *
+ * This library depends on <a href="https://github.com/adafruit/Adafruit_Sensor">
+ * Adafruit_Sensor</a> being present on your system. Please make sure you have
+ * installed the latest version before using this library.
+ *
+ * @section author Author
+ *
+ * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
+ *
+ * @section license License
+ *
+ * BSD license, all text here must be included in any redistribution.
+ *
+ *   @section  HISTORY
+ *
+ *   v2.0 - Rewrote driver for Adafruit_Sensor and Auto-Gain support, and
+ *          added lux clipping check (returns 0 lux on sensor saturation)
+ *   v1.0 - First release (previously TSL2561)
+*/
+/**************************************************************************/
+
+#include "Adafruit_TSL2561_U.h"
+
+/*========================================================================*/
+/*                            CONSTRUCTORS                                */
+/*========================================================================*/
+
+/**************************************************************************/
+/*!
+    @brief Constructor
+    @param addr The I2C address this chip can be found on, 0x29, 0x39 or 0x49
+    @param sensorID An optional ID that will be placed in sensor events to help
+                    keep track if you have many sensors in use
+*/
+/**************************************************************************/
+Adafruit_TSL2561_Unified::Adafruit_TSL2561_Unified(uint8_t addr, int32_t sensorID)
+{
+  _addr = addr;
+  _tsl2561Initialised = false;
+  _tsl2561AutoGain = false;
+  _tsl2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
+  _tsl2561Gain = TSL2561_GAIN_1X;
+  _tsl2561SensorID = sensorID;
+}
+
+/*========================================================================*/
+/*                           PUBLIC FUNCTIONS                             */
+/*========================================================================*/
+
+/**************************************************************************/
+/*!
+    @brief Initializes I2C and configures the sensor with default Wire I2C
+           (call this function before doing anything else)
+    @returns True if sensor is found and initialized, false otherwise.
+*/
+/**************************************************************************/
+boolean Adafruit_TSL2561_Unified::begin()
+{
+  _i2c = &Wire;
+  _i2c->begin();
+  return init();
+}
+
+/**************************************************************************/
+/*!
+    @brief Initializes I2C and configures the sensor with provided I2C device
+           (call this function before doing anything else)
+    @param theWire A pointer to any I2C interface (e.g. &Wire1)
+    @returns True if sensor is found and initialized, false otherwise.
+*/
+/**************************************************************************/
+boolean Adafruit_TSL2561_Unified::begin(TwoWire *theWire)
+{
+  _i2c = theWire;
+  _i2c-> begin();
+  return init();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initializes I2C connection and settings. 
+    Attempts to determine if the sensor is contactable, then sets up a default
+    integration time and gain. Then powers down the chip.
+    @returns True if sensor is found and initialized, false otherwise.
+*/
+/**************************************************************************/
+boolean Adafruit_TSL2561_Unified::init()
+{
+  /* Make sure we're actually connected */
+  uint8_t x = read8(TSL2561_REGISTER_ID);
+  if (x & 0xF0 != 0x10) { // ID code for TSL2561
+    return false;
+  }
+  _tsl2561Initialised = true;
+
+  /* Set default integration time and gain */
+  setIntegrationTime(_tsl2561IntegrationTime);
+  setGain(_tsl2561Gain);
+
+  /* Note: by default, the device is in power down mode on bootup */
+  disable();
+
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Enables or disables the auto-gain settings when reading
+            data from the sensor
+    @param enable Set to true to enable, False to disable
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::enableAutoRange(bool enable)
+{
+   _tsl2561AutoGain = enable ? true : false;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sets the integration time for the TSL2561. Higher time means
+                more light captured (better for low light conditions) but will
+		take longer to run readings.
+    @param time The amount of time we'd like to add up values
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::setIntegrationTime(tsl2561IntegrationTime_t time)
+{
+  if (!_tsl2561Initialised) begin();
+
+  /* Enable the device by setting the control bit to 0x03 */
+  enable();
+
+  /* Update the timing register */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, time | _tsl2561Gain);
+
+  /* Update value placeholders */
+  _tsl2561IntegrationTime = time;
+
+  /* Turn the device off to save power */
+  disable();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Adjusts the gain on the TSL2561 (adjusts the sensitivity to light)
+    @param gain The value we'd like to set the gain to
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::setGain(tsl2561Gain_t gain)
+{
+  if (!_tsl2561Initialised) begin();
+
+  /* Enable the device by setting the control bit to 0x03 */
+  enable();
+
+  /* Update the timing register */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _tsl2561IntegrationTime | gain);
+
+  /* Update value placeholders */
+  _tsl2561Gain = gain;
+
+  /* Turn the device off to save power */
+  disable();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the broadband (mixed lighting) and IR only values from
+            the TSL2561, adjusting gain if auto-gain is enabled
+    @param  broadband Pointer to a uint16_t we will fill with a sensor 
+                      reading from the IR+visible light diode.
+    @param  ir Pointer to a uint16_t we will fill with a sensor the 
+               IR-only light diode.
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::getLuminosity (uint16_t *broadband, uint16_t *ir)
+{
+  bool valid = false;
+
+  if (!_tsl2561Initialised) begin();
+
+  /* If Auto gain disabled get a single reading and continue */
+  if(!_tsl2561AutoGain)
+  {
+    getData (broadband, ir);
+    return;
+  }
+
+  /* Read data until we find a valid range */
+  bool _agcCheck = false;
+  do
+  {
+    uint16_t _b, _ir;
+    uint16_t _hi, _lo;
+    tsl2561IntegrationTime_t _it = _tsl2561IntegrationTime;
+
+    /* Get the hi/low threshold for the current integration time */
+    switch(_it)
+    {
+      case TSL2561_INTEGRATIONTIME_13MS:
+        _hi = TSL2561_AGC_THI_13MS;
+        _lo = TSL2561_AGC_TLO_13MS;
+        break;
+      case TSL2561_INTEGRATIONTIME_101MS:
+        _hi = TSL2561_AGC_THI_101MS;
+        _lo = TSL2561_AGC_TLO_101MS;
+        break;
+      default:
+        _hi = TSL2561_AGC_THI_402MS;
+        _lo = TSL2561_AGC_TLO_402MS;
+        break;
+    }
+
+    getData(&_b, &_ir);
+
+    /* Run an auto-gain check if we haven't already done so ... */
+    if (!_agcCheck)
+    {
+      if ((_b < _lo) && (_tsl2561Gain == TSL2561_GAIN_1X))
+      {
+        /* Increase the gain and try again */
+        setGain(TSL2561_GAIN_16X);
+        /* Drop the previous conversion results */
+        getData(&_b, &_ir);
+        /* Set a flag to indicate we've adjusted the gain */
+        _agcCheck = true;
+      }
+      else if ((_b > _hi) && (_tsl2561Gain == TSL2561_GAIN_16X))
+      {
+        /* Drop gain to 1x and try again */
+        setGain(TSL2561_GAIN_1X);
+        /* Drop the previous conversion results */
+        getData(&_b, &_ir);
+        /* Set a flag to indicate we've adjusted the gain */
+        _agcCheck = true;
+      }
+      else
+      {
+        /* Nothing to look at here, keep moving ....
+           Reading is either valid, or we're already at the chips limits */
+        *broadband = _b;
+        *ir = _ir;
+        valid = true;
+      }
+    }
+    else
+    {
+      /* If we've already adjusted the gain once, just return the new results.
+         This avoids endless loops where a value is at one extreme pre-gain,
+         and the the other extreme post-gain */
+      *broadband = _b;
+      *ir = _ir;
+      valid = true;
+    }
+  } while (!valid);
+}
+
+
+
+/**************************************************************************/
+/*!
+    Enables the device
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::enable(void)
+{
+  /* Enable the device by setting the control bit to 0x03 */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
+}
+
+/**************************************************************************/
+/*!
+    Disables the device (putting it in lower power sleep mode)
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::disable(void)
+{
+  /* Turn the device off to save power */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
+}
+
+/**************************************************************************/
+/*!
+    Private function to read luminosity on both channels
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::getData (uint16_t *broadband, uint16_t *ir)
+{
+  /* Enable the device by setting the control bit to 0x03 */
+  enable();
+
+  /* Wait x ms for ADC to complete */
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      delay(TSL2561_DELAY_INTTIME_13MS);  // KTOWN: Was 14ms
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      delay(TSL2561_DELAY_INTTIME_101MS); // KTOWN: Was 102ms
+      break;
+    default:
+      delay(TSL2561_DELAY_INTTIME_402MS); // KTOWN: Was 403ms
+      break;
+  }
+
+  /* Reads a two byte value from channel 0 (visible + infrared) */
+  *broadband = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
+
+  /* Reads a two byte value from channel 1 (infrared) */
+  *ir = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
+
+  /* Turn the device off to save power */
+  disable();
+}
+
+
+/**************************************************************************/
+/*!
+    @brief  Converts the raw sensor values to the standard SI lux equivalent.
+    @param  broadband The 16-bit sensor reading from the IR+visible light diode.
+    @param  ir The 16-bit sensor reading from the IR-only light diode.
+    @returns The integer Lux value we calcuated. 
+             Returns 0 if the sensor is saturated and the values are 
+             unreliable, or 65536 if the sensor is saturated.
+*/
+/**************************************************************************/
+/**************************************************************************/
+/*!
+    
+    Returns 
+*/
+/**************************************************************************/
+uint32_t Adafruit_TSL2561_Unified::calculateLux(uint16_t broadband, uint16_t ir)
+{
+  unsigned long chScale;
+  unsigned long channel1;
+  unsigned long channel0;
+
+  /* Make sure the sensor isn't saturated! */
+  uint16_t clipThreshold;
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      clipThreshold = TSL2561_CLIPPING_13MS;
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      clipThreshold = TSL2561_CLIPPING_101MS;
+      break;
+    default:
+      clipThreshold = TSL2561_CLIPPING_402MS;
+      break;
+  }
+
+  /* Return 65536 lux if the sensor is saturated */
+  if ((broadband > clipThreshold) || (ir > clipThreshold))
+  {
+    return 65536;
+  }
+
+  /* Get the correct scale depending on the intergration time */
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      chScale = TSL2561_LUX_CHSCALE_TINT0;
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      chScale = TSL2561_LUX_CHSCALE_TINT1;
+      break;
+    default: /* No scaling ... integration time = 402ms */
+      chScale = (1 << TSL2561_LUX_CHSCALE);
+      break;
+  }
+
+  /* Scale for gain (1x or 16x) */
+  if (!_tsl2561Gain) chScale = chScale << 4;
+
+  /* Scale the channel values */
+  channel0 = (broadband * chScale) >> TSL2561_LUX_CHSCALE;
+  channel1 = (ir * chScale) >> TSL2561_LUX_CHSCALE;
+
+  /* Find the ratio of the channel values (Channel1/Channel0) */
+  unsigned long ratio1 = 0;
+  if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
+
+  /* round the ratio value */
+  unsigned long ratio = (ratio1 + 1) >> 1;
+
+  unsigned int b, m;
+
+#ifdef TSL2561_PACKAGE_CS
+  if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
+    {b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
+  else if (ratio <= TSL2561_LUX_K2C)
+    {b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
+  else if (ratio <= TSL2561_LUX_K3C)
+    {b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
+  else if (ratio <= TSL2561_LUX_K4C)
+    {b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
+  else if (ratio <= TSL2561_LUX_K5C)
+    {b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
+  else if (ratio <= TSL2561_LUX_K6C)
+    {b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
+  else if (ratio <= TSL2561_LUX_K7C)
+    {b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
+  else if (ratio > TSL2561_LUX_K8C)
+    {b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
+#else
+  if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
+    {b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
+  else if (ratio <= TSL2561_LUX_K2T)
+    {b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
+  else if (ratio <= TSL2561_LUX_K3T)
+    {b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
+  else if (ratio <= TSL2561_LUX_K4T)
+    {b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
+  else if (ratio <= TSL2561_LUX_K5T)
+    {b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
+  else if (ratio <= TSL2561_LUX_K6T)
+    {b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
+  else if (ratio <= TSL2561_LUX_K7T)
+    {b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
+  else if (ratio > TSL2561_LUX_K8T)
+    {b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
+#endif
+
+  unsigned long temp;
+  temp = ((channel0 * b) - (channel1 * m));
+
+  /* Do not allow negative lux value */
+  if (temp < 0) temp = 0;
+
+  /* Round lsb (2^(LUX_SCALE-1)) */
+  temp += (1 << (TSL2561_LUX_LUXSCALE-1));
+
+  /* Strip off fractional portion */
+  uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
+
+  /* Signal I2C had no errors */
+  return lux;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the most recent sensor event
+    @param  event Pointer to a sensor_event_t type that will be filled 
+                  with the lux value, timestamp, data type and sensor ID.
+    @returns True if sensor reading is between 0 and 65535 lux, 
+             false if sensor is saturated
+*/
+/**************************************************************************/
+bool Adafruit_TSL2561_Unified::getEvent(sensors_event_t *event)
+{
+  uint16_t broadband, ir;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _tsl2561SensorID;
+  event->type      = SENSOR_TYPE_LIGHT;
+  event->timestamp = millis();
+
+  /* Calculate the actual lux value */
+  getLuminosity(&broadband, &ir);
+  event->light = calculateLux(broadband, ir);
+
+  if (event->light == 65536) {
+    return false;
+  }
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the sensor_t data
+    @param  sensor A pointer to a sensor_t structure that we will fill with
+                   details about the TSL2561 and its capabilities
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::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, "TSL2561", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _tsl2561SensorID;
+  sensor->type        = SENSOR_TYPE_LIGHT;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 17000.0;  /* Based on trial and error ... confirm! */
+  sensor->min_value   = 1.0;
+  sensor->resolution  = 1.0;
+}
+
+
+
+/*========================================================================*/
+/*                          PRIVATE FUNCTIONS                             */
+/*========================================================================*/
+
+/**************************************************************************/
+/*!
+    @brief  Writes a register and an 8 bit value over I2C
+    @param  reg I2C register to write the value to
+    @param  value The 8-bit value we're writing to the register
+*/
+/**************************************************************************/
+void Adafruit_TSL2561_Unified::write8 (uint8_t reg, uint8_t value)
+{
+  _i2c->beginTransmission(_addr);
+  _i2c->write(reg);
+  _i2c->write(value);
+  _i2c->endTransmission();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an 8 bit value over I2C
+    @param  reg I2C register to read from
+    @returns 8-bit value containing single byte data read
+*/
+/**************************************************************************/
+uint8_t Adafruit_TSL2561_Unified::read8(uint8_t reg)
+{
+  _i2c->beginTransmission(_addr);
+  _i2c->write(reg);
+  _i2c->endTransmission();
+
+  _i2c->requestFrom(_addr, 1);
+  return _i2c-> read();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+    @param  reg I2C register to read from
+    @returns 16-bit value containing 2-byte data read
+*/
+/**************************************************************************/
+uint16_t Adafruit_TSL2561_Unified::read16(uint8_t reg)
+{
+  uint16_t x, t;
+
+  _i2c->beginTransmission(_addr);
+  _i2c->write(reg);
+  _i2c->endTransmission();
+
+  _i2c->requestFrom(_addr, 2);
+  t = _i2c->read();
+  x = _i2c->read();
+  x <<= 8;
+  x |= t;
+  return x;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Original/Adafruit_TSL2561_U_h.txt	Fri Sep 21 22:57:07 2018 +0000
@@ -0,0 +1,203 @@
+/*!
+ * @file Adafruit_TSL2561_U.h
+ *
+ * This is part of Adafruit's FXOS8700 driver for the Arduino platform.  It is
+ * designed specifically to work with the Adafruit FXOS8700 breakout:
+ * https://www.adafruit.com/products/3463
+ *
+ * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
+ * to interface with the breakout.
+ *
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
+ *
+ * BSD license, all text here must be included in any redistribution.
+ *
+ */
+
+#ifndef ADAFRUIT_TSL2561_H_
+#define ADAFRUIT_TSL2561_H_
+
+#include <Arduino.h>
+#include <Adafruit_Sensor.h>
+#include <Wire.h>
+
+#define TSL2561_VISIBLE 2                   ///< channel 0 - channel 1
+#define TSL2561_INFRARED 1                  ///< channel 1
+#define TSL2561_FULLSPECTRUM 0              ///< channel 0
+
+// I2C address options
+#define TSL2561_ADDR_LOW          (0x29)    ///< Default address (pin pulled low)
+#define TSL2561_ADDR_FLOAT        (0x39)    ///< Default address (pin left floating)
+#define TSL2561_ADDR_HIGH         (0x49)    ///< Default address (pin pulled high)
+
+// Lux calculations differ slightly for CS package
+//#define TSL2561_PACKAGE_CS                ///< Chip scale package     
+#define TSL2561_PACKAGE_T_FN_CL             ///< Dual Flat No-Lead package
+
+#define TSL2561_COMMAND_BIT       (0x80)    ///< Must be 1
+#define TSL2561_CLEAR_BIT         (0x40)    ///< Clears any pending interrupt (write 1 to clear)
+#define TSL2561_WORD_BIT          (0x20)    ///< 1 = read/write word (rather than byte)
+#define TSL2561_BLOCK_BIT         (0x10)    ///< 1 = using block read/write
+
+#define TSL2561_CONTROL_POWERON   (0x03)    ///< Control register setting to turn on
+#define TSL2561_CONTROL_POWEROFF  (0x00)    ///< Control register setting to turn off
+
+#define TSL2561_LUX_LUXSCALE      (14)      ///< Scale by 2^14
+#define TSL2561_LUX_RATIOSCALE    (9)       ///< Scale ratio by 2^9
+#define TSL2561_LUX_CHSCALE       (10)      ///< Scale channel values by 2^10
+#define TSL2561_LUX_CHSCALE_TINT0 (0x7517)  ///< 322/11 * 2^TSL2561_LUX_CHSCALE
+#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7)  ///< 322/81 * 2^TSL2561_LUX_CHSCALE
+
+// T, FN and CL package values
+#define TSL2561_LUX_K1T           (0x0040)  ///< 0.125 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1T           (0x01f2)  ///< 0.0304 * 2^LUX_SCALE
+#define TSL2561_LUX_M1T           (0x01be)  ///< 0.0272 * 2^LUX_SCALE
+#define TSL2561_LUX_K2T           (0x0080)  ///< 0.250 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2T           (0x0214)  ///< 0.0325 * 2^LUX_SCALE
+#define TSL2561_LUX_M2T           (0x02d1)  ///< 0.0440 * 2^LUX_SCALE
+#define TSL2561_LUX_K3T           (0x00c0)  ///< 0.375 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3T           (0x023f)  ///< 0.0351 * 2^LUX_SCALE
+#define TSL2561_LUX_M3T           (0x037b)  ///< 0.0544 * 2^LUX_SCALE
+#define TSL2561_LUX_K4T           (0x0100)  ///< 0.50 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4T           (0x0270)  ///< 0.0381 * 2^LUX_SCALE
+#define TSL2561_LUX_M4T           (0x03fe)  ///< 0.0624 * 2^LUX_SCALE
+#define TSL2561_LUX_K5T           (0x0138)  ///< 0.61 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5T           (0x016f)  ///< 0.0224 * 2^LUX_SCALE
+#define TSL2561_LUX_M5T           (0x01fc)  ///< 0.0310 * 2^LUX_SCALE
+#define TSL2561_LUX_K6T           (0x019a)  ///< 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6T           (0x00d2)  ///< 0.0128 * 2^LUX_SCALE
+#define TSL2561_LUX_M6T           (0x00fb)  ///< 0.0153 * 2^LUX_SCALE
+#define TSL2561_LUX_K7T           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7T           (0x0018)  ///< 0.00146 * 2^LUX_SCALE
+#define TSL2561_LUX_M7T           (0x0012)  ///< 0.00112 * 2^LUX_SCALE
+#define TSL2561_LUX_K8T           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8T           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8T           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+
+// CS package values
+#define TSL2561_LUX_K1C           (0x0043)  ///< 0.130 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1C           (0x0204)  ///< 0.0315 * 2^LUX_SCALE
+#define TSL2561_LUX_M1C           (0x01ad)  ///< 0.0262 * 2^LUX_SCALE
+#define TSL2561_LUX_K2C           (0x0085)  ///< 0.260 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2C           (0x0228)  ///< 0.0337 * 2^LUX_SCALE
+#define TSL2561_LUX_M2C           (0x02c1)  ///< 0.0430 * 2^LUX_SCALE
+#define TSL2561_LUX_K3C           (0x00c8)  ///< 0.390 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3C           (0x0253)  ///< 0.0363 * 2^LUX_SCALE
+#define TSL2561_LUX_M3C           (0x0363)  ///< 0.0529 * 2^LUX_SCALE
+#define TSL2561_LUX_K4C           (0x010a)  ///< 0.520 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4C           (0x0282)  ///< 0.0392 * 2^LUX_SCALE
+#define TSL2561_LUX_M4C           (0x03df)  ///< 0.0605 * 2^LUX_SCALE
+#define TSL2561_LUX_K5C           (0x014d)  ///< 0.65 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5C           (0x0177)  ///< 0.0229 * 2^LUX_SCALE
+#define TSL2561_LUX_M5C           (0x01dd)  ///< 0.0291 * 2^LUX_SCALE
+#define TSL2561_LUX_K6C           (0x019a)  ///< 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6C           (0x0101)  ///< 0.0157 * 2^LUX_SCALE
+#define TSL2561_LUX_M6C           (0x0127)  ///< 0.0180 * 2^LUX_SCALE
+#define TSL2561_LUX_K7C           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7C           (0x0037)  ///< 0.00338 * 2^LUX_SCALE
+#define TSL2561_LUX_M7C           (0x002b)  ///< 0.00260 * 2^LUX_SCALE
+#define TSL2561_LUX_K8C           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8C           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8C           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+
+// Auto-gain thresholds
+#define TSL2561_AGC_THI_13MS      (4850)    ///< Max value at Ti 13ms = 5047
+#define TSL2561_AGC_TLO_13MS      (100)     ///< Min value at Ti 13ms = 100
+#define TSL2561_AGC_THI_101MS     (36000)   ///< Max value at Ti 101ms = 37177
+#define TSL2561_AGC_TLO_101MS     (200)     ///< Min value at Ti 101ms = 200
+#define TSL2561_AGC_THI_402MS     (63000)   ///< Max value at Ti 402ms = 65535
+#define TSL2561_AGC_TLO_402MS     (500)     ///< Min value at Ti 402ms = 500
+
+// Clipping thresholds
+#define TSL2561_CLIPPING_13MS     (4900)    ///< # Counts that trigger a change in gain/integration
+#define TSL2561_CLIPPING_101MS    (37000)   ///< # Counts that trigger a change in gain/integration
+#define TSL2561_CLIPPING_402MS    (65000)   ///< # Counts that trigger a change in gain/integration
+
+// Delay for integration times
+#define TSL2561_DELAY_INTTIME_13MS    (15)    ///< Wait 15ms for 13ms integration
+#define TSL2561_DELAY_INTTIME_101MS   (120)   ///< Wait 120ms for 101ms integration
+#define TSL2561_DELAY_INTTIME_402MS   (450)   ///< Wait 450ms for 402ms integration
+
+/** TSL2561 I2C Registers */
+enum
+{
+  TSL2561_REGISTER_CONTROL          = 0x00, // Control/power register 
+  TSL2561_REGISTER_TIMING           = 0x01, // Set integration time register
+  TSL2561_REGISTER_THRESHHOLDL_LOW  = 0x02, // Interrupt low threshold low-byte
+  TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, // Interrupt low threshold high-byte
+  TSL2561_REGISTER_THRESHHOLDH_LOW  = 0x04, // Interrupt high threshold low-byte
+  TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, // Interrupt high threshold high-byte
+  TSL2561_REGISTER_INTERRUPT        = 0x06, // Interrupt settings
+  TSL2561_REGISTER_CRC              = 0x08, // Factory use only
+  TSL2561_REGISTER_ID               = 0x0A, // TSL2561 identification setting
+  TSL2561_REGISTER_CHAN0_LOW        = 0x0C, // Light data channel 0, low byte
+  TSL2561_REGISTER_CHAN0_HIGH       = 0x0D, // Light data channel 0, high byte
+  TSL2561_REGISTER_CHAN1_LOW        = 0x0E, // Light data channel 1, low byte
+  TSL2561_REGISTER_CHAN1_HIGH       = 0x0F  // Light data channel 1, high byte
+};
+
+/** Three options for how long to integrate readings for */
+typedef enum
+{
+  TSL2561_INTEGRATIONTIME_13MS      = 0x00,    // 13.7ms
+  TSL2561_INTEGRATIONTIME_101MS     = 0x01,    // 101ms
+  TSL2561_INTEGRATIONTIME_402MS     = 0x02     // 402ms
+}
+tsl2561IntegrationTime_t;
+
+/** TSL2561 offers 2 gain settings */
+typedef enum
+{
+  TSL2561_GAIN_1X                   = 0x00,    // No gain
+  TSL2561_GAIN_16X                  = 0x10,    // 16x gain
+}
+tsl2561Gain_t;
+
+
+
+/**************************************************************************/
+/*! 
+    @brief  Class that stores state and functions for interacting with TSL2561 Light Sensor
+*/
+/**************************************************************************/
+class Adafruit_TSL2561_Unified : public Adafruit_Sensor {
+ public:
+  Adafruit_TSL2561_Unified(uint8_t addr, int32_t sensorID = -1);
+  boolean begin(void);
+  boolean begin(TwoWire *theWire);
+  boolean init();
+  
+  /* TSL2561 Functions */
+  void enableAutoRange(bool enable);
+  void setIntegrationTime(tsl2561IntegrationTime_t time);
+  void setGain(tsl2561Gain_t gain);
+  void getLuminosity (uint16_t *broadband, uint16_t *ir);
+  uint32_t calculateLux(uint16_t broadband, uint16_t ir);
+  
+  /* Unified Sensor API Functions */  
+  bool getEvent(sensors_event_t*);
+  void getSensor(sensor_t*);
+
+ private:
+  TwoWire *_i2c;
+ 
+  int8_t _addr;
+  boolean _tsl2561Initialised;
+  boolean _tsl2561AutoGain;
+  tsl2561IntegrationTime_t _tsl2561IntegrationTime;
+  tsl2561Gain_t _tsl2561Gain;
+  int32_t _tsl2561SensorID;
+  
+  void     enable (void);
+  void     disable (void);
+  void     write8 (uint8_t reg, uint8_t value);
+  uint8_t  read8 (uint8_t reg);
+  uint16_t read16 (uint8_t reg);
+  void     getData (uint16_t *broadband, uint16_t *ir);
+};
+
+#endif // ADAFRUIT_TSL2561_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Original/sensorapi_ino.txt	Fri Sep 21 22:57:07 2018 +0000
@@ -0,0 +1,140 @@
+#include <Wire.h>
+#include <Adafruit_Sensor.h>
+#include <Adafruit_TSL2561_U.h>
+
+/* This driver uses the Adafruit unified sensor library (Adafruit_Sensor),
+   which provides a common 'type' for sensor data and some helper functions.
+   
+   To use this driver you will also need to download the Adafruit_Sensor
+   library and include it in your libraries folder.
+
+   You should also assign a unique ID to this sensor for use with
+   the Adafruit Sensor API so that you can identify this particular
+   sensor in any data logs, etc.  To assign a unique ID, simply
+   provide an appropriate value in the constructor below (12345
+   is used by default in this example).
+   
+   Connections
+   ===========
+   Connect SCL to I2C SCL Clock
+   Connect SDA to I2C SDA Data
+   Connect VDD to 3.3V or 5V (whatever your logic level is)
+   Connect GROUND to common ground
+
+   I2C Address
+   ===========
+   The address will be different depending on whether you leave
+   the ADDR pin floating (addr 0x39), or tie it to ground or vcc. 
+   The default addess is 0x39, which assumes the ADDR pin is floating
+   (not connected to anything).  If you set the ADDR pin high
+   or low, use TSL2561_ADDR_HIGH (0x49) or TSL2561_ADDR_LOW
+   (0x29) respectively.
+    
+   History
+   =======
+   2013/JAN/31  - First version (KTOWN)
+*/
+   
+Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
+
+/**************************************************************************/
+/*
+    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 TSL2561
+*/
+/**************************************************************************/
+void configureSensor(void)
+{
+  /* You can also manually set the gain or enable auto-gain support */
+  // tsl.setGain(TSL2561_GAIN_1X);      /* No gain ... use in bright light to avoid sensor saturation */
+  // tsl.setGain(TSL2561_GAIN_16X);     /* 16x gain ... use in low light to boost sensitivity */
+  tsl.enableAutoRange(true);            /* Auto-gain ... switches automatically between 1x and 16x */
+  
+  /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */
+  tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS);      /* fast but low resolution */
+  // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);  /* medium resolution and speed   */
+  // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);  /* 16-bit data but slowest conversions */
+
+  /* Update these values depending on what you've set above! */  
+  Serial.println("------------------------------------");
+  Serial.print  ("Gain:         "); Serial.println("Auto");
+  Serial.print  ("Timing:       "); Serial.println("13 ms");
+  Serial.println("------------------------------------");
+}
+
+/**************************************************************************/
+/*
+    Arduino setup function (automatically called at startup)
+*/
+/**************************************************************************/
+void setup(void) 
+{
+  Serial.begin(9600);
+  Serial.println("Light Sensor Test"); Serial.println("");
+  
+  /* Initialise the sensor */
+  //use tsl.begin() to default to Wire, 
+  //tsl.begin(&Wire2) directs api to use Wire2, etc.
+  if(!tsl.begin())
+  {
+    /* There was a problem detecting the TSL2561 ... check your connections */
+    Serial.print("Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!");
+    while(1);
+  }
+  
+  /* Display some basic information on this sensor */
+  displaySensorDetails();
+  
+  /* Setup the sensor gain and integration time */
+  configureSensor();
+  
+  /* We're ready to go! */
+  Serial.println("");
+}
+
+/**************************************************************************/
+/*
+    Arduino loop function, called once 'setup' is complete (your own code
+    should go here)
+*/
+/**************************************************************************/
+void loop(void) 
+{  
+  /* 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");
+  }
+  delay(250);
+}
--- a/TSL2561.cpp	Tue Feb 20 10:52:41 2018 +0000
+++ b/TSL2561.cpp	Fri Sep 21 22:57:07 2018 +0000
@@ -1,47 +1,169 @@
-/*
- * mbed library program
- *  Luminosity sensor -- LIGHT-TO-DIGITAL CONVERTER (light intensity to a digital signal output)
- *  TSL2561 by Texas Advanced Optoelectronic Solutions Inc.
+/*!
+ * @file Adafruit_TSL2561_U.cpp
+ *
+ * @mainpage Adafruit TSL2561 Light/Lux sensor driver
+ *
+ * @section intro_sec Introduction
+ *
+ * This is the documentation for Adafruit's TSL2561 driver for the
+ * Arduino platform.  It is designed specifically to work with the
+ * Adafruit TSL2561 breakout: http://www.adafruit.com/products/439
+ *
+ * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
+ * to interface with the breakout.
+ *
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * @section dependencies Dependencies
+ *
+ * This library depends on
+ *  <a href="https://github.com/adafruit/Adafruit_Sensor">
+ * Adafruit_Sensor</a> being present on your system. Please make sure you have
+ * installed the latest version before using this library.
+ *
+ * @section author Author
+ *
+ * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
  *
- * Copyright (c) 2015,'17,'18 Kenji Arai / JH1PJL
- *  http://www.page.sannet.ne.jp/kenjia/index.html
- *  http://mbed.org/users/kenjiArai/
- *      Created: Feburary   21st, 2015
- *      Revised: August     23rd, 2017
- *      Revised: Feburary   20th, 2018   bug fix -> read_ID() & who_am_i()
- *                                       Thanks PARK JAICHANG
- */
+ * @section license License
+ *
+ * BSD license, all text here must be included in any redistribution.
+ *
+ *   @section  HISTORY
+ *
+ *   v2.0 - Rewrote driver for Adafruit_Sensor and Auto-Gain support, and
+ *          added lux clipping check (returns 0 lux on sensor saturation)
+ *   v1.0 - First release (previously TSL2561)
+*/
+/**************************************************************************/
+
+//------- Modified by ----------------------------------------------------------
+//  Kenji Arai / JH1PJL
+//  http://www.page.sannet.ne.jp/kenjia/index.html
+//  http://mbed.org/users/kenjiArai/
+//      Created: Feburary   21st, 2015
+//      Revised: August     23rd, 2017
+//      Revised: Feburary   20th, 2018   bug fix -> read_ID() & who_am_i()
+//                                       Thanks PARK JAICHANG
+//      Revised: March      31st, 2018   Added "Auto Range mode"
+//                                       Use Adafruit library
+//
+// Original information     https://www.adafruit.com/product/439
+// Original source files    https://github.com/adafruit/TSL2561-Arduino-Library
+//                          https://github.com/adafruit/Adafruit_TSL2561
+// Change for Mbed platform
+//    modified -> all related files
+//------------------------------------------------------------------------------
 
 #include "TSL2561.h"
 
+// T, FN and CL package values
+#define TSL2561_LUX_K1T           (0x0040)  ///< 0.125 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1T           (0x01f2)  ///< 0.0304 * 2^LUX_SCALE
+#define TSL2561_LUX_M1T           (0x01be)  ///< 0.0272 * 2^LUX_SCALE
+#define TSL2561_LUX_K2T           (0x0080)  ///< 0.250 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2T           (0x0214)  ///< 0.0325 * 2^LUX_SCALE
+#define TSL2561_LUX_M2T           (0x02d1)  ///< 0.0440 * 2^LUX_SCALE
+#define TSL2561_LUX_K3T           (0x00c0)  ///< 0.375 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3T           (0x023f)  ///< 0.0351 * 2^LUX_SCALE
+#define TSL2561_LUX_M3T           (0x037b)  ///< 0.0544 * 2^LUX_SCALE
+#define TSL2561_LUX_K4T           (0x0100)  ///< 0.50 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4T           (0x0270)  ///< 0.0381 * 2^LUX_SCALE
+#define TSL2561_LUX_M4T           (0x03fe)  ///< 0.0624 * 2^LUX_SCALE
+#define TSL2561_LUX_K5T           (0x0138)  ///< 0.61 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5T           (0x016f)  ///< 0.0224 * 2^LUX_SCALE
+#define TSL2561_LUX_M5T           (0x01fc)  ///< 0.0310 * 2^LUX_SCALE
+#define TSL2561_LUX_K6T           (0x019a)  ///< 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6T           (0x00d2)  ///< 0.0128 * 2^LUX_SCALE
+#define TSL2561_LUX_M6T           (0x00fb)  ///< 0.0153 * 2^LUX_SCALE
+#define TSL2561_LUX_K7T           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7T           (0x0018)  ///< 0.00146 * 2^LUX_SCALE
+#define TSL2561_LUX_M7T           (0x0012)  ///< 0.00112 * 2^LUX_SCALE
+#define TSL2561_LUX_K8T           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8T           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8T           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+
+// CS package values
+#define TSL2561_LUX_K1C           (0x0043)  ///< 0.130 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1C           (0x0204)  ///< 0.0315 * 2^LUX_SCALE
+#define TSL2561_LUX_M1C           (0x01ad)  ///< 0.0262 * 2^LUX_SCALE
+#define TSL2561_LUX_K2C           (0x0085)  ///< 0.260 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2C           (0x0228)  ///< 0.0337 * 2^LUX_SCALE
+#define TSL2561_LUX_M2C           (0x02c1)  ///< 0.0430 * 2^LUX_SCALE
+#define TSL2561_LUX_K3C           (0x00c8)  ///< 0.390 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3C           (0x0253)  ///< 0.0363 * 2^LUX_SCALE
+#define TSL2561_LUX_M3C           (0x0363)  ///< 0.0529 * 2^LUX_SCALE
+#define TSL2561_LUX_K4C           (0x010a)  ///< 0.520 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4C           (0x0282)  ///< 0.0392 * 2^LUX_SCALE
+#define TSL2561_LUX_M4C           (0x03df)  ///< 0.0605 * 2^LUX_SCALE
+#define TSL2561_LUX_K5C           (0x014d)  ///< 0.65 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5C           (0x0177)  ///< 0.0229 * 2^LUX_SCALE
+#define TSL2561_LUX_M5C           (0x01dd)  ///< 0.0291 * 2^LUX_SCALE
+#define TSL2561_LUX_K6C           (0x019a)  ///< 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6C           (0x0101)  ///< 0.0157 * 2^LUX_SCALE
+#define TSL2561_LUX_M6C           (0x0127)  ///< 0.0180 * 2^LUX_SCALE
+#define TSL2561_LUX_K7C           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7C           (0x0037)  ///< 0.00338 * 2^LUX_SCALE
+#define TSL2561_LUX_M7C           (0x002b)  ///< 0.00260 * 2^LUX_SCALE
+#define TSL2561_LUX_K8C           (0x029a)  ///< 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8C           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8C           (0x0000)  ///< 0.000 * 2^LUX_SCALE
+
+// Auto-gain thresholds
+#define TSL2561_AGC_THI_13MS      (4850)    ///< Max value at Ti 13ms = 5047
+#define TSL2561_AGC_TLO_13MS      (100)     ///< Min value at Ti 13ms = 100
+#define TSL2561_AGC_THI_101MS     (36000)   ///< Max value at Ti 101ms = 37177
+#define TSL2561_AGC_TLO_101MS     (200)     ///< Min value at Ti 101ms = 200
+#define TSL2561_AGC_THI_402MS     (63000)   ///< Max value at Ti 402ms = 65535
+#define TSL2561_AGC_TLO_402MS     (500)     ///< Min value at Ti 402ms = 500
+
+// Clipping thresholds  ///< # Counts that trigger a change in gain/integration
+#define TSL2561_CLIPPING_13MS     (4900)
+#define TSL2561_CLIPPING_101MS    (37000)
+#define TSL2561_CLIPPING_402MS    (65000)
+
+// Delay for integration times
+#define TSL2561_DELAY_INTTIME_13MS  (15)   ///< Wait 15ms for 13ms integration
+#define TSL2561_DELAY_INTTIME_101MS (120)  ///< Wait 120ms for 101ms integration
+#define TSL2561_DELAY_INTTIME_402MS (450)  ///< Wait 450ms for 402ms integration
+
+/*========================================================================*/
+/*                            CONSTRUCTORS                                */
+/*========================================================================*/
+
 TSL2561::TSL2561 (PinName p_sda, PinName p_scl)
- : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
+    : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
 {
-    TSL2561_addr = TSL2561_ADDRESS_GND;
+    _addr = TSL2561_ADDR_LOW;
     init();
 }
 
 TSL2561::TSL2561 (PinName p_sda, PinName p_scl, uint8_t addr)
- : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
+    : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
 {
-    TSL2561_addr = addr;
+    _addr = addr;
     init();
 }
 
 TSL2561::TSL2561 (I2C& p_i2c)
- : _i2c(p_i2c)
+    : _i2c(p_i2c)
 {
-    TSL2561_addr = TSL2561_ADDRESS_GND;
+    _addr = TSL2561_ADDR_LOW;
     init();
 }
 
 TSL2561::TSL2561 (I2C& p_i2c, uint8_t addr)
- : _i2c(p_i2c)
+    : _i2c(p_i2c)
 {
-    TSL2561_addr = addr;
+    _addr = addr;
     init();
 }
 
+/*========================================================================*/
+/*                           PUBLIC FUNCTIONS                             */
+/*========================================================================*/
 /////////////// Read Lux from sensor //////////////////////
 /*
 For 0    < CH1/CH0 < 0.50 Lux = 0.0304  x CH0-0.062  x CH0 x ((CH1/CH0)1.4)
@@ -56,25 +178,28 @@
     double ratio;
     double dlux;
 
-    dt[0] = CMD_MULTI + TSL2561_DATA0LOW;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
-    _i2c.read(TSL2561_addr, (char *)dt, 2, false);
-    ch0 = dt[1] << 8 | dt[0];
-    dt[0] = CMD_MULTI + TSL2561_DATA1LOW;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
-    _i2c.read(TSL2561_addr, (char *)dt, 2, false);
-    ch1 = dt[1] << 8 | dt[0];
-    if (ch0 == 0xFFFF) {
-        return 2500.0;
-    }
+    _TSL2561AutoGain = false;
+    _TSL2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
+    _TSL2561Gain = TSL2561_GAIN_1X;
+    /* Set default integration time and gain */
+    setIntegrationTime(_TSL2561IntegrationTime);
+    setGain(_TSL2561Gain);
+    uint16_t x0, x1;
+    getLuminosity(&x0, &x1);
+    ch0 = x0;
+    ch1 = x1;
+    //printf("ch0 = %d, ch1 = %d\r\n", ch0, ch1);
+    //printf("Integ. Time = %d, Gain %d\r\n",
+    //     _TSL2561IntegrationTime, _TSL2561Gain);
     lux0 = (double)ch0;
     lux1 = (double)ch1;
     ratio = lux1 / lux0;
     read_timing_reg();
-    lux0 *= (402.0/integ_time);
-    lux1 *= (402.0/integ_time);
+    lux0 *= (402.0/(double)integ_time);
+    lux1 *= (402.0/(double)integ_time);
     lux0 /= gain;
     lux1 /= gain;
+    //printf("Integ. Time = %f, Gain %d\r\n", integ_time, gain);
     if (ratio <= 0.5) {
         dlux = 0.03040 * lux0 - 0.06200 * lux0 * pow(ratio,1.4);
     } else if (ratio <= 0.61) {
@@ -86,54 +211,528 @@
     } else {
         dlux = 0;
     }
+    disable();
     return (float)dlux;
 }
 
-/////////////// Initialize ////////////////////////////////
-void TSL2561::init()
+float TSL2561::lux_auto(void)
+{
+    uint32_t data;
+
+    enableAutoRange(true);
+    getEvent(&data);
+    //printf("line:%d\r\n", __LINE__);
+    return (float)data;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initializes I2C connection and settings.
+    Attempts to determine if the sensor is contactable, then sets up a default
+    integration time and gain. Then powers down the chip.
+    @returns True if sensor is found and initialized, false otherwise.
+*/
+/**************************************************************************/
+bool TSL2561::init()
+{
+    _TSL2561Initialised = false;
+    _TSL2561AutoGain = false;
+    _TSL2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
+    _TSL2561Gain = TSL2561_GAIN_1X;
+
+    /* Make sure we're actually connected */
+    uint8_t x = read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_ID);
+    if (x & 0xF0 != 0x50) { // ID code for TSL2561
+        //printf("initialize error!\r\n");
+        return false;
+    }
+    //printf("ID=0x%02x\r\n", x);
+    _TSL2561Initialised = true;
+
+    /* Set default integration time and gain */
+    setIntegrationTime(_TSL2561IntegrationTime);
+    setGain(_TSL2561Gain);
+    read_timing_reg();
+
+    /* Note: by default, the device is in power down mode on bootup */
+    disable();
+
+    t.reset();
+    t.start();
+    //printf("Integ. Time = %d, Gain %d\r\n",
+    //         _TSL2561IntegrationTime, _TSL2561Gain);
+    //printf("initialize finished!\r\n");
+    x = read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING);
+    //printf("TIMING REG=0x%02x\r\n", x);
+    return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Enables or disables the auto-gain settings when reading
+            data from the sensor
+    @param enable Set to true to enable, False to disable
+*/
+/**************************************************************************/
+void TSL2561::enableAutoRange(bool enable)
+{
+    _TSL2561AutoGain = enable ? true : false;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sets the integration time for the TSL2561. Higher time means
+                more light captured (better for low light conditions) but will
+        take longer to run readings.
+    @param time The amount of time we'd like to add up values
+*/
+/**************************************************************************/
+void TSL2561::setIntegrationTime(TSL2561IntegrationTime_t time)
+{
+    /* Enable the device by setting the control bit to 0x03 */
+    enable();
+    /* Update the timing register */
+    write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, time | _TSL2561Gain);
+    /* Update value placeholders */
+    _TSL2561IntegrationTime = time;
+    /* Turn the device off to save power */
+    disable();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Adjusts the gain on the TSL2561 (adjusts the sensitivity to light)
+    @param gain The value we'd like to set the gain to
+*/
+/**************************************************************************/
+void TSL2561::setGain(TSL2561Gain_t gain)
+{
+    /* Enable the device by setting the control bit to 0x03 */
+    enable();
+    /* Update the timing register */
+    write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _TSL2561IntegrationTime | gain);
+    /* Update value placeholders */
+    _TSL2561Gain = gain;
+    /* Turn the device off to save power */
+    disable();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the broadband (mixed lighting) and IR only values from
+            the TSL2561, adjusting gain if auto-gain is enabled
+    @param  broadband Pointer to a uint16_t we will fill with a sensor
+                      reading from the IR+visible light diode.
+    @param  ir Pointer to a uint16_t we will fill with a sensor the
+               IR-only light diode.
+*/
+/**************************************************************************/
+void TSL2561::getLuminosity (uint16_t *broadband, uint16_t *ir)
+{
+    bool valid = false;
+
+    /* If Auto gain disabled get a single reading and continue */
+    if(!_TSL2561AutoGain) {
+        //printf("Get data without Auto gain\r\n");
+        getData (broadband, ir);
+        return;
+    }
+    //printf("Get data with Auto gain\r\n");
+    /* Read data until we find a valid range */
+    bool _agcCheck = false;
+    do {
+        uint16_t _b, _ir;
+        uint16_t _hi, _lo;
+        TSL2561IntegrationTime_t _it = _TSL2561IntegrationTime;
+
+        /* Get the hi/low threshold for the current integration time */
+        switch(_it) {
+            case TSL2561_INTEGRATIONTIME_13MS:
+                _hi = TSL2561_AGC_THI_13MS;
+                _lo = TSL2561_AGC_TLO_13MS;
+                break;
+            case TSL2561_INTEGRATIONTIME_101MS:
+                _hi = TSL2561_AGC_THI_101MS;
+                _lo = TSL2561_AGC_TLO_101MS;
+                break;
+            default:
+                _hi = TSL2561_AGC_THI_402MS;
+                _lo = TSL2561_AGC_TLO_402MS;
+                break;
+        }
+
+        getData(&_b, &_ir);
+
+        /* Run an auto-gain check if we haven't already done so ... */
+        if (!_agcCheck) {
+            if ((_b < _lo) && (_TSL2561Gain == TSL2561_GAIN_1X)) {
+                /* Increase the gain and try again */
+                setGain(TSL2561_GAIN_16X);
+                /* Drop the previous conversion results */
+                getData(&_b, &_ir);
+                /* Set a flag to indicate we've adjusted the gain */
+                _agcCheck = true;
+            } else if ((_b > _hi) && (_TSL2561Gain == TSL2561_GAIN_16X)) {
+                /* Drop gain to 1x and try again */
+                setGain(TSL2561_GAIN_1X);
+                /* Drop the previous conversion results */
+                getData(&_b, &_ir);
+                /* Set a flag to indicate we've adjusted the gain */
+                _agcCheck = true;
+            } else {
+                /* Nothing to look at here, keep moving ....
+                   Reading is either valid, or we're already at the chips limits */
+                *broadband = _b;
+                *ir = _ir;
+                valid = true;
+            }
+        } else {
+            /* If we've already adjusted the gain once, just return the new results.
+               This avoids endless loops where a value is at one extreme pre-gain,
+               and the the other extreme post-gain */
+            *broadband = _b;
+            *ir = _ir;
+            valid = true;
+        }
+    } while (!valid);
+}
+
+/**************************************************************************/
+/*!
+    Enables the device
+*/
+/**************************************************************************/
+void TSL2561::enable(void)
+{
+    /* Enable the device by setting the control bit to 0x03 */
+    write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
+}
+
+/**************************************************************************/
+/*!
+    Disables the device (putting it in lower power sleep mode)
+*/
+/**************************************************************************/
+void TSL2561::disable(void)
+{
+    /* Turn the device off to save power */
+    write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
+}
+
+/**************************************************************************/
+/*!
+    Private function to read luminosity on both channels
+*/
+/**************************************************************************/
+void TSL2561::getData (uint16_t *broadband, uint16_t *ir)
 {
-    _i2c.frequency(100000);
-    power_up();
-    set_timing_reg(TIMING_DEFAULT);
+    /* Enable the device by setting the control bit to 0x03 */
+    enable();
+
+    /* Wait x ms for ADC to complete */
+    switch (_TSL2561IntegrationTime) {
+        case TSL2561_INTEGRATIONTIME_13MS:
+            wait_ms(TSL2561_DELAY_INTTIME_13MS);
+            break;
+        case TSL2561_INTEGRATIONTIME_101MS:
+            wait_ms(TSL2561_DELAY_INTTIME_101MS);
+            break;
+        default:
+            wait_ms(TSL2561_DELAY_INTTIME_402MS);
+            break;
+    }
+
+    /* Reads a two byte value from channel 0 (visible + infrared) */
+    *broadband = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
+
+    /* Reads a two byte value from channel 1 (infrared) */
+    *ir = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
+
+    /* Turn the device off to save power */
+    disable();
 }
 
+/**************************************************************************/
+/*!
+    @brief  Converts the raw sensor values to the standard SI lux equivalent.
+    @param  broadband The 16-bit sensor reading from the IR+visible light diode.
+    @param  ir The 16-bit sensor reading from the IR-only light diode.
+    @returns The integer Lux value we calcuated.
+             Returns 0 if the sensor is saturated and the values are
+             unreliable, or 65536 if the sensor is saturated.
+*/
+/**************************************************************************/
+/**************************************************************************/
+/*!
+
+    Returns
+*/
+/**************************************************************************/
+uint32_t TSL2561::calculateLux(uint16_t broadband, uint16_t ir)
+{
+    unsigned long chScale;
+    unsigned long channel1;
+    unsigned long channel0;
+
+    //printf("line:%d\r\n", __LINE__);
+    /* Make sure the sensor isn't saturated! */
+    uint16_t clipThreshold;
+    //printf("_TSL2561IntegrationTime=%d\r\n", _TSL2561IntegrationTime);
+    switch (_TSL2561IntegrationTime) {
+        case TSL2561_INTEGRATIONTIME_13MS:
+            clipThreshold = TSL2561_CLIPPING_13MS;
+            chScale = TSL2561_LUX_CHSCALE_TINT0;
+            //printf("line:%d\r\n", __LINE__);
+            break;
+        case TSL2561_INTEGRATIONTIME_101MS:
+            clipThreshold = TSL2561_CLIPPING_101MS;
+            chScale = TSL2561_LUX_CHSCALE_TINT1;
+            break;
+        default:
+            clipThreshold = TSL2561_CLIPPING_402MS;
+            chScale = (1 << TSL2561_LUX_CHSCALE);
+            break;
+    }
+    //printf("clipThreshold=%d\r\n", clipThreshold);
+    /* Return 65536 lux if the sensor is saturated */
+    if ((broadband > clipThreshold) || (ir > clipThreshold)) {
+        //printf("line:%d\r\n", __LINE__);
+        return 65536;
+    }
+
+    //printf("line:%d\r\n", __LINE__);
+    //printf("chScale=%d\r\n", chScale);
+    /* Scale for gain (1x or 16x) */
+    if (!_TSL2561Gain) {
+        chScale = chScale << 4;
+    }
+    //printf("chScale=%d\r\n", chScale);
+    /* Scale the channel values */
+    channel0 = (broadband * chScale) >> TSL2561_LUX_CHSCALE;
+    channel1 = (ir * chScale) >> TSL2561_LUX_CHSCALE;
+    //printf("channel0=%d, channel1=%d\r\n", channel0, channel1);
+
+    /* Find the ratio of the channel values (Channel1/Channel0) */
+    unsigned long ratio1 = 0;
+    if (channel0 != 0) {
+        ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
+    }
+
+    /* round the ratio value */
+    long ratio = (ratio1 + 1) >> 1;
+    //printf("ratio1=%d, ratio=%d\r\n", ratio1, ratio);
+    unsigned int b, m;
+
+#ifdef TSL2561_PACKAGE_CS
+    //printf("line:%d\r\n", __LINE__);
+    if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {
+        b=TSL2561_LUX_B1C;
+        m=TSL2561_LUX_M1C;
+    } else if (ratio <= TSL2561_LUX_K2C) {
+        b=TSL2561_LUX_B2C;
+        m=TSL2561_LUX_M2C;
+    } else if (ratio <= TSL2561_LUX_K3C) {
+        b=TSL2561_LUX_B3C;
+        m=TSL2561_LUX_M3C;
+    } else if (ratio <= TSL2561_LUX_K4C) {
+        b=TSL2561_LUX_B4C;
+        m=TSL2561_LUX_M4C;
+    } else if (ratio <= TSL2561_LUX_K5C) {
+        b=TSL2561_LUX_B5C;
+        m=TSL2561_LUX_M5C;
+    } else if (ratio <= TSL2561_LUX_K6C) {
+        b=TSL2561_LUX_B6C;
+        m=TSL2561_LUX_M6C;
+    } else if (ratio <= TSL2561_LUX_K7C) {
+        b=TSL2561_LUX_B7C;
+        m=TSL2561_LUX_M7C;
+    } else if (ratio > TSL2561_LUX_K8C) {
+        b=TSL2561_LUX_B8C;
+        m=TSL2561_LUX_M8C;
+    }
+#else
+    //printf("line:%d\r\n", __LINE__);
+    if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) {
+        b=TSL2561_LUX_B1T;
+        m=TSL2561_LUX_M1T;
+    } else if (ratio <= TSL2561_LUX_K2T) {
+        b=TSL2561_LUX_B2T;
+        m=TSL2561_LUX_M2T;
+    } else if (ratio <= TSL2561_LUX_K3T) {
+        b=TSL2561_LUX_B3T;
+        m=TSL2561_LUX_M3T;
+    } else if (ratio <= TSL2561_LUX_K4T) {
+        b=TSL2561_LUX_B4T;
+        m=TSL2561_LUX_M4T;
+    } else if (ratio <= TSL2561_LUX_K5T) {
+        b=TSL2561_LUX_B5T;
+        m=TSL2561_LUX_M5T;
+    } else if (ratio <= TSL2561_LUX_K6T) {
+        b=TSL2561_LUX_B6T;
+        m=TSL2561_LUX_M6T;
+    } else if (ratio <= TSL2561_LUX_K7T) {
+        b=TSL2561_LUX_B7T;
+        m=TSL2561_LUX_M7T;
+    } else if (ratio > TSL2561_LUX_K8T) {
+        b=TSL2561_LUX_B8T;
+        m=TSL2561_LUX_M8T;
+    }
+#endif
+
+    long temp;
+    temp = ((channel0 * b) - (channel1 * m));
+
+    /* Do not allow negative lux value */
+    if (temp < 0L) {
+        temp = 0;
+    }
+    //printf("line:%d\r\n", __LINE__);
+    /* Round lsb (2^(LUX_SCALE-1)) */
+    temp += (1 << (TSL2561_LUX_LUXSCALE-1));
+
+    /* Strip off fractional portion */
+    uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
+
+    /* Signal I2C had no errors */
+    //printf("Lux=%d\r\n", lux);
+    return lux;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the most recent sensor event
+    @param  event Pointer to a sensor_event_t type that will be filled
+                  with the lux value, timestamp, data type and sensor ID.
+    @returns True if sensor reading is between 0 and 65535 lux,
+             false if sensor is saturated
+*/
+/**************************************************************************/
+bool TSL2561::getEvent(uint32_t *event)
+{
+    uint16_t broadband, ir;
+
+    /* Calculate the actual lux value */
+    getLuminosity(&broadband, &ir);
+    //printf("broadband=%d, ir=%d\r\n", broadband, ir);
+    *event = calculateLux(broadband, ir);
+    //printf("LUX=%f\r\n", event->light);
+    //printf("LUX=%d\r\n", *event);
+    //printf("line:%d\r\n", __LINE__);
+    if (*event == 65536) {
+        //printf("line:%d\r\n", __LINE__);
+        return false;
+    }
+    //printf("line:%d\r\n", __LINE__);
+    return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the sensor_t data
+    @param  sensor A pointer to a sensor_t structure that we will fill with
+                   details about the TSL2561 and its capabilities
+*/
+/**************************************************************************/
+void TSL2561::getSensor(sensor_t *sensor)
+{
+    /* Insert the sensor name in the fixed length char array */
+    //sensor->version     = 1;
+    sensor->min_delay   = 0;
+    sensor->max_value   = 17000.0;  /* Based on trial and error ... confirm! */
+    sensor->min_value   = 1.0;
+    sensor->resolution  = 1.0;
+}
+
+/*========================================================================*/
+/*                          PRIVATE FUNCTIONS                             */
+/*========================================================================*/
+
+/**************************************************************************/
+/*!
+    @brief  Writes a register and an 8 bit value over I2C
+    @param  reg I2C register to write the value to
+    @param  value The 8-bit value we're writing to the register
+*/
+/**************************************************************************/
+void TSL2561::write8 (uint8_t reg, uint8_t value)
+{
+    dt[0] = reg;
+    dt[1] = value;
+    _i2c.write((int)_addr, (char *)dt, 2, false);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an 8 bit value over I2C
+    @param  reg I2C register to read from
+    @returns 8-bit value containing single byte data read
+*/
+/**************************************************************************/
+uint8_t TSL2561::read8(uint8_t reg)
+{
+    dt[0] = reg;
+    _i2c.write((int)_addr, (char *)dt, 1, true);
+    _i2c.read(_addr, (char *)dt, 1, false);
+    return dt[0];
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+    @param  reg I2C register to read from
+    @returns 16-bit value containing 2-byte data read
+*/
+/**************************************************************************/
+uint16_t TSL2561::read16(uint8_t reg)
+{
+    dt[0] = reg;
+    _i2c.write((int)_addr, (char *)dt, 1, true);
+    _i2c.read(_addr, (char *)dt, 2, false);
+    uint16_t data = ((uint16_t)dt[1] << 8) + dt[0];
+    return data;
+}
+
+/*========================================================================*/
+/*   JH1PJL Original Functions  -> Keep compacibility for older revision  */
+/*========================================================================*/
+
 /////////////// Timing Register ///////////////////////////
 uint8_t TSL2561::set_timing_reg(uint8_t parameter)
 {
-    dt[0] = CMD_SINGLE + TSL2561_TIMING;
-    dt[1] = parameter;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
-    dt[0] = CMD_SINGLE + TSL2561_TIMING;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
-    _i2c.read(TSL2561_addr, (char *)dt, 1, false);
-    return dt[0];
+    enable();
+    write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, parameter);
+    return read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING);
 }
 
 uint8_t TSL2561::read_timing_reg(void)
 {
-    uint8_t i;
+    uint8_t i, data;
 
-    dt[0] = CMD_SINGLE + TSL2561_TIMING;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
-    _i2c.read(TSL2561_addr, (char *)dt, 1, false);
-    if (dt[0] & TIMING_GAIN_16){
+    data = read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING);
+    if (data & TSL2561_GAIN_16X) {
         gain = 16;
+        _TSL2561Gain = TSL2561_GAIN_16X;
     } else {
         gain = 1;
+        _TSL2561Gain = TSL2561_GAIN_1X;
     }
-    i = dt[0] & 0x3;
+    i = data & 0x3;
     switch (i) {
         case 0:
             integ_time = 13.7;
+            _TSL2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
             break;
         case 1:
             integ_time = 101.0;
+            _TSL2561IntegrationTime = TSL2561_INTEGRATIONTIME_101MS;
             break;
         case 2:
             integ_time = 402.0;
+            _TSL2561IntegrationTime = TSL2561_INTEGRATIONTIME_402MS;
             break;
         default:
             integ_time = 0;
+            _TSL2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
             break;
     }
     return dt[0];
@@ -142,10 +741,7 @@
 /////////////// ID ////////////////////////////////////////
 uint8_t TSL2561::read_ID()
 {
-    dt[0] = CMD_SINGLE + TSL2561_ID;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
-    _i2c.read(TSL2561_addr, (char *)dt, 2, false);
-    id_number = dt[0];
+    id_number = read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_ID);
     return id_number;
 }
 
@@ -164,16 +760,12 @@
 /////////////// Power ON/OFF //////////////////////////////
 void TSL2561::power_up()
 {
-    dt[0] = CMD_SINGLE + TSL2561_CONTROL;
-    dt[1] = 3;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
+    enable();
 }
 
 void TSL2561::power_down()
 {
-    dt[0] = CMD_SINGLE + TSL2561_CONTROL;
-    dt[1] = 0;
-    _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
+    disable();
 }
 
 /////////////// I2C Freq. /////////////////////////////////
@@ -181,4 +773,3 @@
 {
     _i2c.frequency(hz);
 }
-
--- a/TSL2561.h	Tue Feb 20 10:52:41 2018 +0000
+++ b/TSL2561.h	Fri Sep 21 22:57:07 2018 +0000
@@ -1,164 +1,273 @@
-/*
- * mbed library program
- *  Luminosity sensor -- LIGHT-TO-DIGITAL CONVERTER (light intensity to a digital signal output)
- *  TSL2561 by Texas Advanced Optoelectronic Solutions Inc.
- *
- * Copyright (c) 2015,'17,'18 Kenji Arai / JH1PJL
- *  http://www.page.sannet.ne.jp/kenjia/index.html
- *  http://mbed.org/users/kenjiArai/
- *      Created: Feburary   21st, 2015
- *      Revised: August     23rd, 2017
- *      Revised: Feburary   20th, 2018   bug fix -> read_ID() & who_am_i()
- *                                       Thanks PARK JAICHANG
- */
-/*
- *---------------- REFERENCE ----------------------------------------------------------------------
- *  https://docs.google.com/viewer?url=http%3A%2F%2Fwww.adafruit.com%2Fdatasheets%2FTSL256x.pdf
- *  https://learn.adafruit.com/tsl2561?view=all
- *  http://www.adafruit.com/products/439
- *  http://akizukidenshi.com/catalog/g/gM-08219/
- */
-
-#ifndef TSL2561_H
-#define TSL2561_H
-
-#include "mbed.h"
-
-// Luminosity sensor, TSL2561
-// Address b7=0,b6=1,b5=1,b4=1,b3=0,b2=0,b1=1, b0=R/W
-#define TSL2561_ADDRESS_GND         (0x29 << 1)
-#define TSL2561_ADDRESS_FLOAT       (0x39 << 1)
-#define TSL2561_ADDRESS_VDD         (0x49 << 1)
-
-////////////// Registers //////////////////////////////////
-// Register definition
-#define TSL2561_CONTROL             0x00
-#define TSL2561_TIMING              0x01
-#define TSL2561_THRESHLOWLOW        0x02
-#define TSL2561_THRESHHIGHLOW       0x04
-#define TSL2561_INTERRUPT           0x06
-#define TSL2561_CRC                 0x08
-#define TSL2561_ID                  0x0A
-#define TSL2561_DATA0LOW            0x0C
-#define TSL2561_DATA0HIGH           0x0D
-#define TSL2561_DATA1LOW            0x0E
-#define TSL2561_DATA1HIGH           0x0F
-
-////////////// TIMING PARAMETER ///////////////////////////
-#define TIMING_GAIN_1               (0UL << 4)
-#define TIMING_GAIN_16              (1UL << 4)
-#define TIMING_TIME_13R7            (0x0)
-#define TIMING_TIME_101             (0x1)
-#define TIMING_TIME_402             (0x2)
-#define TIMING_TIME_MANU            (0x3)
-#define TIMING_DEFAULT              (TIMING_GAIN_1 + TIMING_TIME_402)
-
-////////////// ID /////////////////////////////////////////
-#define I_AM_TSL2561CS              0x01
-#define I_AM_TSL2561T_FN_CL         0x05
-
-////////////// COMMAND ////////////////////////////////////
-#define CMD_CMDMODE                 (1UL << 7)
-#define CMD_CLEAR                   (1UL << 6)
-#define CMD_WORD                    (1UL << 5)
-#define CMD_BLOCK                   (1UL << 4)
-#define CMD_SINGLE                  (CMD_CMDMODE)
-#define CMD_MULTI                   (CMD_CMDMODE + CMD_WORD)
-
-/** Interface for Luminosity sensor, TSL2561
- * @code
- * #include "mbed.h"
- * #include "TSL2561.h"
- *
- * // I2C Communication
- *  TSL2561      lum(dp5,dp27);    // TSL2561 SDA, SCL
- * // If you connected I2C line not only this device but also other devices,
- * //     you need to declare following method.
- *  I2C          i2c(dp5,dp27);    // SDA, SCL
- *  TSL2561      lum(i2c);         // TSL2561 SDA, SCL (Data available every 400mSec)
- *
- * int main() {;
- *   while(true){
- *      printf("Illuminance: %+7.2f [Lux]\r\n", lum.lux());
- *      wait(1.0);
- *   }
- * }
- * @endcode
- */
-
-class TSL2561
-{
-public:
-    /** Configure data pin
-      * @param data SDA and SCL pins
-      */
-    TSL2561(PinName p_sda, PinName p_scl);
-    TSL2561(PinName p_sda, PinName p_scl, uint8_t addr);
-
-    /** Configure data pin (with other devices on I2C line)
-      * @param I2C previous definition
-      */
-    TSL2561(I2C& p_i2c);
-    TSL2561(I2C& p_i2c, uint8_t addr);
-
-    /** Get approximates the human eye response
-      *  in the commonly used Illuminance unit of Lux
-      * @param none
-      * @return Lux
-      */
-    float lux(void);
-
-    /** Set timing register
-      * @param timing parameter
-      * @return timing read data
-      */
-    uint8_t set_timing_reg(uint8_t parameter);
-
-    /** Read timing register
-      * @param timing parameter
-      * @return timing read data
-      */
-    uint8_t read_timing_reg(void);
-
-    /** Set I2C clock frequency
-      * @param freq.
-      * @return none
-      */
-    void frequency(int hz);
-
-    /** check Device ID number
-      * @param none
-      * @return TSL2561 = 1, others  0
-      */
-    uint8_t who_am_i(void);
-
-    /** Read ID and Revision Number
-      * @param none
-      * @return ID + REVNO
-      */
-    uint8_t read_ID(void);
-
-    /** Power Up/Down
-      * @param none
-      * @return none
-      */
-    void power_up(void);
-    void power_down(void);
-
-protected:
-    I2C *_i2c_p;
-    I2C &_i2c;
-
-    void init(void);
-
-private:
-    uint8_t  TSL2561_addr;
-    uint8_t  dt[4];
-    uint32_t ch0;
-    uint32_t ch1;
-    int8_t   gain;
-    uint8_t  id_number;
-    double   integ_time;
-};
-
-#endif      // TSL2561_H
+/*!
+ * @file Adafruit_TSL2561_U.h
+ *
+ * This is part of Adafruit's FXOS8700 driver for the Arduino platform.  It is
+ * designed specifically to work with the Adafruit FXOS8700 breakout:
+ * https://www.adafruit.com/products/3463
+ *
+ * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
+ * to interface with the breakout.
+ *
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
+ *
+ * BSD license, all text here must be included in any redistribution.
+ *
+ */
+
+//------- Modified by ----------------------------------------------------------
+//  Kenji Arai / JH1PJL
+//  http://www.page.sannet.ne.jp/kenjia/index.html
+//  http://mbed.org/users/kenjiArai/
+//      Created: Feburary   21st, 2015
+//      Revised: August     23rd, 2017
+//      Revised: Feburary   20th, 2018   bug fix -> read_ID() & who_am_i()
+//                                       Thanks PARK JAICHANG
+//      Revised: March      31st, 2018   Added "Auto Range mode"
+//                                       Use Adafruit library
+//
+// Original information     https://www.adafruit.com/product/439
+// Original source files    https://github.com/adafruit/TSL2561-Arduino-Library
+//                          https://github.com/adafruit/Adafruit_TSL2561
+// Change for Mbed platform
+//    modified -> all related files
+//------------------------------------------------------------------------------
+
+#ifndef TSL2561_H_
+#define TSL2561_H_
+
+#include "mbed.h"
+
+// Luminosity sensor, TSL2561
+// Address b7=0,b6=1,b5=1,b4=1,b3=0,b2=0,b1=1, b0=R/W
+#define TSL2561_ADDRESS_GND       (0x29 << 1)
+#define TSL2561_ADDR_LOW          (0x29 << 1)
+#define TSL2561_ADDRESS_FLOAT     (0x39 << 1)
+#define TSL2561_ADDR_FLOAT        (0x39 << 1)
+#define TSL2561_ADDRESS_VDD       (0x49 << 1)
+#define TSL2561_ADDR_HIGH         (0x49 << 1)
+
+// Lux calculations differ slightly for CS package
+//#define TSL2561_PACKAGE_CS                ///< Chip scale package
+#define TSL2561_PACKAGE_T_FN_CL             ///< Dual Flat No-Lead package
+
+// ID
+#define I_AM_TSL2561CS             0x01
+#define I_AM_TSL2561T_FN_CL        0x05
+
+// COMMAND register bit definition
+#define TSL2561_COMMAND_BIT       (0x80)    ///< Must be 1
+///< Clears any pending interrupt (write 1 to clear)
+#define TSL2561_CLEAR_BIT         (0x40)
+///< 1 = read/write word (rather than byte)
+#define TSL2561_WORD_BIT          (0x20)
+///< 1 = using block read/write
+#define TSL2561_BLOCK_BIT         (0x10)
+
+// Control register setting to turn on/off
+#define TSL2561_CONTROL_POWERON   (0x03)
+#define TSL2561_CONTROL_POWEROFF  (0x00)
+
+#define TSL2561_LUX_LUXSCALE      (14)      ///< Scale by 2^14
+#define TSL2561_LUX_RATIOSCALE    (9)       ///< Scale ratio by 2^9
+#define TSL2561_LUX_CHSCALE       (10)      ///< Scale channel values by 2^10
+#define TSL2561_LUX_CHSCALE_TINT0 (0x7517)  ///< 322/11 * 2^TSL2561_LUX_CHSCALE
+#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7)  ///< 322/81 * 2^TSL2561_LUX_CHSCALE
+
+/** TSL2561 I2C Registers */
+enum {
+    TSL2561_REGISTER_CONTROL          = 0x00, // Control/power register
+    TSL2561_REGISTER_TIMING           = 0x01, // Set integration time register
+    TSL2561_REGISTER_THRESHHOLDL_LOW  = 0x02, // Interrupt low threshold low-byte
+    TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, // Interrupt low threshold high-byte
+    TSL2561_REGISTER_THRESHHOLDH_LOW  = 0x04, // Interrupt high threshold low-byte
+    TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, // Interrupt high threshold high-byte
+    TSL2561_REGISTER_INTERRUPT        = 0x06, // Interrupt settings
+    TSL2561_REGISTER_CRC              = 0x08, // Factory use only
+    TSL2561_REGISTER_ID               = 0x0A, // TSL2561 identification setting
+    TSL2561_REGISTER_CHAN0_LOW        = 0x0C, // Light data channel 0, low byte
+    TSL2561_REGISTER_CHAN0_HIGH       = 0x0D, // Light data channel 0, high byte
+    TSL2561_REGISTER_CHAN1_LOW        = 0x0E, // Light data channel 1, low byte
+    TSL2561_REGISTER_CHAN1_HIGH       = 0x0F  // Light data channel 1, high byte
+};
+
+/** Three options for how long to integrate readings for */
+typedef enum {
+    TSL2561_INTEGRATIONTIME_13MS  = 0x00,    // 13.7ms
+    TSL2561_INTEGRATIONTIME_101MS = 0x01,    // 101ms
+    TSL2561_INTEGRATIONTIME_402MS = 0x02     // 402ms
+}
+TSL2561IntegrationTime_t;
+
+/** TSL2561 offers 2 gain settings */
+typedef enum {
+    TSL2561_GAIN_1X               = 0x00,    // No gain
+    TSL2561_GAIN_16X              = 0x10,    // 16x gain
+}
+TSL2561Gain_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;
+
+#define SENSOR_TYPE_LIGHT       5
+
+/* Sensor details */
+/** struct sensor_s is used to describe basic information
+        about a specific sensor. */
+typedef struct {
+    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 */
+    /**< smallest difference between two values reported by this sensor */
+    float    resolution;
+    /**< min delay in microseconds between events. zero = not a constant rate */
+    int32_t  min_delay;
+} sensor_t;
+
+/** Interface for Luminosity sensor, TSL2561
+ * @code
+ * #include "mbed.h"
+ * #include "TSL2561.h"
+ *
+ * // I2C Communication
+ *  TSL2561      lum(dp5,dp27);    // TSL2561 SDA, SCL
+ * // If you connected I2C line not only this device but also other devices,
+ * //     you need to declare following method.
+ *  I2C          i2c(dp5,dp27); // SDA, SCL
+ *  TSL2561      lum(i2c); // TSL2561 SDA, SCL (Data available every 400mSec)
+ *
+ * int main() {;
+ *   while(true){
+ *      printf("Illuminance: %+7.2f [Lux]\r\n", lum.lux());
+ *      wait(1.0);
+ *   }
+ * }
+ * @endcode
+ */
+
+/**************************************************************************/
+/*!
+    @brief  Class that stores state and functions
+                 for interacting with TSL2561 Light Sensor
+*/
+/**************************************************************************/
+class TSL2561
+{
+public:
+    /** Configure data pin
+      * @param data SDA and SCL pins
+      */
+    TSL2561(PinName p_sda, PinName p_scl);
+    TSL2561(PinName p_sda, PinName p_scl, uint8_t addr);
+
+    /** Configure data pin (with other devices on I2C line)
+      * @param I2C previous definition
+      */
+    TSL2561(I2C& p_i2c);
+    TSL2561(I2C& p_i2c, uint8_t addr);
+
+    /** Get approximates the human eye response
+      *  in the commonly used Illuminance unit of Lux
+      * @param none
+      * @return Lux
+      */
+    float lux(void);
+
+    /** Get approximates the human eye response with "Auto Range"
+      *  in the commonly used Illuminance unit of Lux
+      * @param none
+      * @return Lux
+      */
+    float lux_auto(void);
+
+    /** Set timing register
+      * @param timing parameter
+      * @return timing read data
+      */
+    uint8_t set_timing_reg(uint8_t parameter);
+
+    /** Read timing register
+      * @param timing parameter
+      * @return timing read data
+      */
+    uint8_t read_timing_reg(void);
+
+    /** Set I2C clock frequency
+      * @param freq.
+      * @return none
+      */
+    void frequency(int hz);
+
+    /** check Device ID number
+      * @param none
+      * @return TSL2561 = 1, others  0
+      */
+    uint8_t who_am_i(void);
+
+    /** Read ID and Revision Number
+      * @param none
+      * @return ID + REVNO
+      */
+    uint8_t read_ID(void);
+
+    /** Power Up/Down
+      * @param none
+      * @return none
+      */
+    void power_up(void);
+    void power_down(void);
+
+    //---------- Adafruit_TSL2561_U.h Original functions part ------------------
+    bool init();
+
+    /* TSL2561 Functions */
+    void enableAutoRange(bool enable);
+    void setIntegrationTime(TSL2561IntegrationTime_t time);
+    void setGain(TSL2561Gain_t gain);
+    void getLuminosity (uint16_t *broadband, uint16_t *ir);
+    uint32_t calculateLux(uint16_t broadband, uint16_t ir);
+
+    /* Unified Sensor API Functions */
+    bool getEvent(uint32_t*);
+    void getSensor(sensor_t*);
+
+private:
+    I2C *_i2c_p;
+    I2C &_i2c;
+    Timer   t;
+
+    int8_t  _addr;
+    bool    _TSL2561Initialised;
+    bool    _TSL2561AutoGain;
+    TSL2561IntegrationTime_t _TSL2561IntegrationTime;
+    TSL2561Gain_t _TSL2561Gain;
+    uint32_t ch0;
+    uint32_t ch1;
+    int8_t   gain;
+    uint8_t  id_number;
+    float    integ_time;
+
+    uint8_t  dt[4];
+
+    void     enable (void);
+    void     disable (void);
+    void     write8 (uint8_t reg, uint8_t value);
+    uint8_t  read8 (uint8_t reg);
+    uint16_t read16 (uint8_t reg);
+    void     getData (uint16_t *broadband, uint16_t *ir);
+};
+
+#endif // TSL2561_H