mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-11 17:14:27 +00:00
[TSL2591] Perform async reading of sensor prevent blocking calls
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
@@ -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!?"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user