mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-12 01:24:04 +00:00
[VL53L0x] Make reading sensor async
This commit is contained in:
+21
-13
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<P110_data_struct *>(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<P110_data_struct *>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user