Update TSL2561 library

Remove TSL2561 debug message and update library (#2415)
This commit is contained in:
Theo Arends 2018-07-09 12:41:17 +02:00
parent f81e0eb2e4
commit cc24dd11ce
19 changed files with 306 additions and 57 deletions

View File

@ -21,6 +21,17 @@ This file is part of the Joba_Tsl2561 Library.
#include <Tsl2561Util.h> #include <Tsl2561Util.h>
// to mimic Serial.printf() of esp8266 core for other platforms
char *format( const char *fmt, ... ) {
static char buf[128];
va_list arg;
va_start(arg, fmt);
vsnprintf(buf, sizeof(buf), fmt, arg);
buf[sizeof(buf)-1] = '\0';
va_end(arg);
return buf;
}
Tsl2561 Tsl(Wire); Tsl2561 Tsl(Wire);
uint8_t id; uint8_t id;
@ -35,31 +46,30 @@ void setup() {
} }
void loop() { void loop() {
uint16_t scaledFull = ~0, scaledIr = ~0; uint16_t scaledFull = 0xffff, scaledIr = 0xffff;
uint32_t full = ~0, ir = ~0, milliLux = ~0; uint32_t full = 0xffffffff, ir = 0xffffffff, milliLux = 0xffffffff;
bool gain = false; bool gain = false;
Tsl2561::exposure_t exposure = Tsl2561::EXP_OFF; Tsl2561::exposure_t exposure = Tsl2561::EXP_OFF;
if( Tsl2561Util::autoGain(Tsl, gain, exposure, scaledFull, scaledIr) ) { if( Tsl2561Util::autoGain(Tsl, gain, exposure, scaledFull, scaledIr) ) {
if( Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) ) { if( Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) ) {
if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id)) ) { if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id), 5) ) {
Serial.printf("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, full: %5u, ir: %5u, gain: %d, exp: %d, lux: %5u.%03u\n", Serial.print(format("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, full: %7lu, ir: %7lu, gain: %d, exp: %d, lux: %5lu.%03lu\n",
Tsl.address(), id, scaledFull, scaledIr, full, ir, gain, exposure, milliLux/1000, milliLux%1000); Tsl.address(), id, scaledFull, scaledIr, (unsigned long)full, (unsigned long)ir, gain, exposure, (unsigned long)milliLux/1000, (unsigned long)milliLux%1000));
} }
else { else {
Serial.printf("Tsl2561Util::milliLux(full=%u, ir=%u) error\n", full, ir); Serial.print(format("Tsl2561Util::milliLux(full=%lu, ir=%lu) error\n", (unsigned long)full, (unsigned long)ir));
} }
} }
else { else {
Serial.printf("Tsl2561Util::normalizedLuminosity(gain=%u, exposure=%u, sfull=%u, sir=%u, full=%u, ir=%u) error\n", Serial.print(format("Tsl2561Util::normalizedLuminosity(gain=%u, exposure=%u, sfull=%u, sir=%u, full=%lu, ir=%lu) error\n",
gain, exposure, scaledFull, scaledIr, full, ir); gain, exposure, scaledFull, scaledIr, (unsigned long)full, (unsigned long)ir));
} }
} }
else { else {
Serial.printf("Tsl2561Util::autoGain(gain=%u, exposure=%u, sfull=%u, sir=%u) error\n", Serial.print(format("Tsl2561Util::autoGain(gain=%u, exposure=%u, sfull=%u, sir=%u) error\n",
gain, exposure, scaledFull, scaledIr); gain, exposure, scaledFull, scaledIr));
} }
delay(1000); delay(1000);
} }

View File

@ -21,6 +21,17 @@ This file is part of the Joba_Tsl2561 Library.
#include <Tsl2561.h> #include <Tsl2561.h>
// to mimic Serial.printf() of esp8266 core for other platforms
char *format( const char *fmt, ... ) {
static char buf[128];
va_list arg;
va_start(arg, fmt);
vsnprintf(buf, sizeof(buf), fmt, arg);
buf[sizeof(buf)-1] = '\0';
va_end(arg);
return buf;
}
Tsl2561 Tsl(Wire); Tsl2561 Tsl(Wire);
void setup() { void setup() {
@ -44,7 +55,7 @@ void loop() {
Tsl.fullLuminosity(full); Tsl.fullLuminosity(full);
Tsl.irLuminosity(ir); Tsl.irLuminosity(ir);
Serial.printf("Tsl2561 at 0x%02x(id=0x%02x) luminosity is %5u (full) and %5u (ir)\n", Tsl.address(), id, full, ir); Serial.print(format("Tsl2561 at 0x%02x(id=0x%02x) luminosity is %5u (full) and %5u (ir)\n", Tsl.address(), id, full, ir));
Tsl.off(); Tsl.off();
} }

View File

@ -22,11 +22,22 @@ This file is part of the Joba_Tsl2561 Library.
#include <Tsl2561.h> #include <Tsl2561.h>
// to mimic Serial.printf() of esp8266 core for other platforms
char *format( const char *fmt, ... ) {
static char buf[128];
va_list arg;
va_start(arg, fmt);
vsnprintf(buf, sizeof(buf), fmt, arg);
buf[sizeof(buf)-1] = '\0';
va_end(arg);
return buf;
}
Tsl2561 Tsl(Wire); Tsl2561 Tsl(Wire);
void showError( Tsl2561 &tsl ) { void showError( Tsl2561 &tsl ) {
Tsl2561::status_t status = tsl.status(); Tsl2561::status_t status = tsl.status();
Serial.printf("Error was %u: ", status); Serial.print(format("Error was %u: ", status));
switch( status ) { switch( status ) {
case Tsl2561::ERR_OK: Serial.println("None"); break; case Tsl2561::ERR_OK: Serial.println("None"); break;
case Tsl2561::ERR_RW: Serial.println("Read/Write"); break; case Tsl2561::ERR_RW: Serial.println("Read/Write"); break;
@ -40,7 +51,7 @@ void showError( Tsl2561 &tsl ) {
void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) { void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
if( tsl.on() ) { if( tsl.on() ) {
uint32_t start = millis(); uint32_t start = millis();
Serial.printf("Chip powered on at %u\n", start); Serial.print(format("Chip powered on at %lu\n", (unsigned long)start));
bool chipGain; bool chipGain;
Tsl2561::exposure_t chipExp; Tsl2561::exposure_t chipExp;
@ -58,7 +69,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
bool check = true; bool check = true;
if( change ) { if( change ) {
if( tsl.setSensitivity(newGain, newExp) ) { if( tsl.setSensitivity(newGain, newExp) ) {
Serial.printf("New gain = %d, exposure = 0x%02x\n", newGain, newExp); Serial.print(format("New gain = %d, exposure = 0x%02x\n", newGain, newExp));
} }
else { else {
check = false; check = false;
@ -69,6 +80,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
if( check ) { if( check ) {
uint16_t ir, full = 0; uint16_t ir, full = 0;
while( !full && millis() - start < 1000 ) { while( !full && millis() - start < 1000 ) {
if( !tsl.fullLuminosity(full) ) { if( !tsl.fullLuminosity(full) ) {
Serial.print("Check full luminosity failed. "); Serial.print("Check full luminosity failed. ");
@ -89,7 +101,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
Serial.println("No luminosity reading after 1s. Too dark?"); Serial.println("No luminosity reading after 1s. Too dark?");
} }
else { else {
Serial.printf("Got luminosity after %d ms. Full spectrum is %d and IR only is %d\n", millis() - start, full, ir); Serial.print(format("Got luminosity after %lu ms. Full spectrum is %u and IR only is %u\n", (unsigned long)millis() - start, full, ir));
} }
} }
@ -107,7 +119,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
bool testPackage( Tsl2561 &tsl ) { bool testPackage( Tsl2561 &tsl ) {
uint8_t id; uint8_t id;
if( tsl.id(id) ) { if( tsl.id(id) ) {
Serial.printf("Chip has type %02x and revision %x\n", Tsl2561::type(id), Tsl2561::revision(id) ); Serial.print(format("Chip has type %02x and revision %x\n", Tsl2561::type(id), Tsl2561::revision(id)));
if( Tsl2561::packageT_FN_CL(id) ) { if( Tsl2561::packageT_FN_CL(id) ) {
Serial.println("Chip is a T, FN or CL type package"); Serial.println("Chip is a T, FN or CL type package");
} }
@ -128,7 +140,7 @@ bool testPackage( Tsl2561 &tsl ) {
void test( Tsl2561 &tsl ) { void test( Tsl2561 &tsl ) {
bool ok = tsl.available(); bool ok = tsl.available();
Serial.printf("\nTesting Tsl2561 at address %02x: %sfound\n", tsl.address(), ok ? "" : "NOT "); Serial.print(format("\nTesting Tsl2561 at address %02x: %sfound\n", tsl.address(), ok ? "" : "NOT "));
if( ok ) { if( ok ) {
if( testPackage(tsl) ) { if( testPackage(tsl) ) {
testSensitivity(tsl, Tsl2561::GAIN_OFF, Tsl2561::EXP_402); testSensitivity(tsl, Tsl2561::GAIN_OFF, Tsl2561::EXP_402);
@ -160,4 +172,3 @@ void loop() {
Serial.println("\nNext test in 5s\n"); Serial.println("\nNext test in 5s\n");
delay(5000); delay(5000);
} }

View File

@ -21,6 +21,17 @@ This file is part of the Joba_Tsl2561 Library.
#include <Tsl2561Util.h> #include <Tsl2561Util.h>
// to mimic Serial.printf() of esp8266 core for other platforms
char *format( const char *fmt, ... ) {
static char buf[128];
va_list arg;
va_start(arg, fmt);
vsnprintf(buf, sizeof(buf), fmt, arg);
buf[sizeof(buf)-1] = '\0';
va_end(arg);
return buf;
}
Tsl2561::address_t addr[] = { Tsl2561::ADDR_GND, Tsl2561::ADDR_FLOAT, Tsl2561::ADDR_VDD }; Tsl2561::address_t addr[] = { Tsl2561::ADDR_GND, Tsl2561::ADDR_FLOAT, Tsl2561::ADDR_VDD };
Tsl2561 Tsl(Wire); Tsl2561 Tsl(Wire);
@ -58,18 +69,19 @@ void loop() {
Tsl.fullLuminosity(scaledFull); Tsl.fullLuminosity(scaledFull);
Tsl.irLuminosity(scaledIr); Tsl.irLuminosity(scaledIr);
Serial.printf("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, gain: %d, exp: %d", addr[i], id, scaledFull, scaledIr, gain, exposure); Serial.print(format("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, gain: %d, exp: %d",
addr[i], id, scaledFull, scaledIr, gain, exposure));
if( Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) ) { if( Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) ) {
if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id)) ) { if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id)) ) {
Serial.printf(", full: %5u, ir: %5u, lux: %5u.%03u\n", full, ir, milliLux/1000, milliLux%1000); Serial.print(format(", full: %5lu, ir: %5lu, lux: %5lu.%03lu\n", (unsigned long)full, (unsigned long)ir, (unsigned long)milliLux/1000, (unsigned long)milliLux%1000));
} }
else { else {
Serial.printf(", full: %5u, ir: %5u: Tsl2561Util::milliLux() error\n", full, ir); Serial.print(format(", full: %5lu, ir: %5lu: Tsl2561Util::milliLux() error\n", (unsigned long)full, (unsigned long)ir));
} }
} }
else { else {
Serial.printf(", full: %5u, ir: %5u: Tsl2561Util::normalizedLuminosity() error\n", full, ir); Serial.print(format(", full: %5lu, ir: %5lu: Tsl2561Util::normalizedLuminosity() error\n", (unsigned long)full, (unsigned long)ir));
} }
Tsl.off(); Tsl.off();
@ -84,4 +96,3 @@ void loop() {
delay(5000); delay(5000);
} }

View File

@ -0,0 +1,61 @@
; PlatformIO Project Configuration File
;
; Example config for flashing nodemcuv2 boards via linux serial port
;
; Adapt (e.g. platform, board, port) to your environment as needed.
; Then call platformio.sh to copy the file to all examples.
; Now cd to the example directory (e.g. Autogain/) and do "pio run"
; to build it or directly upload with "pio run --target upload".
; Watch the serial output of your sketch with "pio device monitor".
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
[platformio]
src_dir = .
lib_dir = ../..
; uncomment one, if you want to build only one
; env_default = nodemcuv2
; env_default = nano328
[env:nodemcuv2]
; TSL <-> ESP8266
; ------------
; GND <-> GND
; VCC <-> 3V
; SCL <-> D1
; SDA <-> D2
platform = espressif8266
board = nodemcuv2
framework = arduino
build_flags = -Wall
monitor_speed = 115200
upload_speed = 230400
upload_resetmethod = nodemcu
;usually upload port is autodetected
;upload_port = /dev/ttyUSB[1-9]
[env:nano328]
; TSL <-> NANO
; ------------
; GND <-> GND
; VCC <-> 3V3
; SCL <-> A5
; SDA <-> A4
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Wall
monitor_speed = 115200
;upload_port = /dev/ttyUSB[1-9]

View File

@ -0,0 +1,12 @@
#!/bin/bash
#
# Create platformio.ini templates for all examples, if missing.
# Start this script from within the examples directory.
for d in *; do
if [ -d "$d" -a -f "$d/$d.ino" -a ! -e "$d/platformio.ini" ]
then
cp -av platformio.ini "$d/"
fi
done

View File

@ -0,0 +1,36 @@
This directory is intended for the project specific (private) libraries.
PlatformIO will compile them to static libraries and link to executable file.
The source code of each library should be placed in separate directory, like
"lib/private_lib/[here are source files]".
For example, see how can be organized `Foo` and `Bar` libraries:
|--lib
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |- readme.txt --> THIS FILE
|- platformio.ini
|--src
|- main.c
Then in `src/main.c` you should use:
#include <Foo.h>
#include <Bar.h>
// rest H/C/CPP code
PlatformIO will find your libraries automatically, configure preprocessor's
include paths and build them.
More information about PlatformIO Library Dependency Finder
- http://docs.platformio.org/page/librarymanager/ldf.html

View File

@ -1,6 +1,6 @@
{ {
"name": "Joba_Tsl2561", "name": "Joba_Tsl2561",
"version": "2.0.1", "version": "2.0.7",
"keywords": "twowire, i2c, bus, sensor, luminosity, illuminance, lux", "keywords": "twowire, i2c, bus, sensor, luminosity, illuminance, lux",
"description": "Arduino Library for ams (taos) luminance chip Tsl2561 with autogain", "description": "Arduino Library for ams (taos) luminance chip Tsl2561 with autogain",
"repository": "repository":

View File

@ -1,5 +1,5 @@
name=Joba Tsl2561 Library name=Joba Tsl2561 Library
version=2.0.1 version=2.0.7
author=joba-1 author=joba-1
maintainer=joba-1 <joban123.psn@gmail.com> maintainer=joba-1 <joban123.psn@gmail.com>
sentence=IoT library for using the Tsl2561 luminosity sensor sentence=IoT library for using the Tsl2561 luminosity sensor

View File

@ -0,0 +1,58 @@
; PlatformIO Project Configuration File
;
; Example config for flashing nodemcuv2 boards via linux serial port
;
; Adapt (e.g. platform, board, port) to your environment as needed.
; Then call platformio.sh to copy the file to all examples.
; Now cd to the example directory (e.g. Autogain/) and do "pio run"
; to build it or directly upload with "pio run --target upload".
; Watch the serial output of your sketch with "pio device monitor".
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
[platformio]
; uncomment one, if you want to build only one
; env_default = nodemcuv2
; env_default = nano328
[env:nodemcuv2]
; TSL <-> ESP8266
; ------------
; GND <-> GND
; VCC <-> 3V
; SCL <-> D1
; SDA <-> D2
platform = espressif8266
board = nodemcuv2
framework = arduino
build_flags = -Wall
monitor_speed = 115200
upload_speed = 230400
upload_resetmethod = nodemcu
;usually upload port is autodetected
;upload_port = /dev/ttyUSB[1-9]
[env:nano328]
; TSL <-> NANO
; ------------
; GND <-> GND
; VCC <-> 3V3
; SCL <-> A5
; SDA <-> A4
platform = atmelavr
board = nanoatmega328
framework = arduino
build_flags = -Wall
monitor_speed = 115200

View File

@ -48,24 +48,30 @@ bool Tsl2561::begin() {
bool Tsl2561::readByte( register_t reg, uint8_t &val ) { bool Tsl2561::readByte( register_t reg, uint8_t &val ) {
_wire.beginTransmission(_addr); _wire.beginTransmission(_addr);
_wire.write(reg | CONTROL_CMD); _wire.write(reg | CONTROL_CMD);
if( _wire.endTransmission(false) == ERR_OK ) { if( (_status = static_cast<status_t>(_wire.endTransmission(false))) == ERR_OK ) {
if( _wire.requestFrom(_addr, 1) ) { if( _wire.requestFrom(_addr, 1) == 1 ) {
val = static_cast<uint8_t>(_wire.read()); val = static_cast<uint8_t>(_wire.read());
} }
else {
_status = ERR_RW;
} }
return (_status = static_cast<status_t>(_wire.endTransmission())) == ERR_OK; }
return _status == ERR_OK;
} }
bool Tsl2561::readWord( register_t reg, uint16_t &val ) { bool Tsl2561::readWord( register_t reg, uint16_t &val ) {
_wire.beginTransmission(_addr); _wire.beginTransmission(_addr);
_wire.write(reg | CONTROL_CMD); _wire.write(reg | CONTROL_CMD);
if( _wire.endTransmission(false) == ERR_OK ) { if( (_status = static_cast<status_t>(_wire.endTransmission(false))) == ERR_OK ) {
if( _wire.requestFrom(_addr, 2) ) { if( _wire.requestFrom(_addr, 2) == 2 ) {
val = (uint16_t)_wire.read() & 0xff; val = static_cast<uint16_t>(_wire.read()) & 0xff;
val |= ((uint16_t)_wire.read() & 0xff) << 8; val |= (static_cast<uint16_t>(_wire.read()) & 0xff) << 8;
}
else {
_status = ERR_RW;
} }
} }
return (_status = static_cast<status_t>(_wire.endTransmission())) == ERR_OK; return _status == ERR_OK;
} }
bool Tsl2561::writeByte( register_t reg, uint8_t val ) { bool Tsl2561::writeByte( register_t reg, uint8_t val ) {

View File

@ -39,22 +39,22 @@ bool normalizedLuminosity( bool gain, Tsl2561::exposure_t exposure, uint32_t &fu
switch( exposure ) { switch( exposure ) {
case Tsl2561::EXP_14: case Tsl2561::EXP_14:
full = (scaledFull >= 5047/4*3) ? ~0 : ((full + 5) * 322) / 11; full = (scaledFull >= 5047/4*3) ? 0xffffffff : ((full + 5) * 322) / 11;
ir = (scaledIr >= 5047/4*3) ? ~0 : ((ir + 5) * 322) / 11; ir = (scaledIr >= 5047/4*3) ? 0xffffffff : ((ir + 5) * 322) / 11;
break; break;
case Tsl2561::EXP_101: case Tsl2561::EXP_101:
full = (scaledFull >= 37177/4*3) ? ~0 : ((full + 40) * 322) / 81; full = (scaledFull >= 37177/4*3) ? 0xffffffff : ((full + 40) * 322) / 81;
ir = (scaledIr >= 37177/4*3) ? ~0 : ((ir + 40) * 322) / 81; ir = (scaledIr >= 37177/4*3) ? 0xffffffff : ((ir + 40) * 322) / 81;
break; break;
case Tsl2561::EXP_402: case Tsl2561::EXP_402:
if( scaledFull >= 65535/4*3 ) full = ~0; if( scaledFull >= 65535/4*3 ) full = 0xffffffff;
if( scaledIr >= 65535/4*3 ) ir = ~0; if( scaledIr >= 65535/4*3 ) ir = 0xffffffff;
break; break;
default: default:
return false; return false;
} }
return full != ~0U && ir != ~0U; return full != 0xffffffff && ir != 0xffffffff;
} }
return false; return false;
@ -72,9 +72,9 @@ uint16_t getLimit( Tsl2561::exposure_t exposure ) {
// Wait for one measurement interval plus some empirically tested extra millis // Wait for one measurement interval plus some empirically tested extra millis
void waitNext( Tsl2561::exposure_t exposure ) { void waitNext( Tsl2561::exposure_t exposure ) {
switch( exposure ) { switch( exposure ) {
case Tsl2561::EXP_14: delay(16); break; case Tsl2561::EXP_14: delay(Tsl2561Util::DELAY_EXP_14); break;
case Tsl2561::EXP_101: delay(103); break; case Tsl2561::EXP_101: delay(Tsl2561Util::DELAY_EXP_101); break;
default: delay(408); break; default: delay(Tsl2561Util::DELAY_EXP_402); break;
} }
} }
@ -95,7 +95,7 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
// get current sensitivity // get current sensitivity
if( !tsl.getSensitivity(gain, exposure) ) { if( !tsl.getSensitivity(gain, exposure) ) {
return false; return false; // I2C error
} }
// find index of current sensitivity // find index of current sensitivity
@ -111,11 +111,13 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
} }
// in a loop wait for next sample, get values and adjust sensitivity if needed // in a loop wait for next sample, get values and adjust sensitivity if needed
uint8_t retryOnSaturated = 10;
while( true ) { while( true ) {
waitNext(exposure); waitNext(exposure);
if( !tsl.fullLuminosity(full) || !tsl.irLuminosity(ir) ) { if( !tsl.fullLuminosity(full) || !tsl.irLuminosity(ir) ) {
return false; return false; // I2C error
} }
uint16_t limit = getLimit(exposure); uint16_t limit = getLimit(exposure);
@ -126,31 +128,49 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
if( (full < 1000 && ++curr < sizeof(sensitivity)/sizeof(sensitivity[0])) if( (full < 1000 && ++curr < sizeof(sensitivity)/sizeof(sensitivity[0]))
|| (full > limit && curr-- > 0) ) { || (full > limit && curr-- > 0) ) {
if( !tsl.setSensitivity(sensitivity[curr].gain, sensitivity[curr].exposure) ) { if( !tsl.setSensitivity(sensitivity[curr].gain, sensitivity[curr].exposure) ) {
return false; return false; // I2C error
} }
gain = sensitivity[curr].gain; gain = sensitivity[curr].gain;
exposure = sensitivity[curr].exposure; exposure = sensitivity[curr].exposure;
} }
else { else {
if( ++curr > 0 && retryOnSaturated-- == 0 ) {
return true; // saturated, but best we can do return true; // saturated, but best we can do
} }
} }
}
} }
// Measurement is up to 20% too high for temperatures above 25°C. Compensate for that. // Measurement is up to 20% too high for temperatures above 25°C. Compensate for that.
bool compensateTemperature( int16_t centiCelsius, uint32_t &full, uint32_t &ir ) { bool compensateTemperature( int16_t centiCelsius, uint32_t &full, uint32_t &ir ) {
// assume linear gradient 0% at 25°C to +20% at 70°C // assume linear gradient 0% at 25°C to +20% at 70°C
if( centiCelsius >= -3000 && centiCelsius <= 7000 ) { if( centiCelsius >= -3000 && centiCelsius <= 7000 ) {
full -= (full * (centiCelsius - 2500) * 20) / (100 * (7000 - 2500)); full -= (full * (centiCelsius - 2500)) / (5 * (7000 - 2500));
ir -= (ir * (centiCelsius - 2500) * 20) / (100 * (7000 - 2500)); ir -= (ir * (centiCelsius - 2500)) / (5 * (7000 - 2500));
return true; return true;
} }
return false; return false;
} }
// Round num after valid digits
uint32_t significance( uint32_t num, uint8_t digits ) {
uint8_t len = 1;
uint32_t n = num;
while( n /= 10 ) {
len++;
}
uint32_t e10 = 1;
while( len-- > digits ) {
e10 *= 10;
}
return ((num + e10 / 2) / e10) * e10;
}
// Calculate lux from raw luminosity values // Calculate lux from raw luminosity values
bool milliLux( uint32_t full, uint32_t ir, uint32_t &mLux, bool csType ) { bool milliLux( uint32_t full, uint32_t ir, uint32_t &mLux, bool csType, uint8_t digits ) {
if( !full ) { if( !full ) {
mLux = 0; mLux = 0;
return true; return true;
@ -187,6 +207,8 @@ bool milliLux( uint32_t full, uint32_t ir, uint32_t &mLux, bool csType ) {
mLux /= 400 * 16 / 193; // 33 = counts/lux (cpl) mLux /= 400 * 16 / 193; // 33 = counts/lux (cpl)
} }
mLux = significance(mLux, digits); // only the first 4 digits seem to make sense.
return true; return true;
} }

View File

@ -24,6 +24,14 @@ This file is part of the Joba_Tsl2561 Library.
namespace Tsl2561Util { namespace Tsl2561Util {
// Some chips may need higher values.
// Tweak here if autogain does not return valid results.
typedef enum {
DELAY_EXP_14 = 20, // Max. delay in ms after
DELAY_EXP_101 = 110, // starting a measurement until
DELAY_EXP_402 = 430 // the first values arrive.
} delay_t;
// delay until next sample is available // delay until next sample is available
void waitNext( Tsl2561::exposure_t exposure ); void waitNext( Tsl2561::exposure_t exposure );
@ -40,9 +48,11 @@ namespace Tsl2561Util {
// adjust luminosity according to sensor temperature (max +/-20% from 25°C) // adjust luminosity according to sensor temperature (max +/-20% from 25°C)
bool compensateTemperature( int16_t centiCelsius, uint32_t &full, uint32_t &ir ); bool compensateTemperature( int16_t centiCelsius, uint32_t &full, uint32_t &ir );
// calculate lux from normalized (and optionally temperature adjusted) luminosity // helper function to round after significant digits (~4 digits for Tsl2561)
bool milliLux( uint32_t full, uint32_t ir, uint32_t &milliLux, bool csType = false ); uint32_t significance( uint32_t value, uint8_t digits );
// calculate lux from normalized (and optionally temperature adjusted) luminosity
bool milliLux( uint32_t full, uint32_t ir, uint32_t &milliLux, bool csType = false, uint8_t digits = 4 );
}; };
#endif #endif

View File

@ -1,4 +1,5 @@
/* 6.1.0a /* 6.1.0a
* Remove TSL2561 debug message and update library (#2415)
* Change SHT1x sensor initialization from pre-teleperiod to once during restart to fix I2C interference * Change SHT1x sensor initialization from pre-teleperiod to once during restart to fix I2C interference
* Add wifi and mqtt status led blinkyblinky to be disabled by SetOption31 1. Does not work when LedPower is On (deliberate) (#871, #2230, #3114, #3155) * Add wifi and mqtt status led blinkyblinky to be disabled by SetOption31 1. Does not work when LedPower is On (deliberate) (#871, #2230, #3114, #3155)
* Add experimental (untested) TM1638 switch support (#2226) * Add experimental (untested) TM1638 switch support (#2226)

View File

@ -63,9 +63,9 @@ void Tsl2561Show(boolean json)
&& Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) && Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr)
&& Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id))) { && Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id))) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_ILLUMINANCE " g:%d, e:%d, f:%u, i:%u -> %u.%03u " D_UNIT_LUX), // snprintf_P(log_data, sizeof(log_data), PSTR(D_ILLUMINANCE " g:%d, e:%d, f:%u, i:%u -> %u.%03u " D_UNIT_LUX),
gain, exposure, full, ir, milliLux/1000, milliLux%1000); // gain, exposure, full, ir, milliLux/1000, milliLux%1000);
AddLog(LOG_LEVEL_DEBUG); // AddLog(LOG_LEVEL_DEBUG);
if (json) { if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"TSL2561\":{\"" D_JSON_ILLUMINANCE "\":%u.%03u}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"TSL2561\":{\"" D_JSON_ILLUMINANCE "\":%u.%03u}"),