Skip to content

Commit

Permalink
Merge pull request letscontrolit#5041 from tonhuisman/feature/P110-P1…
Browse files Browse the repository at this point in the history
…13-Add-direction-option

[P110]/[P113] Add Direction value, optimizations
  • Loading branch information
TD-er authored May 30, 2024
2 parents 65cad6b + 8d1c4db commit 4f1f471
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 89 deletions.
24 changes: 18 additions & 6 deletions docs/source/Plugin/P110.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ Configuration

.. image:: P110_DeviceConfiguration.png

**Name** A unique name should be entered here.
* **Name** A unique name should be entered here.

**Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources.
* **Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources.

I2C Options
^^^^^^^^^^^^

The available settings here depend on the build used. At least the **Force Slow I2C speed** option is available, but selections for the I2C Multiplexer can also be shown. For details see the :ref:`Hardware_page`

**I2C Address**: The address the device is using. Some boards holding this chip offer an extra connection SDO that can be used to select the address, other boards just allow to select the secondary address and keep that active until the next power-cycle of the sensor.
* **I2C Address**: The address the device is using. Some boards holding this chip offer an extra connection SDO that can be used to select the address, other boards just allow to select the secondary address and keep that active until the next power-cycle of the sensor.

Device Settings
^^^^^^^^^^^^^^^^

**Timing**: The timing setting of the sensor determines the accuracy of the measurement. There are 3 options available:
* **Timing**: The timing setting of the sensor determines the accuracy of the measurement. There are 3 options available:

.. image:: P110_TimingOptions.png

Expand All @@ -55,20 +55,30 @@ Device Settings

*Accurate* A slower but far more accurate measurement (320 msec.) For use with a longer read interval setting (30-60 sec).

**Range**: the measuring ranges:
* **Range**: the measuring ranges:

.. image:: P110_RangeOptions.png

*Normal* For measurements in the 0 to 800 millimeter range.

*Long* For measurements in the 0 to 2000 millimeter range (but somewhat less accurate).

* **Send event when value unchanged**: When checked, will generate events for every **Interval**, when unchecked *and* **Interval** is set to 0, a change in **Distance** will immediately trigger events. (NB: Behavior changed since 2024/04/27, when this option was added)

* **Trigger delta** To avoid triggering many events with only a small difference in distance the 'Trigger delta' option is available. This can be set to only trigger an event when the new distance is at least the delta less or more than the previous measurement.

NB: This setting is ignored if 'Send event when value unchanged' is checked!
n
The Data Acquisition, Send to Controller and Interval settings are standard available configuration items. Send to Controller only when one or more Controllers are configured.

``Interval`` can now be set to 0, causing events to only be generated when changed, with ``Trigger delta`` calculated in.

Values
^^^^^^

There is only 1 value available for this sensor, with the default name ``Distance``. A formula can be set to recalculate, f.e. to centimeters using ``%value%/10``. The number of decimals is by default set to 2, but for use with millimeters distance it can be set to 0, as no decimals are provided from the measurement.
There are 2 values available for this sensor, with the default name ``Distance`` and ``Direction``. A formula can be set to recalculate the distance, f.e. to centimeters using ``%value%/10``. The number of decimals can be set to 0, when using millimeters, as no decimals are provided from the measurement.

Value ``Direction`` holds the direction relative to the *previous* distance value: ``-1`` = smaller distance, ``0`` = unchanged distance, ``1`` = greater distance.

.. Events
.. ~~~~~~
Expand All @@ -83,6 +93,8 @@ Change log
.. versionchanged:: 2.0
...

|added| 2024-04-27 Add options for ``Send event when value unchanged`` and ``Trigger delta``, causing somewhat changed behavior.

|added| 2021-02-06 Moved to main repository Plugin 110 from PluginPlayground Plugin 133

|added| 2021-02-06 Refactoring to allow multiple instances of the plugin (when using an I2C multiplexer)
Binary file modified docs/source/Plugin/P110_DeviceConfiguration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/source/Plugin/P110_RangeOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/source/Plugin/P110_TimingOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 14 additions & 9 deletions docs/source/Plugin/P113.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ Configuration

.. image:: P113_DeviceConfiguration.png

**Name** A unique name should be entered here.
* **Name** A unique name should be entered here.

**Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources.
* **Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources.

I2C Options
^^^^^^^^^^^^

The available settings here depend on the build used. At least the **Force Slow I2C speed** option is available, but selections for the I2C Multiplexer can also be shown. For details see the :ref:`Hardware_page`

**I2C Address**: The address the device is using. Because of an issue with changing the I2C address of the sensor, this list is limited to 1 item, and the address isn't changed/set.
* **I2C Address**: The address the device is using. Because of an issue with changing the I2C address of the sensor, this list is limited to 1 item, and the address isn't changed/set.

Device Settings
^^^^^^^^^^^^^^^^

**Timing**: The timing setting of the sensor determines the accuracy of the measurement. There are 6 options available:
* **Timing**: The timing setting of the sensor determines the accuracy of the measurement. There are 6 options available:

.. image:: P113_TimingOptions.png

Expand All @@ -63,32 +63,34 @@ Device Settings

*500ms* The longest integration time available. For use with long read interval settings.

**Range**: the measuring ranges:
* **Range**: the measuring ranges:

.. image:: P113_RangeOptions.png

*Normal (~130cm)* For measurements in the 0 to 1300 millimeter (130cm) range.

*Long (~400cm)* For measurements in the 0 to 4000 millimeter (400cm) range (but somewhat less accurate).

**Send event when value unchanged** To avoid many of the same events when the measurement is stable, this option is off by default. When enabled, every measurement will cause an event, and send the data to any enabled Controller.
* **Send event when value unchanged** To avoid many of the same events when the measurement is stable, this option is off by default. When enabled, every measurement will cause an event, and send the data to any enabled Controller.

**Trigger delta** To avoid triggering many events with only a small difference in distance the 'Trigger delta' option is available. This can be set to only trigger an event when the new distance is at least the delta less or more than the previous measurement.
* **Trigger delta** To avoid triggering many events with only a small difference in distance the 'Trigger delta' option is available. This can be set to only trigger an event when the new distance is at least the delta less or more than the previous measurement.

NB: This setting is ignored if 'Send event when value unchanged' is checked!


The Data Acquisition, Send to Controller and Interval settings are standard available configuration items. Send to Controller only when one or more Controllers are configured.

**Interval** By default, Interval will be set to 60 sec. Setting this to 1 or 2 seconds, usually offers a reasonable response time.
* **Interval** By default, Interval will be set to 60 sec. Setting this to 1 or 2 seconds, usually offers a reasonable response time.

Values
^^^^^^

The measured distance is available in ``Distance``. A formula can be set to recalculate, f.e. to centimeters using ``%value%/10``. The number of decimals is by default set to 2, but for use with millimeters distance it can be set to 0, as no decimals are provided from the measurement.
The measured distance is available in ``Distance``. A formula can be set to recalculate, f.e. to centimeters using ``%value%/10``. The number of decimals can be set to 0, when using millimeters, as no decimals are provided from the measurement.

The Ambient lighting condition during measurement is available in ``Ambient``. The unit is kcps (Photons per second, recalculated to kilo count per second)

Value ``Direction`` holds the direction relative to the *previous* distance value: ``-1`` = smaller distance, ``0`` = unchanged distance, ``1`` = greater distance.

.. Events
.. ~~~~~~
Expand All @@ -100,5 +102,8 @@ Change log
----------

.. versionchanged:: 2.0
...

|added| 2024-04-27 Add value ``Direction``.

|added| 2021-04-05 Added to main repository as Plugin 113 Distance - VL53L1X (400cm), based on a copy of Plugin 110 Distance - VL53L0X (200cm)
Binary file modified docs/source/Plugin/P113_DeviceConfiguration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/source/Plugin/P113_RangeOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/source/Plugin/P113_TimingOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 54 additions & 12 deletions src/_P110_VL53L0X.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
// ###################################### [email protected] ##########################################
// #######################################################################################################

// Changelog:
// 2022-06-22, tonhuisman: Remove delay() call from begin(), handle delay via PLUGIN_FIFTY_PER_SECOND
// Reformat source (uncrustify)
// 2021-04-05, tonhuisman: Removed check for VL53L1X as that is not compatible with this driver (Got its own plugin P113)
// 2021-02-06, tonhuisman: Refactored to use PluginStruct to enable multiple-instance use with an I2C Multiplexer
// 2021-01-07, tonhuisman: Moved from PluginPlayground (P133) to main repo (P110), fixed some issues
/** Changelog:
* 2024-04-27 tonhuisman: Read sensor asynchronously to enable (the new default) trigger on changed value
* 2024-04-26 tonhuisman: Migrate 'Send event when value unchanged' and 'Trigger delta' settings from P113 (at last...)
* Add Direction value, -1 = closer, 0 = unchanged, 1 = further away
* 2022-06-22 tonhuisman: Remove delay() call from begin(), handle delay via PLUGIN_FIFTY_PER_SECOND
* Reformat source (uncrustify)
* 2021-04-05 tonhuisman: Removed check for VL53L1X as that is not compatible with this driver (Got its own plugin P113)
* 2021-02-06 tonhuisman: Refactored to use PluginStruct to enable multiple-instance use with an I2C Multiplexer
* 2021-01-07 tonhuisman: Moved from PluginPlayground (P133) to main repo (P110), fixed some issues
*/

// needs VL53L0X library from pololu https://github.com/pololu/vl53l0x-arduino

Expand All @@ -21,6 +25,7 @@
#define PLUGIN_ID_110 110
#define PLUGIN_NAME_110 "Distance - VL53L0X (200cm)"
#define PLUGIN_VALUENAME1_110 "Distance"
#define PLUGIN_VALUENAME2_110 "Direction"


///////////////////////////
Expand All @@ -42,9 +47,10 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string)
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].ValueCount = 2;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].TimerOptional = true;
Device[deviceCount].GlobalSyncOption = true;
Device[deviceCount].PluginStats = true;
break;
Expand All @@ -59,6 +65,7 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string)
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_110));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_110));
break;
}

Expand All @@ -78,14 +85,14 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string)
break;
}

# if FEATURE_I2C_GET_ADDRESS
#if FEATURE_I2C_GET_ADDRESS
case PLUGIN_I2C_GET_ADDRESS:
{
event->Par1 = P110_I2C_ADDRESS;
success = true;
break;
}
# endif // if FEATURE_I2C_GET_ADDRESS
#endif // if FEATURE_I2C_GET_ADDRESS

case PLUGIN_WEBFORM_LOAD:
{
Expand All @@ -105,6 +112,14 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string)
const int optionValuesMode3[2] = { 0, 1 };
addFormSelector(F("Range"), F("prange"), 2, optionsMode3, optionValuesMode3, P110_RANGE);
}
addFormCheckBox(F("Send event when value unchanged"), F("notchanged"), P110_SEND_ALWAYS == 1);
addFormNote(F("When checked, 'Trigger delta' setting is ignored!"));

addFormNumericBox(F("Trigger delta"), F("delta"), P110_DELTA, 0, 100);
addUnit(F("0-100mm"));
#ifndef LIMIT_BUILD_SIZE
addFormNote(F("Minimal change in Distance to trigger an event."));
#endif // ifndef LIMIT_BUILD_SIZE

success = true;
break;
Expand All @@ -115,6 +130,8 @@ boolean Plugin_110(uint8_t function, struct EventStruct *event, String& string)
P110_I2C_ADDRESS = getFormItemInt(F("i2cAddr"));
P110_TIMING = getFormItemInt(F("ptiming"));
P110_RANGE = getFormItemInt(F("prange"));
P110_SEND_ALWAYS = isFormItemChecked(F("notchanged")) ? 1 : 0;
P110_DELTA = getFormItemInt(F("delta"));

success = true;
break;
Expand All @@ -133,12 +150,37 @@ 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) {
long dist = P110_data->readDistance();
const uint16_t dist = P110_data->getDistance();
const uint16_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));

#ifdef P110_INFO_LOG

success = P110_data->isReadSuccessful();
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
addLog(LOG_LEVEL_INFO, strformat(F("VL53L0x: Perform read: trig: %d, prev: %d, dist: %d"), triggered, p_dist, dist));
}
#endif // ifdef P110_INFO_LOG

if (success) {
if (triggered || (P110_SEND_ALWAYS == 1)) {
UserVar.setFloat(event->TaskIndex, 0, dist); // Value is classified as invalid when > 8190, so no conversion or 'split' needed
UserVar.setFloat(event->TaskIndex, 1, direct);
success = true;
}
}
break;
}

case PLUGIN_TEN_PER_SECOND: // Handle sensor reading
{
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
Scheduler.schedule_task_device_timer(event->TaskIndex, millis() + 10);
}
}
break;
Expand Down
Loading

0 comments on commit 4f1f471

Please sign in to comment.