diff --git a/lib/VL53L0X/src/VL53L0X.cpp b/lib/VL53L0X/src/VL53L0X.cpp index 5ad482cf7..72ef0173e 100644 --- a/lib/VL53L0X/src/VL53L0X.cpp +++ b/lib/VL53L0X/src/VL53L0X.cpp @@ -832,12 +832,16 @@ uint16_t VL53L0X::readRangeContinuousMillimeters() start_timeout_ms = millis(); while (!loop(distance)) { if (VL53L0X_NOT_WAITING == distance) { - return 65535; + return 65535u; } } if (VL53L0X_TIMEOUT == distance) { - return 65535; + return 65535u; + } + if (VL53L0X_WAITING == distance) + { + return 65534u; } return distance; } @@ -869,6 +873,11 @@ bool VL53L0X::asyncReadRangeSingleMillimeters(int16_t& distance) return false; } +bool VL53L0X::asyncReadRangeContinuousMillimeters(int16_t& distance) +{ + return loop(distance); +} + // Performs a single-shot range measurement and returns the reading in // millimeters // based on VL53L0X_PerformSingleRangingMeasurement() @@ -1100,7 +1109,6 @@ bool VL53L0X::loop(int16_t& distance) { } case state_e::waitMeasurement: { - distance = VL53L0X_WAITING; if ((readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0) { if (timePassedSince > io_timeout) { distance = VL53L0X_TIMEOUT; @@ -1108,17 +1116,17 @@ bool VL53L0X::loop(int16_t& distance) { start_timeout_ms = millis(); return true; } - } else { - // assumptions: Linearity Corrective Gain is 1000 (default); - // fractional ranging is not enabled - distance = readReg16Bit(RESULT_RANGE_STATUS + 10); - - writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01); - did_timeout = false; - start_timeout_ms = millis(); - return true; + distance = VL53L0X_WAITING; + return false; } - return false; + // assumptions: Linearity Corrective Gain is 1000 (default); + // fractional ranging is not enabled + distance = readReg16Bit(RESULT_RANGE_STATUS + 10); + + writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01); + did_timeout = false; + start_timeout_ms = millis(); + return true; } } return true; diff --git a/lib/VL53L0X/src/VL53L0X.h b/lib/VL53L0X/src/VL53L0X.h index af80a7870..4b2c4d3fa 100644 --- a/lib/VL53L0X/src/VL53L0X.h +++ b/lib/VL53L0X/src/VL53L0X.h @@ -197,6 +197,11 @@ public: // Valid distance when distance >= 0 bool asyncReadRangeSingleMillimeters(int16_t& distance); + // Check if new sample is ready. + // Return true when measurement has finished or aborted. + // Valid distance when distance >= 0 + bool asyncReadRangeContinuousMillimeters(int16_t& distance); + private: enum class state_e { diff --git a/src/_P110_VL53L0X.ino b/src/_P110_VL53L0X.ino index aa778ad5f..5f7224824 100644 --- a/src/_P110_VL53L0X.ino +++ b/src/_P110_VL53L0X.ino @@ -142,7 +142,10 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string) initPluginTaskData(event->TaskIndex, new (std::nothrow) P110_data_struct(P110_I2C_ADDRESS, P110_TIMING, P110_RANGE == 1)); P110_data_struct *P110_data = static_cast(getPluginTaskData(event->TaskIndex)); - success = (nullptr != P110_data) && P110_data->begin(); // Start the sensor + if (nullptr != P110_data) { + const uint32_t interval_ms = Settings.TaskDeviceTimer[event->TaskIndex] * 1000; + success = P110_data->begin(interval_ms); // Start the sensor + } break; } case PLUGIN_READ: @@ -151,8 +154,8 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string) if (nullptr != P110_data) { if (P110_data->isReadSuccessful()) { - const uint16_t dist = P110_data->getDistance(); - const uint16_t p_dist = UserVar.getFloat(event->TaskIndex, 0); + const int16_t dist = P110_data->getDistance(); + const int16_t p_dist = UserVar.getFloat(event->TaskIndex, 0); const int16_t direct = dist == p_dist ? 0 : (dist < p_dist ? -1 : 1); const bool triggered = (dist > (p_dist + P110_DELTA)) || (dist < (p_dist - P110_DELTA)); @@ -178,10 +181,7 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string) P110_data_struct *P110_data = static_cast(getPluginTaskData(event->TaskIndex)); if (nullptr != P110_data) { - P110_data->readDistance(); - - if (P110_data->isReadSuccessful() && (Settings.TaskDeviceTimer[event->TaskIndex] == 0)) { // Trigger as soon as there's a valid - // measurement and 0 interval is set + if (P110_data->readDistance() >= 0) { Scheduler.schedule_task_device_timer(event->TaskIndex, millis() + 10); } } diff --git a/src/src/PluginStructs/P110_data_struct.cpp b/src/src/PluginStructs/P110_data_struct.cpp index 01e9a0c05..78949eb3b 100644 --- a/src/src/PluginStructs/P110_data_struct.cpp +++ b/src/src/PluginStructs/P110_data_struct.cpp @@ -10,7 +10,7 @@ P110_data_struct::P110_data_struct(uint8_t i2c_addr, int timing, bool range) : // **************************************************************************/ // Initialize VL53L0X // **************************************************************************/ -bool P110_data_struct::begin() { +bool P110_data_struct::begin(uint32_t interval_ms) { _timeToWait = 0; _initPhase = P110_initPhases::Undefined; sensor.setAddress(_i2cAddress); // Initialize for configured address @@ -39,6 +39,8 @@ bool P110_data_struct::begin() { _initPhase = P110_initPhases::InitDelay; _timeToWait = millis() + _timing + 50; + sensor.startContinuous(interval_ms); + return true; } @@ -52,8 +54,10 @@ bool P110_data_struct::plugin_fifty_per_second() { return true; } -int16_t P110_data_struct::getDistance() const { - return _distance; +int16_t P110_data_struct::getDistance() { + const int res = _distance; + _distance = P110_DISTANCE_WAITING; + return res; } int16_t P110_data_struct::readDistance() { @@ -61,6 +65,15 @@ int16_t P110_data_struct::readDistance() { return P110_DISTANCE_UNINITIALIZED; } + const uint16_t dist = sensor.readRangeContinuousMillimeters(); + + if (dist == 65534) { + // Just waiting + // No need to keep sending many logs per second + return P110_DISTANCE_WAITING; + } + + # ifdef P110_DEBUG_LOG if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { @@ -69,35 +82,28 @@ int16_t P110_data_struct::readDistance() { } # endif // P110_DEBUG_LOG - const uint16_t dist = sensor.readRangeSingleMillimeters(); - if (sensor.timeoutOccurred()) { # ifdef P110_DEBUG_LOG addLog(LOG_LEVEL_DEBUG, F("VL53L0X: TIMEOUT")); # endif // P110_DEBUG_LOG - _distance = P110_DISTANCE_READ_TIMEOUT; + return P110_DISTANCE_READ_TIMEOUT; } else if (dist == 0xFFFF) { # ifdef P110_DEBUG_LOG addLog(LOG_LEVEL_DEBUG, F("VL53L0X: NO MEASUREMENT: 0xFFFF")); # endif // P110_DEBUG_LOG - _distance = P110_DISTANCE_READ_ERROR; + return P110_DISTANCE_READ_ERROR; } else if (dist >= 8190u) { # ifdef P110_DEBUG_LOG addLog(LOG_LEVEL_DEBUG, concat(F("VL53L0X: NO MEASUREMENT: "), dist)); # endif // P110_DEBUG_LOG - _distance = P110_DISTANCE_OUT_OF_RANGE; - } else { - _distance = dist; - } - -# ifdef P110_INFO_LOG - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - addLogMove(LOG_LEVEL_INFO, strformat(F("VL53L0X: Addr: 0x%02x / Timing: %d / Long Range: %d / success: %d / Distance: %d"), - _i2cAddress, _timing, _range, success, dist)); - } -# endif // P110_INFO_LOG + return P110_DISTANCE_OUT_OF_RANGE; + } + // Only keep a copy of actual distance readings. + // Since the distance reading is later called from PLUGIN_READ, + // we might have had a new reading inbetween which could be a "still waiting" + // value and then we lost the actual reading. + _distance = dist; return _distance; } diff --git a/src/src/PluginStructs/P110_data_struct.h b/src/src/PluginStructs/P110_data_struct.h index e8bdf5fd6..fa2c2cf4f 100644 --- a/src/src/PluginStructs/P110_data_struct.h +++ b/src/src/PluginStructs/P110_data_struct.h @@ -25,12 +25,14 @@ # define P110_DISTANCE_READ_TIMEOUT -2 # define P110_DISTANCE_READ_ERROR -3 # define P110_DISTANCE_OUT_OF_RANGE -4 +# define P110_DISTANCE_WAITING -5 enum class P110_initPhases : uint8_t { - Ready = 0x00, - InitDelay = 0x01, - Undefined = 0xFF + Undefined = 0xFF, + InitDelay = 0x00, + Ready = 0x01, + WaitMeasurement = 0x02 }; struct P110_data_struct : public PluginTaskData_base { @@ -42,9 +44,9 @@ public: P110_data_struct() = delete; virtual ~P110_data_struct() = default; - bool begin(); + bool begin(uint32_t interval_ms); int16_t readDistance(); - int16_t getDistance() const; + int16_t getDistance(); bool isReadSuccessful() const; bool plugin_fifty_per_second();