[TSL2591] Perform async reading of sensor prevent blocking calls

This commit is contained in:
TD-er
2020-10-28 17:19:54 +01:00
parent cfe7d2f2cf
commit 46ee0ffe19
3 changed files with 109 additions and 30 deletions
+23
View File
@@ -250,6 +250,29 @@ uint32_t Adafruit_TSL2591::calculateLux(uint16_t ch0, uint16_t ch1)
return (uint32_t) calculateLuxf(ch0, ch1);
}
uint32_t Adafruit_TSL2591::getFullLuminosity (bool& finished)
{
const uint8_t status = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_STATUS);
// ALS Valid. Indicates that the ADC channels have completed an
// integration cycle since the AEN bit was asserted.
finished = status & 0x01;
if (!finished) {
return 0;
}
uint32_t x;
uint16_t y = 0;
y |= read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
x = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
x <<= 16;
x |= y;
disable();
return x;
}
uint32_t Adafruit_TSL2591::getFullLuminosity (void)
{
if (!_initialized)
+1
View File
@@ -163,6 +163,7 @@ class Adafruit_TSL2591 : public Adafruit_Sensor
void setTiming ( tsl2591IntegrationTime_t integration );
uint16_t getLuminosity (uint8_t channel );
uint32_t getFullLuminosity ( );
uint32_t getFullLuminosity (bool& finished);
tsl2591IntegrationTime_t getTiming();
tsl2591Gain_t getGain();
+85 -30
View File
@@ -61,7 +61,49 @@ struct P074_data_struct : public PluginTaskData_base {
}
}
// Return true when value is present.
bool getFullLuminosity(uint32_t & value) {
value = 0;
if (newValuePresent) {
// don't try to read a new value until the last one was processed.
return false;
}
if (!integrationActive) {
if (startIntegrationNeeded) {
// Fix to re-set the gain/timing before every read.
// See https://github.com/letscontrolit/ESPEasy/issues/3347
if (tsl.begin()) {
tsl.enable();
integrationStart = millis();
integrationActive = true;
startIntegrationNeeded = false;
}
}
return false; // Started integration, so no value possible yet.
}
bool finished = false;
value = tsl.getFullLuminosity(finished);
if (finished) {
integrationActive = false;
integrationStart = 0;
newValuePresent = true;
} else {
if (timePassedSince(integrationStart) > 1000) {
// Max integration time is 600 msec, so if we still have no value, reset the current state
integrationStart = 0;
integrationActive = false;
newValuePresent = false;
startIntegrationNeeded = true; // Apparently a value was needed
}
}
return finished;
}
Adafruit_TSL2591 tsl;
unsigned long integrationStart = 0;
bool integrationActive = false;
bool newValuePresent = false;
bool startIntegrationNeeded = false;
};
boolean Plugin_074(byte function, struct EventStruct *event, String& string) {
@@ -192,24 +234,14 @@ boolean Plugin_074(byte function, struct EventStruct *event, String& string) {
break;
}
case PLUGIN_READ: {
case PLUGIN_TEN_PER_SECOND: {
P074_data_struct *P074_data =
static_cast<P074_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr != P074_data) {
// Fix to re-set the gain/timing before every read.
// See https://github.com/letscontrolit/ESPEasy/issues/3347
if (!P074_data->tsl.begin()) {
break;
}
// Simple data read example. Just read the infrared, fullspecrtrum diode
// or 'visible' (difference between the two) channels.
float lux, full, visible, ir;
{
uint32_t fullLuminosity = P074_data->tsl.getFullLuminosity();
uint32_t fullLuminosity;
if (P074_data->getFullLuminosity(fullLuminosity)) {
float lux, full, visible, ir;
// TSL2591_FULLSPECTRUM: Reads two byte value from channel 0 (visible + infrared)
full = (fullLuminosity & 0xFFFF);
@@ -220,25 +252,48 @@ boolean Plugin_074(byte function, struct EventStruct *event, String& string) {
visible = ( (fullLuminosity & 0xFFFF) - (fullLuminosity >> 16));
lux = P074_data->tsl.calculateLuxf(full, ir); // get LUX
}
UserVar[event->BaseVarIndex + 0] = lux;
UserVar[event->BaseVarIndex + 1] = full;
UserVar[event->BaseVarIndex + 2] = visible;
UserVar[event->BaseVarIndex + 3] = ir;
UserVar[event->BaseVarIndex + 0] = lux;
UserVar[event->BaseVarIndex + 1] = full;
UserVar[event->BaseVarIndex + 2] = visible;
UserVar[event->BaseVarIndex + 3] = ir;
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("TSL2591: Lux: ");
log += String(lux);
log += F(" Full: ");
log += String(full);
log += F(" Visible: ");
log += String(visible);
log += F(" IR: ");
log += String(ir);
addLog(LOG_LEVEL_INFO, log);
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("TSL2591: Lux: ");
log += String(lux);
log += F(" Full: ");
log += String(full);
log += F(" Visible: ");
log += String(visible);
log += F(" IR: ");
log += String(ir);
addLog(LOG_LEVEL_INFO, log);
}
// Update was succesfull, schedule a read.
Scheduler.schedule_task_device_timer(event->TaskIndex, millis() + 10);
}
}
break;
}
case PLUGIN_READ: {
P074_data_struct *P074_data =
static_cast<P074_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr != P074_data) {
// PLUGIN_READ is either triggered by the task interval timer, or re-scheduled
// from PLUGIN_TEN_PER_SECOND when there is new data.
if (P074_data->newValuePresent) {
// Value was read in the PLUGIN_TEN_PER_SECOND call, just notify controllers.
P074_data->newValuePresent = false;
success = true;
} else {
if (!P074_data->integrationActive) {
// No reading in progress and no new value present, so must trigger a new reading.
P074_data->startIntegrationNeeded = true;
}
}
success = true;
} else {
addLog(LOG_LEVEL_ERROR, F("TSL2591: Sensor not initialized!?"));
}