Add support and sample of the tsl256x light sensor
This commit is contained in:
parent
f13349dfc5
commit
b90795782a
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 British Broadcasting Corporation.
|
||||
This software is provided by Lancaster University by arrangement with the BBC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "MicroBit.h"
|
||||
#include "tsl256x.h"
|
||||
|
||||
MicroBit uBit;
|
||||
MicroBitI2C i2c(I2C_SDA0,I2C_SCL0);
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialise the micro:bit runtime.
|
||||
uBit.init();
|
||||
|
||||
tsl256x tsl(&uBit,&i2c);
|
||||
uint16_t comb =0;
|
||||
uint16_t ir = 0;
|
||||
uint32_t lux = 0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
tsl.sensor_read(&comb, &ir, &lux);
|
||||
ManagedString display = "Lux:" + ManagedString((int)lux);
|
||||
uBit.display.scroll(display.toCharArray());
|
||||
|
||||
uBit.sleep(1000);
|
||||
}
|
||||
|
||||
release_fiber();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/****************************************************************************
|
||||
* extdrv/tsl256x_light_sensor.c
|
||||
*
|
||||
* TSL256x I2C luminosity and IR sensor driver
|
||||
*
|
||||
* Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "tsl256x.h"
|
||||
|
||||
/* Sensor config
|
||||
* Performs default configuration of the luminosity sensor.
|
||||
* FIXME : Add more comments about the behavior and the resulting configuration.
|
||||
*/
|
||||
#define CONF_BUF_SIZE 2
|
||||
tsl256x::tsl256x(MicroBit* uB, MicroBitI2C* uBi2c, uint8_t addr, uint8_t pkg,
|
||||
uint8_t p_gain, uint8_t integration)
|
||||
:
|
||||
uBit(uB), i2c(uBi2c), address(addr), package(pkg), gain(p_gain), integration_time(integration)
|
||||
{
|
||||
probe_ok = 0;
|
||||
int ret = 0;
|
||||
char cmd_buf[CONF_BUF_SIZE] = { TSL256x_CMD(timing), 0, };
|
||||
|
||||
cmd_buf[1] = (gain | integration_time);
|
||||
|
||||
if (probe_sensor() != 1) {
|
||||
uBit->display.scroll("TSL256X: No Device");
|
||||
}
|
||||
uBit->sleep(1);
|
||||
ret = i2c->write(address, cmd_buf, CONF_BUF_SIZE);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
uBit->display.scroll("TSL256x: Conf Error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check the sensor presence, return 1 if found
|
||||
* This is done by writing to the control register to set the power state to ON and
|
||||
* reading the register to check the value, as stated in the TSL256x documentation page 14,
|
||||
* (Register Set definitions)
|
||||
* FIXME : Never managed to read the required value, though the sensor is running and
|
||||
* provides seemingly accurate values.
|
||||
*/
|
||||
#define PROBE_BUF_SIZE 2
|
||||
int tsl256x::probe_sensor()
|
||||
{
|
||||
int ret = 0;
|
||||
char cmd_buf[PROBE_BUF_SIZE] = { TSL256x_CMD(control), TSL256x_POWER_ON, };
|
||||
uint8_t control_val = 72;
|
||||
|
||||
/* Did we already probe the sensor ? */
|
||||
if (probe_ok != 1) {
|
||||
ret = i2c->write(address, cmd_buf, PROBE_BUF_SIZE);
|
||||
if (ret != MICROBIT_OK) {
|
||||
return 0;
|
||||
}
|
||||
uBit->sleep(500);
|
||||
i2c->write(address, cmd_buf,1,true);
|
||||
ret = i2c->read(address, (char*)&control_val, 1);
|
||||
/* FIXME : check that control_val is TSL256x_POWER_ON... */
|
||||
if (ret == MICROBIT_OK && (control_val&0x03) == TSL256x_POWER_ON) {
|
||||
probe_ok = 1;
|
||||
}
|
||||
}
|
||||
return probe_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* FIXME: add comments, and make it work right ... never managed to read the ID given in
|
||||
* the documentation
|
||||
*/
|
||||
|
||||
#define ID_BUF_SIZE 1
|
||||
int tsl256x::read_id()
|
||||
{
|
||||
int ret = 0;
|
||||
char cmd_buf[ID_BUF_SIZE] = { TSL256x_CMD(part_id)};
|
||||
char id = 0;
|
||||
|
||||
/* Did we already probe the sensor ? */
|
||||
if (probe_ok != 1) {
|
||||
return 0;
|
||||
}
|
||||
i2c->write(address, cmd_buf, ID_BUF_SIZE, true);
|
||||
ret = i2c->read(address, &id, 1);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/* Lux Read
|
||||
* Performs a non-blocking read of the luminosity from the sensor.
|
||||
* 'lux' 'ir' and 'comb': integer addresses for conversion result, may be NULL.
|
||||
* Return value(s):
|
||||
* Upon successfull completion, returns 0 and the luminosity read is placed in the
|
||||
* provided integer(s). On error, returns a negative integer equivalent to errors from
|
||||
* glibc.
|
||||
*/
|
||||
#define READ_BUF_SIZE 1
|
||||
int tsl256x::sensor_read(uint16_t* comb, uint16_t* ir, uint32_t* lux)
|
||||
{
|
||||
int ret = 0;
|
||||
char cmd_buf[READ_BUF_SIZE] = { TSL256x_CMD(data)};
|
||||
uint8_t data[4];
|
||||
uint16_t comb_raw = 0, ir_raw = 0;
|
||||
|
||||
i2c->write(address, cmd_buf, READ_BUF_SIZE,true);
|
||||
ret = i2c->read(address, (char*)data, 4);
|
||||
if (ret != MICROBIT_OK) {
|
||||
probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
comb_raw = (data[0] & 0xFF) | ((data[1] << 8) & 0xFF00);
|
||||
ir_raw = (data[2] & 0xFF) | ((data[3] << 8) & 0xFF00);
|
||||
|
||||
if (comb != NULL) {
|
||||
*comb = comb_raw;
|
||||
}
|
||||
if (ir != NULL) {
|
||||
*ir = ir_raw;
|
||||
}
|
||||
if (lux != NULL) {
|
||||
*lux = calculate_lux(comb_raw, ir_raw);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************** */
|
||||
/*
|
||||
* lux equation approximation without floating point calculations
|
||||
*
|
||||
* Description:
|
||||
* Calculate the approximate illuminance (lux) given the raw channel values of
|
||||
* the TSL2560. The equation if implemented as a piece−wise linear approximation.
|
||||
*
|
||||
* Arguments:
|
||||
* uint16_t ch0 − raw channel value from channel 0 of TSL2560
|
||||
* uint16_t ch1 − raw channel value from channel 1 of TSL2560
|
||||
*
|
||||
* Return: uint32_t − the approximate illuminance (lux)
|
||||
*
|
||||
*/
|
||||
uint32_t tsl256x::calculate_lux(uint16_t ch0, uint16_t ch1)
|
||||
{
|
||||
/* First, scale the channel values depending on the gain and integration time
|
||||
* 16X, 402mS is nominal.
|
||||
* Scale if integration time is NOT 402 msec */
|
||||
uint32_t chScale = 0;
|
||||
uint32_t channel1 = 0, channel0 = 0;
|
||||
uint32_t ratio = 0, lux = 0;
|
||||
uint32_t b = 0, m = 0;
|
||||
|
||||
switch (integration_time) {
|
||||
case TSL256x_INTEGRATION_13ms: /* 13.7 msec */
|
||||
chScale = CHSCALE_TINT0;
|
||||
break;
|
||||
case TSL256x_INTEGRATION_100ms: /* 101 msec */
|
||||
chScale = CHSCALE_TINT1;
|
||||
break;
|
||||
case TSL256x_INTEGRATION_400ms: /* 402 msec */
|
||||
default: /* assume no scaling */
|
||||
chScale = (1 << CH_SCALE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Scale if gain is NOT 16X */
|
||||
if (gain == TSL256x_LOW_GAIN) {
|
||||
chScale = chScale << 4; /* Scale 1X to 16X */
|
||||
}
|
||||
|
||||
// Scale the channel values */
|
||||
channel0 = (ch0 * chScale) >> CH_SCALE;
|
||||
channel1 = (ch1 * chScale) >> CH_SCALE;
|
||||
|
||||
/* Find the ratio of the channel values (Channel1/Channel0) */
|
||||
/* Protect against divide by zero */
|
||||
if (channel0 != 0) {
|
||||
ratio = (channel1 << (RATIO_SCALE + 1)) / channel0;
|
||||
}
|
||||
/* Round the ratio value */
|
||||
ratio = (ratio + 1) >> 1;
|
||||
|
||||
/* Is ratio <= eachBreak ? */
|
||||
switch (package) {
|
||||
case TSL256x_PACKAGE_T:
|
||||
case TSL256x_PACKAGE_FN:
|
||||
case TSL256x_PACKAGE_CL:
|
||||
if (ratio <= K1T) {
|
||||
b = B1T; m = M1T;
|
||||
} else if (ratio <= K2T) {
|
||||
b = B2T; m = M2T;
|
||||
} else if (ratio <= K3T) {
|
||||
b = B3T; m = M3T;
|
||||
} else if (ratio <= K4T) {
|
||||
b = B4T; m = M4T;
|
||||
} else if (ratio <= K5T) {
|
||||
b = B5T; m = M5T;
|
||||
} else if (ratio <= K6T) {
|
||||
b = B6T; m = M6T;
|
||||
} else if (ratio <= K7T) {
|
||||
b = B7T; m = M7T;
|
||||
} else if (ratio > K8T) {
|
||||
b = B8T; m = M8T;
|
||||
} break;
|
||||
case TSL256x_PACKAGE_CS: /* CS package */
|
||||
if (ratio <= K1C) {
|
||||
b = B1C; m = M1C;
|
||||
} else if (ratio <= K2C) {
|
||||
b = B2C; m = M2C;
|
||||
} else if (ratio <= K3C) {
|
||||
b = B3C; m = M3C;
|
||||
} else if (ratio <= K4C) {
|
||||
b = B4C; m = M4C;
|
||||
} else if (ratio <= K5C) {
|
||||
b = B5C; m = M5C;
|
||||
} else if (ratio <= K6C) {
|
||||
b = B6C; m = M6C;
|
||||
} else if (ratio <= K7C) {
|
||||
b = B7C; m = M7C;
|
||||
}else if (ratio > K8C) {
|
||||
b = B8C; m = M8C;
|
||||
} break;
|
||||
}
|
||||
lux = ((channel0 * b) - (channel1 * m));
|
||||
|
||||
/* Round lsb (2^(LUX_SCALE−1)) */
|
||||
lux += (1 << (LUX_SCALE - 1));
|
||||
/* Strip off fractional portion */
|
||||
lux = lux >> LUX_SCALE;
|
||||
|
||||
return lux;
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
/****************************************************************************
|
||||
* extdrv/tsl256x_light_sensor.h
|
||||
*
|
||||
* TSL256x I2C luminosity and IR sensor driver
|
||||
*
|
||||
* Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
/**
|
||||
* This code is mainly an adaptation of code provided by Techno-Innov (Nathael Pajani <nathael.pajani@ed3l.fr>)
|
||||
* www.techno-innov.fr
|
||||
* http://git.techno-innov.fr
|
||||
*/
|
||||
|
||||
#ifndef TSL256X_H
|
||||
#define TSL256X_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "MicroBit.h"
|
||||
|
||||
#define TSL256x_ADDR 0x52
|
||||
|
||||
|
||||
enum tsl256x_pkg_types {
|
||||
TSL256x_PACKAGE_T = 0,
|
||||
TSL256x_PACKAGE_FN,
|
||||
TSL256x_PACKAGE_CL,
|
||||
TSL256x_PACKAGE_CS,
|
||||
};
|
||||
|
||||
struct tsl256x_internal_regs {
|
||||
uint8_t control; /* Control of basic functions */
|
||||
uint8_t timing; /* Integration time/gain control */
|
||||
uint16_t low_int_threshold; /* low interrupt threshold, in little endian byte order */
|
||||
uint16_t high_int_threshold; /* high interrupt threshold, in little endian byte order */
|
||||
uint8_t interrupt; /* interrupt control */
|
||||
uint8_t reserved0[3];
|
||||
uint8_t part_id; /* Part number and revision ID */
|
||||
uint8_t reserved1;
|
||||
uint16_t data[2]; /* Data from both ADC, in little endian byte order */
|
||||
};
|
||||
#define TSL256x_REGS(x) ((uint8_t)offsetof(struct tsl256x_internal_regs, x))
|
||||
|
||||
/* Defines for command byte */
|
||||
#define TSL256x_CMD_REG_SELECT (1 << 7)
|
||||
#define TSL256x_INT_CLEAR (1 << 6)
|
||||
#define TSL256x_USE_WORD (1 << 5)
|
||||
#define TSL256x_USE_BLOCK (1 << 4)
|
||||
#define TSL256x_REG_ADDR(x) ((x) & 0x0F)
|
||||
|
||||
#define TSL256x_CMD(x) (TSL256x_CMD_REG_SELECT | TSL256x_REGS(x))
|
||||
|
||||
/* Defines for control register */
|
||||
#define TSL256x_POWER_ON (0x03)
|
||||
|
||||
/* Defines for timing register */
|
||||
/* See page 22 of tsl256x manual for information on how to calculate lux. */
|
||||
#define TSL256x_LOW_GAIN (0x00)
|
||||
#define TSL256x_HIGH_GAIN_16X (1 << 4)
|
||||
#define TSL256x_CONVERSION_START (1 << 3)
|
||||
#define TSL256x_CONVERSION_MANUAL (0x03)
|
||||
#define TSL256x_INTEGRATION_400ms (0x02)
|
||||
#define TSL256x_INTEGRATION_100ms (0x01)
|
||||
#define TSL256x_INTEGRATION_13ms (0x00)
|
||||
|
||||
/* Defines for interrupt control register */
|
||||
#define TSL256x_INTR_NONE (0x00)
|
||||
#define TSL256x_INTR_LEVEL (0x01 << 4)
|
||||
#define TSL256x_INTR_SMBUS (0x02 << 4)
|
||||
#define TSL256x_INTR_ON_CONV_DONE (0x00)
|
||||
#define TSL256x_INTR_NB_CYCLE(x) ((x) & 0x0F)
|
||||
|
||||
/* Defines for part ID and revision ID register */
|
||||
#define TSL256x_PART_ID(x) (((x) & 0xF0) >> 4)
|
||||
#define TSL256x_PART_REV(x) ((x) & 0x0F)
|
||||
|
||||
|
||||
|
||||
/***************************************************************************** */
|
||||
/* Lux Computation
|
||||
*
|
||||
* Copyright E 2004−2005 TAOS, Inc.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED ”AS IS” WITHOUT WARRANTY OF ANY KIND,
|
||||
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define LUX_SCALE 14 /* scale by 2^14 */
|
||||
#define RATIO_SCALE 9 /* scale ratio by 2^9 */
|
||||
|
||||
/* Integration time scaling factors */
|
||||
#define CH_SCALE 10 /* scale channel values by 2^10 */
|
||||
#define CHSCALE_TINT0 ((322 / 11) * (2 << CH_SCALE)) /* = 0x7517 = 322/11 * 2^CH_SCALE */
|
||||
#define CHSCALE_TINT1 ((322 / 81) * (2 << CH_SCALE)) /* = 0x0fe7 = 322/81 * 2^CH_SCALE */
|
||||
|
||||
/*
|
||||
* T, FN, and CL Package coefficients
|
||||
*
|
||||
* For Ch1/Ch0=0.00 to 0.50 : Lux/Ch0=0.0304−0.062*((Ch1/Ch0)^1.4)
|
||||
* piecewise approximation
|
||||
* For Ch1/Ch0=0.00 to 0.125: Lux/Ch0=0.0304−0.0272*(Ch1/Ch0)
|
||||
* For Ch1/Ch0=0.125 to 0.250: Lux/Ch0=0.0325−0.0440*(Ch1/Ch0)
|
||||
* For Ch1/Ch0=0.250 to 0.375: Lux/Ch0=0.0351−0.0544*(Ch1/Ch0)
|
||||
* For Ch1/Ch0=0.375 to 0.50: Lux/Ch0=0.0381−0.0624*(Ch1/Ch0)
|
||||
*
|
||||
* For Ch1/Ch0=0.50 to 0.61: Lux/Ch0=0.0224−0.031*(Ch1/Ch0)
|
||||
*
|
||||
* For Ch1/Ch0=0.61 to 0.80: Lux/Ch0=0.0128−0.0153*(Ch1/Ch0)
|
||||
*
|
||||
* For Ch1/Ch0=0.80 to 1.30: Lux/Ch0=0.00146−0.00112*(Ch1/Ch0)
|
||||
*
|
||||
* For Ch1/Ch0>1.3: Lux/Ch0=0
|
||||
*
|
||||
*/
|
||||
#define K1T 0x0040 /* 0.125 * 2^RATIO_SCALE */
|
||||
#define B1T 0x01f2 /* 0.0304 * 2^LUX_SCALE */
|
||||
#define M1T 0x01be /* 0.0272 * 2^LUX_SCALE */
|
||||
#define K2T 0x0080 /* 0.250 * 2^RATIO_SCALE */
|
||||
#define B2T 0x0214 /* 0.0325 * 2^LUX_SCALE */
|
||||
#define M2T 0x02d1 /* 0.0440 * 2^LUX_SCALE */
|
||||
#define K3T 0x00c0 /* 0.375 * 2^RATIO_SCALE */
|
||||
#define B3T 0x023f /* 0.0351 * 2^LUX_SCALE */
|
||||
#define M3T 0x037b /* 0.0544 * 2^LUX_SCALE */
|
||||
#define K4T 0x0100 /* 0.50 * 2^RATIO_SCALE */
|
||||
#define B4T 0x0270 /* 0.0381 * 2^LUX_SCALE */
|
||||
#define M4T 0x03fe /* 0.0624 * 2^LUX_SCALE */
|
||||
#define K5T 0x0138 /* 0.61 * 2^RATIO_SCALE */
|
||||
#define B5T 0x016f /* 0.0224 * 2^LUX_SCALE */
|
||||
#define M5T 0x01fc /* 0.0310 * 2^LUX_SCALE */
|
||||
#define K6T 0x019a /* 0.80 * 2^RATIO_SCALE */
|
||||
#define B6T 0x00d2 /* 0.0128 * 2^LUX_SCALE */
|
||||
#define M6T 0x00fb /* 0.0153 * 2^LUX_SCALE */
|
||||
#define K7T 0x029a /* 1.3 * 2^RATIO_SCALE */
|
||||
#define B7T 0x0018 /* 0.00146 * 2^LUX_SCALE */
|
||||
#define M7T 0x0012 /* 0.00112 * 2^LUX_SCALE */
|
||||
#define K8T 0x029a /* 1.3 * 2^RATIO_SCALE */
|
||||
#define B8T 0x0000 /* 0.000 * 2^LUX_SCALE */
|
||||
#define M8T 0x0000 /* 0.000 * 2^LUX_SCALE*/
|
||||
|
||||
|
||||
/*
|
||||
* CS package coefficients
|
||||
*
|
||||
* For 0 <= Ch1/Ch0 <= 0.52 : Lux/Ch0 = 0.0315−0.0593*((Ch1/Ch0)^1.4)
|
||||
* piecewise approximation
|
||||
* For 0 <= Ch1/Ch0 <= 0.13 : Lux/Ch0 = 0.0315−0.0262*(Ch1/Ch0)
|
||||
* For 0.13 <= Ch1/Ch0 <= 0.26 : Lux/Ch0 = 0.0337−0.0430*(Ch1/Ch0)
|
||||
* For 0.26 <= Ch1/Ch0 <= 0.39 : Lux/Ch0 = 0.0363−0.0529*(Ch1/Ch0)
|
||||
* For 0.39 <= Ch1/Ch0 <= 0.52 : Lux/Ch0 = 0.0392−0.0605*(Ch1/Ch0)
|
||||
*
|
||||
* For 0.52 < Ch1/Ch0 <= 0.65 : Lux/Ch0 = 0.0229−0.0291*(Ch1/Ch0)
|
||||
*
|
||||
* For 0.65 < Ch1/Ch0 <= 0.80 : Lux/Ch0 = 0.00157−0.00180*(Ch1/Ch0)
|
||||
*
|
||||
* For 0.80 < Ch1/Ch0 <= 1.30 : Lux/Ch0 = 0.00338−0.00260*(Ch1/Ch0)
|
||||
*
|
||||
* For Ch1/Ch0 > 1.30 : Lux = 0
|
||||
*
|
||||
*/
|
||||
#define K1C 0x0043 /* 0.130 * 2^RATIO_SCALE */
|
||||
#define B1C 0x0204 /* 0.0315 * 2^LUX_SCALE */
|
||||
#define M1C 0x01ad /* 0.0262 * 2^LUX_SCALE */
|
||||
#define K2C 0x0085 /* 0.260 * 2^RATIO_SCALE */
|
||||
#define B2C 0x0228 /* 0.0337 * 2^LUX_SCALE */
|
||||
#define M2C 0x02c1 /* 0.0430 * 2^LUX_SCALE */
|
||||
#define K3C 0x00c8 /* 0.390 * 2^RATIO_SCALE */
|
||||
#define B3C 0x0253 /* 0.0363 * 2^LUX_SCALE */
|
||||
#define M3C 0x0363 /* 0.0529 * 2^LUX_SCALE*/
|
||||
#define K4C 0x010a /* 0.520 * 2^RATIO_SCALE */
|
||||
#define B4C 0x0282 /* 0.0392 * 2^LUX_SCALE */
|
||||
#define M4C 0x03df /* 0.0605 * 2^LUX_SCALE */
|
||||
#define K5C 0x014d /* 0.65 * 2^RATIO_SCALE */
|
||||
#define B5C 0x0177 /* 0.0229 * 2^LUX_SCALE */
|
||||
#define M5C 0x01dd /* 0.0291 * 2^LUX_SCALE */
|
||||
#define K6C 0x019a /* 0.80 * 2^RATIO_SCALE */
|
||||
#define B6C 0x0101 /* 0.0157 * 2^LUX_SCALE */
|
||||
#define M6C 0x0127 /* 0.0180 * 2^LUX_SCALE */
|
||||
#define K7C 0x029a /* 1.3 * 2^RATIO_SCALE */
|
||||
#define B7C 0x0037 /* 0.00338 * 2^LUX_SCALE */
|
||||
#define M7C 0x002b /* 0.00260 * 2^LUX_SCALE */
|
||||
#define K8C 0x029a /* 1.3 * 2^RATIO_SCALE */
|
||||
#define B8C 0x0000 /* 0.000 * 2^LUX_SCALE */
|
||||
#define M8C 0x0000 /* 0.000 * 2^LUX_SCALE*/
|
||||
|
||||
|
||||
|
||||
class tsl256x {
|
||||
|
||||
public:
|
||||
/* Sensor config
|
||||
* Performs default configuration of the luminosity sensor.
|
||||
* FIXME : Add more comments about the behavior and the resulting configuration.
|
||||
*/
|
||||
tsl256x(MicroBit* uB, MicroBitI2C* i2c, uint8_t addr = TSL256x_ADDR, uint8_t pkg = TSL256x_PACKAGE_T,
|
||||
uint8_t p_gain = TSL256x_LOW_GAIN, uint8_t integration = TSL256x_INTEGRATION_100ms);
|
||||
|
||||
/* Check the sensor presence, return 1 if found
|
||||
* This is done by writing to the control register to set the power state to ON and
|
||||
* reading the register to check the value, as stated in the TSL256x documentation page 14,
|
||||
* (Register Set definitions)
|
||||
* FIXME : Never managed to read the required value, though the sensor is running and
|
||||
* provides seemingly accurate values.
|
||||
*/
|
||||
int probe_sensor();
|
||||
|
||||
|
||||
/* FIXME: add comments, and make it work right ... never managed to read the ID given in
|
||||
* the documentation
|
||||
*/
|
||||
int read_id();
|
||||
|
||||
|
||||
/* Sensor read
|
||||
* Performs a non-blocking read of the luminosity from the sensor.
|
||||
* 'lux' 'ir' and 'comb': integer addresses for conversion result, may be NULL.
|
||||
* Return value(s):
|
||||
* Upon successfull completion, returns 0 and the luminosity read is placed in the
|
||||
* provided integer(s). On error, returns a negative integer equivalent to errors from
|
||||
* glibc.
|
||||
*/
|
||||
int sensor_read(uint16_t* comb, uint16_t* ir, uint32_t* lux);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
/*
|
||||
* lux equation approximation without floating point calculations
|
||||
*
|
||||
* Description:
|
||||
* Calculate the approximate illuminance (lux) given the raw channel values of
|
||||
* the TSL2560. The equation if implemented as a piece−wise linear approximation.
|
||||
*
|
||||
* Arguments:
|
||||
* uint16_t ch0 − raw channel value from channel 0 of TSL2560
|
||||
* uint16_t ch1 − raw channel value from channel 1 of TSL2560
|
||||
*
|
||||
* Return: uint32_t − the approximate illuminance (lux)
|
||||
*
|
||||
*/
|
||||
uint32_t calculate_lux(uint16_t ch0, uint16_t ch1);
|
||||
|
||||
MicroBit* uBit;
|
||||
MicroBitI2C* i2c;
|
||||
uint8_t address;
|
||||
uint8_t package;
|
||||
uint8_t gain;
|
||||
uint8_t integration_time;
|
||||
uint8_t probe_ok;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* TSL256X_H */
|
||||
|
||||
|
Loading…
Reference in New Issue