7typedef TinyWire TwoWire;
12#include "helper/mup_i2c_registers.h"
117 String TSL2561_VERSION =
"0.1.0";
126 unsigned long basePollRateUs = 50000;
127 uint32_t pollRateMs = 2000;
128 uint32_t lastPollMs = 0;
129 enum FilterMode { FAST,
132 enum IntegrationMode { FAST13ms,
135 enum GainMode { LOW1x,
137 String firmwareVersion;
138 FilterMode filterMode;
139 IntegrationMode integrationMode;
143 double illuminanceValue, unitIlluminanceValue, lightCh0Value, IRCh1Value;
144 double unitIlluminanceSensitivity;
145 ustd::sensorprocessor illuminanceSensor = ustd::sensorprocessor(4, 600, 0.005);
146 ustd::sensorprocessor unitIlluminanceSensor = ustd::sensorprocessor(4, 600, 0.005);
147 ustd::sensorprocessor lightCh0Sensor = ustd::sensorprocessor(4, 600, 0.005);
148 ustd::sensorprocessor IRCh1Sensor = ustd::sensorprocessor(4, 600, 0.005);
149 bool bActive =
false;
151 IlluminanceTSL2561(String name, FilterMode filterMode = FilterMode::FAST, IntegrationMode integrationMode = IntegrationMode::LONGTERM402ms,
152 GainMode gainMode = GainMode::LOW1x, uint8_t i2cAddress = 0x39)
153 : name(name), filterMode(filterMode), integrationMode(integrationMode), gainMode(gainMode), i2cAddress(i2cAddress) {
159 unitIlluminanceSensitivity = 0.2;
161 setFilterMode(filterMode,
true);
174 return illuminanceValue;
181 return unitIlluminanceValue;
191 return unitIlluminanceSensitivity;
205 if (sensitivity <= 0.001) sensitivity = 0.2;
206 unitIlluminanceSensitivity = sensitivity;
209 void begin(Scheduler *_pSched, TwoWire *_pWire = &Wire, uint32_t _pollRateMs = 2000) {
212 pollRateMs = _pollRateMs;
215 pI2C =
new I2CRegisters(pWire, i2cAddress);
217 auto ft = [=]() { this->loop(); };
218 tID = pSched->add(ft, name, basePollRateUs);
220 auto fnall = [=](String topic, String msg, String originator) {
221 this->subsMsg(topic, msg, originator);
223 pSched->subscribe(tID, name +
"/sensor/#", fnall);
225 pI2C->lastError = pI2C->checkAddress(i2cAddress);
226 if (pI2C->lastError == I2CRegisters::I2CError::OK) {
228 if (TSLSensorGetRevID(&
id, &rev)) {
229 if (
id == 5 ||
id == 1) {
230 if (TSLSensorPower(
true)) {
233 Serial.println(
"TSL2561: Powered on, revision: " + String(rev));
235 if (TSLSensorGainIntegrationSet()) {
237 Serial.println(
"TSL2561: Integration- and Gain-Mode set.");
241 Serial.println(
"TSL2561: Integration- and Gain-Mode set ERROR.");
243 pI2C->lastError = I2CRegisters::I2C_WRITE_ERR_OTHER;
247 Serial.println(
"TSL2561: Power on failed");
249 pI2C->lastError = I2CRegisters::I2CError::I2C_WRITE_ERR_OTHER;
253 Serial.println(
"TSL2561: Bad sensor ID: " + String(
id) +
", expected: 1, revision: " + String(rev));
255 pI2C->lastError = I2CRegisters::I2CError::I2C_WRONG_HARDWARE_AT_ADDRESS;
259 Serial.println(
"TSL2561: Failed to get sensor ID, wrong hardware?");
261 pI2C->lastError = I2CRegisters::I2CError::I2C_WRONG_HARDWARE_AT_ADDRESS;
265 Serial.println(
"TSL2561: Failed to check I2C address, wrong address?");
267 pI2C->lastError = I2CRegisters::I2CError::I2C_DEVICE_NOT_AT_ADDRESS;
271 void setFilterMode(FilterMode mode,
bool silent =
false) {
275 illuminanceSensor.update(1, 2, 0.05);
276 unitIlluminanceSensor.update(1, 2, 0.1);
277 lightCh0Sensor.update(1, 2, 0.1);
278 IRCh1Sensor.update(1, 2, 0.1);
282 illuminanceSensor.update(4, 30, 0.1);
283 unitIlluminanceSensor.update(4, 30, 0.5);
284 lightCh0Sensor.update(4, 30, 0.5);
285 IRCh1Sensor.update(4, 30, 0.5);
289 filterMode = LONGTERM;
290 illuminanceSensor.update(10, 600, 0.1);
291 unitIlluminanceSensor.update(50, 600, 0.5);
292 lightCh0Sensor.update(50, 600, 0.5);
293 IRCh1Sensor.update(50, 600, 0.5);
300 void setGainIntegrationMode(GainMode gMode, IntegrationMode iMode,
bool silent =
false) {
302 integrationMode = iMode;
303 TSLSensorGainIntegrationSet();
306 publishIntegrationMode();
310 void setIntegrationMode(IntegrationMode mode,
bool silent =
false) {
311 integrationMode = mode;
312 TSLSensorGainIntegrationSet();
314 publishIntegrationMode();
317 void setGainMode(GainMode mode,
bool silent =
false) {
319 TSLSensorGainIntegrationSet();
325 void publishLightCh0() {
327 sprintf(buf,
"%6.3f", lightCh0Value);
328 pSched->publish(name +
"/sensor/lightch0", buf);
331 void publishIRCh1() {
333 sprintf(buf,
"%6.3f", IRCh1Value);
334 pSched->publish(name +
"/sensor/irch1", buf);
337 void publishIlluminance() {
339 sprintf(buf,
"%6.3f", illuminanceValue);
340 pSched->publish(name +
"/sensor/illuminance", buf);
343 void publishUnitIlluminance() {
345 sprintf(buf,
"%6.3f", unitIlluminanceValue);
346 pSched->publish(name +
"/sensor/unitilluminance", buf);
349 void publishUnitIlluminanceSensitivity() {
351 sprintf(buf,
"%6.3f", unitIlluminanceSensitivity);
352 pSched->publish(name +
"/sensor/unitilluminancesensitivity", buf);
355 void publishError(String errMsg) {
356 pSched->publish(name +
"/sensor/error", errMsg);
359 void publishFilterMode() {
360 switch (filterMode) {
361 case FilterMode::FAST:
362 pSched->publish(name +
"/sensor/mode",
"FAST");
364 case FilterMode::MEDIUM:
365 pSched->publish(name +
"/sensor/mode",
"MEDIUM");
367 case FilterMode::LONGTERM:
368 pSched->publish(name +
"/sensor/mode",
"LONGTERM");
373 void publishIntegrationMode() {
374 switch (integrationMode) {
375 case IntegrationMode::FAST13ms:
376 pSched->publish(name +
"/sensor/integration",
"FAST");
378 case IntegrationMode::MEDIUM101ms:
379 pSched->publish(name +
"/sensor/integration",
"MEDIUM");
381 case IntegrationMode::LONGTERM402ms:
382 pSched->publish(name +
"/sensor/integration",
"LONGTERM");
387 void publishGainMode() {
389 case GainMode::LOW1x:
390 pSched->publish(name +
"sensor/gain",
"LOW");
392 case GainMode::HIGH16x:
393 pSched->publish(name +
"sensor/gain",
"HIGH");
398 bool TSLSensorPower(
bool powerOn) {
400 if (!pI2C->writeRegisterByte(0x80, 0x03,
true))
return false;
402 if (!pI2C->writeRegisterByte(0x80, 0x00,
true))
return false;
407 bool TSLSensorGetRevID(uint8_t *pId, uint8_t *pRev) {
416 if (!pI2C->readRegisterByte(0x8a, &idbyte))
return false;
418 *pRev = idbyte & 0x0f;
422 bool TSLSensorGainIntegrationSet() {
425 case GainMode::LOW1x:
428 case GainMode::HIGH16x:
431 switch (integrationMode) {
432 case IntegrationMode::FAST13ms:
435 case IntegrationMode::MEDIUM101ms:
438 case IntegrationMode::LONGTERM402ms:
441 return pI2C->writeRegisterByte(0x81, mx,
true);
444 double calculateLux(uint16_t ch0, uint16_t ch1) {
450 if (ch0 == 0)
return 0;
451 if (ch0 > 65000 || ch1 > 65000)
return 10000.0;
453 double ratio = (double)ch1 / (
double)ch0;
455 lux = 0.0304 * (double)ch0 - 0.062 * (
double)ch0 * pow(ratio, 1.4);
456 }
else if (ratio <= 0.61) {
457 lux = 0.0224 * (double)ch0 - 0.031 * (
double)ch1;
458 }
else if (ratio <= 0.80) {
459 lux = 0.0128 * (double)ch0 - 0.0153 * (
double)ch1;
460 }
else if (ratio <= 1.30) {
461 lux = 0.00146 * (double)ch0 - 0.00112 * (
double)ch1;
468 bool readTSLSensorMeasurement(uint8_t reg,
double *pMeas) {
471 if (!pI2C->readRegisterWordLE(reg, &data,
true)) {
473 Serial.print(
"Failed to read TSL2561 at address 0x");
474 Serial.print(i2cAddress, HEX);
475 Serial.print(
" data: ");
476 Serial.print(data, HEX);
477 Serial.print(
" lasterr: ");
478 Serial.println(pI2C->lastError, HEX);
482 *pMeas = (double)data;
484 Serial.println(
"TSL2561 Measurement: " + String(data));
490 bool readTSLSensor(
double *pIlluminanceCh0,
double *pIlluminanceCh1,
491 double *pLux,
double *pUnitIlluminance) {
492 *pIlluminanceCh0 = 0.0;
493 *pIlluminanceCh1 = 0.0;
495 *pUnitIlluminance = 0.0;
496 if (!readTSLSensorMeasurement(0xac, pIlluminanceCh0))
return false;
497 if (!readTSLSensorMeasurement(0xae, pIlluminanceCh1))
return false;
498 *pLux = calculateLux(*pIlluminanceCh0, *pIlluminanceCh1);
501 ui = log(*pLux) * unitIlluminanceSensitivity;
505 if (ui < 0.0) ui = 0.0;
506 if (ui > 1.0) ui = 1.0;
507 *pUnitIlluminance = ui;
512 double illuminanceVal, unitIlluminanceVal, lightCh0Val, IRCh1Val;
513 if (timeDiff(lastPollMs, millis()) > pollRateMs) {
514 lastPollMs = millis();
516 if (readTSLSensor(&lightCh0Val, &IRCh1Val, &illuminanceVal, &unitIlluminanceVal)) {
517 if (lightCh0Sensor.filter(&lightCh0Val)) {
518 lightCh0Value = lightCh0Val;
521 if (IRCh1Sensor.filter(&IRCh1Val)) {
522 IRCh1Value = IRCh1Val;
525 if (illuminanceSensor.filter(&illuminanceVal)) {
526 illuminanceValue = illuminanceVal;
527 publishIlluminance();
529 if (unitIlluminanceSensor.filter(&unitIlluminanceVal)) {
530 unitIlluminanceValue = unitIlluminanceVal;
531 publishUnitIlluminance();
538 void subsMsg(String topic, String msg, String originator) {
539 if (topic == name +
"/sensor/illuminance/get") {
540 publishIlluminance();
541 }
else if (topic == name +
"/sensor/unitilluminance/get") {
542 publishUnitIlluminance();
543 }
else if (topic == name +
"/sensor/lightch0/get") {
545 }
else if (topic == name +
"/sensor/irch1/get") {
547 }
else if (topic == name +
"/sensor/mode/get") {
549 }
else if (topic == name +
"/sensor/mode/set") {
550 if (msg ==
"fast" || msg ==
"FAST") {
551 setFilterMode(FilterMode::FAST);
553 if (msg ==
"medium" || msg ==
"MEDIUM") {
554 setFilterMode(FilterMode::MEDIUM);
556 setFilterMode(FilterMode::LONGTERM);
559 }
else if (topic == name +
"/sensor/integration/get") {
560 publishIntegrationMode();
561 }
else if (topic == name +
"/sensor/integration/set") {
562 if (msg ==
"fast" || msg ==
"FAST") {
563 setIntegrationMode(IntegrationMode::FAST13ms);
565 if (msg ==
"medium" || msg ==
"MEDIUM") {
566 setIntegrationMode(IntegrationMode::MEDIUM101ms);
568 setIntegrationMode(IntegrationMode::LONGTERM402ms);
571 }
else if (topic == name +
"/sensor/gain/get") {
573 }
else if (topic == name +
"/sensor/gain/set") {
574 if (msg ==
"low" || msg ==
"LOW") {
575 setGainMode(GainMode::LOW1x);
577 setGainMode(GainMode::HIGH16x);
579 }
else if (topic == name +
"/sensor/unitilluminancesensitivity/set") {
581 }
else if (topic == name +
"/sensor/unitilluminancesensitivity/get") {
582 publishUnitIlluminanceSensitivity();
mupplet-sensor luminance with TSL2561
Definition: mup_illuminance_tsl2561.h:115
double getUnitIlluminanceSensitivity()
Definition: mup_illuminance_tsl2561.h:184
IlluminanceTSL2561(String name, FilterMode filterMode=FilterMode::FAST, IntegrationMode integrationMode=IntegrationMode::LONGTERM402ms, GainMode gainMode=GainMode::LOW1x, uint8_t i2cAddress=0x39)
Definition: mup_illuminance_tsl2561.h:151
void setUnitIlluminanceSensitivity(double sensitivity)
Definition: mup_illuminance_tsl2561.h:194
double getUnitIlluminance()
Definition: mup_illuminance_tsl2561.h:177
double getIlluminance()
Definition: mup_illuminance_tsl2561.h:170