libraries / Adafruit_Sensor-master / README.mdon commit Added link to project report (97a3ba0)
   1# Adafruit Unified Sensor Driver #
   2
   3Many 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.
   4
   5One 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.
   6
   7Creating 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.
   8
   9By 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.
  10
  11The 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.
  12
  13## Unified Sensor Drivers ##
  14
  15The following drivers are based on the Adafruit Unified Sensor Driver:
  16
  17**Accelerometers**
  18  - [Adafruit\_ADXL345](https://github.com/adafruit/Adafruit_ADXL345)
  19  - [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
  20  - [Adafruit\_MMA8451\_Library](https://github.com/adafruit/Adafruit_MMA8451_Library)
  21
  22**Gyroscope**
  23  - [Adafruit\_L3GD20\_U](https://github.com/adafruit/Adafruit_L3GD20_U)
  24
  25**Light**
  26  - [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561)
  27  - [Adafruit\_TSL2591\_Library](https://github.com/adafruit/Adafruit_TSL2591_Library)
  28
  29**Magnetometers**
  30  - [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
  31  - [Adafruit\_HMC5883\_Unified](https://github.com/adafruit/Adafruit_HMC5883_Unified)
  32  
  33**Barometric Pressure**
  34  - [Adafruit\_BMP085\_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified)
  35  - [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library)
  36
  37**Humidity & Temperature**
  38  - [Adafruit\_DHT\_Unified](https://github.com/adafruit/Adafruit_DHT_Unified)
  39
  40**Orientation**
  41 - [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055)
  42
  43## How Does it Work? ##
  44
  45Any 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:
  46
  47**Sensor Types (sensors\_type\_t)**
  48
  49These 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.
  50
  51```
  52/** Sensor types */
  53typedef enum
  54{
  55  SENSOR_TYPE_ACCELEROMETER         = (1),
  56  SENSOR_TYPE_MAGNETIC_FIELD        = (2),
  57  SENSOR_TYPE_ORIENTATION           = (3),
  58  SENSOR_TYPE_GYROSCOPE             = (4),
  59  SENSOR_TYPE_LIGHT                 = (5),
  60  SENSOR_TYPE_PRESSURE              = (6),
  61  SENSOR_TYPE_PROXIMITY             = (8),
  62  SENSOR_TYPE_GRAVITY               = (9),
  63  SENSOR_TYPE_LINEAR_ACCELERATION   = (10),
  64  SENSOR_TYPE_ROTATION_VECTOR       = (11),
  65  SENSOR_TYPE_RELATIVE_HUMIDITY     = (12),
  66  SENSOR_TYPE_AMBIENT_TEMPERATURE   = (13),
  67  SENSOR_TYPE_VOLTAGE               = (15),
  68  SENSOR_TYPE_CURRENT               = (16),
  69  SENSOR_TYPE_COLOR                 = (17)
  70} sensors_type_t;
  71```
  72
  73**Sensor Details (sensor\_t)**
  74
  75This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer.
  76
  77```
  78/* Sensor details (40 bytes) */
  79/** struct sensor_s is used to describe basic information about a specific sensor. */
  80typedef struct
  81{
  82    char     name[12];
  83    int32_t  version;
  84    int32_t  sensor_id;
  85    int32_t  type;
  86    float    max_value;
  87    float    min_value;
  88    float    resolution;
  89    int32_t  min_delay;
  90} sensor_t;
  91```
  92
  93The individual fields are intended to be used as follows:
  94
  95- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2")
  96- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver
  97- **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
  98- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h
  99- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit)
 100- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit)
 101- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit)
 102- **min\_delay**: The minimum delay in microseconds between two sensor events, or '0' if there is no constant sensor rate
 103
 104**Sensor Data/Events (sensors\_event\_t)**
 105
 106This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales.
 107
 108```
 109/* Sensor event (36 bytes) */
 110/** struct sensor_event_s is used to provide a single sensor event in a common format. */
 111typedef struct
 112{
 113    int32_t version;
 114    int32_t sensor_id;
 115    int32_t type;
 116    int32_t reserved0;
 117    int32_t timestamp;
 118    union
 119    {
 120        float           data[4];
 121        sensors_vec_t   acceleration;
 122        sensors_vec_t   magnetic;
 123        sensors_vec_t   orientation;
 124        sensors_vec_t   gyro;
 125        float           temperature;
 126        float           distance;
 127        float           light;
 128        float           pressure;
 129        float           relative_humidity;
 130        float           current;
 131        float           voltage;
 132        sensors_color_t color;
 133    };
 134} sensors_event_t;
 135```
 136It includes the following fields:
 137
 138- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future
 139- **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!)
 140- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h
 141- **timestamp**: time in milliseconds when the sensor value was read
 142- **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)
 143
 144**Required Functions**
 145
 146In addition to the two standard types and the sensor type enum, all drivers based on Adafruit_Sensor must also implement the following two functions:
 147
 148```
 149bool getEvent(sensors_event_t*);
 150```
 151Calling 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.
 152
 153```
 154void getSensor(sensor_t*);
 155```
 156Calling this function will provide some basic information about the sensor (the sensor name, driver version, min and max values, etc.
 157
 158**Standardised SI values for sensors\_event\_t**
 159
 160A 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:
 161
 162- **acceleration**: values are in **meter per second per second** (m/s^2)
 163- **magnetic**: values are in **micro-Tesla** (uT)
 164- **orientation**: values are in **degrees**
 165- **gyro**: values are in **rad/s**
 166- **temperature**: values in **degrees centigrade** (Celsius) 
 167- **distance**: values are in **centimeters**
 168- **light**: values are in **SI lux** units
 169- **pressure**: values are in **hectopascal** (hPa)
 170- **relative\_humidity**: values are in **percent**
 171- **current**: values are in **milliamps** (mA)
 172- **voltage**: values are in **volts** (V)
 173- **color**: values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format
 174
 175## The Unified Driver Abstraction Layer in Practice ##
 176
 177Using the unified sensor abstraction layer is relatively easy once a compliant driver has been created.
 178
 179Every 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).
 180
 181An example of reading the [TSL2561](https://github.com/adafruit/Adafruit_TSL2561) light sensor can be seen below:
 182
 183```
 184 Adafruit_TSL2561 tsl = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345);
 185 ...
 186 /* Get a new sensor event */ 
 187 sensors_event_t event;
 188 tsl.getEvent(&event);
 189 
 190 /* Display the results (light is measured in lux) */
 191 if (event.light)
 192 {
 193   Serial.print(event.light); Serial.println(" lux");
 194 }
 195 else
 196 {
 197   /* If event.light = 0 lux the sensor is probably saturated
 198      and no reliable data could be generated! */
 199   Serial.println("Sensor overload");
 200 }
 201```
 202
 203Similarly, we can get the basic technical capabilities of this sensor with the following code:
 204
 205```
 206 sensor_t sensor;
 207 
 208 sensor_t sensor;
 209 tsl.getSensor(&sensor);
 210
 211 /* Display the sensor details */
 212 Serial.println("------------------------------------");
 213 Serial.print  ("Sensor:       "); Serial.println(sensor.name);
 214 Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
 215 Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
 216 Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" lux");
 217 Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" lux");
 218 Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" lux");  
 219 Serial.println("------------------------------------");
 220 Serial.println("");
 221```