2021-04-02 18:04:10 +02:00
|
|
|
/*
|
|
|
|
* That usermod implements support of simple hand gestures with VL53L0X sensor: on/off and brightness correction.
|
|
|
|
* It can be useful for kitchen strips to avoid any touches.
|
|
|
|
* - on/off - just swipe a hand below your sensor ("shortPressAction" is called and can be customized through WLED macros)
|
|
|
|
* - brightness correction - keep your hand below sensor for 1 second to switch to "brightness" mode.
|
|
|
|
* Configure brightness by changing distance to the sensor (see parameters below for customization).
|
|
|
|
* "macroLongPress" is also called here.
|
|
|
|
*
|
|
|
|
* Enabling this mod usermod:
|
|
|
|
* 1. Attach VL53L0X sensor to i2c pins according to default pins for your board.
|
|
|
|
* 2. Add "-D USERMOD_VL53L0X_GESTURES" to your build flags at platformio.ini (plaformio_override.ini) for needed environment.
|
|
|
|
* In my case, for example: build_flags = ${common.build_flags_esp8266} -D RLYPIN=12 -D USERMOD_VL53L0X_GESTURES
|
|
|
|
* 3. Add "pololu/VL53L0X" dependency to lib_deps like this:
|
|
|
|
* lib_deps = ${env.lib_deps}
|
|
|
|
* pololu/VL53L0X @ ^1.3.0
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "wled.h"
|
|
|
|
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <VL53L0X.h>
|
|
|
|
|
2022-02-01 09:33:57 +01:00
|
|
|
#ifdef ARDUINO_ARCH_ESP32
|
|
|
|
#define HW_PIN_SCL 22
|
|
|
|
#define HW_PIN_SDA 21
|
|
|
|
#else
|
|
|
|
#define HW_PIN_SCL 5
|
|
|
|
#define HW_PIN_SDA 4
|
|
|
|
#endif
|
|
|
|
|
2021-04-02 18:04:10 +02:00
|
|
|
#ifndef VL53L0X_MAX_RANGE_MM
|
|
|
|
#define VL53L0X_MAX_RANGE_MM 230 // max height in millimiters to react for motions
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef VL53L0X_MIN_RANGE_OFFSET
|
|
|
|
#define VL53L0X_MIN_RANGE_OFFSET 60 // minimal range in millimiters that sensor can detect. Used in long motions to correct brightnes calculation.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef VL53L0X_DELAY_MS
|
|
|
|
#define VL53L0X_DELAY_MS 100 // how often to get data from sensor
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef VL53L0X_LONG_MOTION_DELAY_MS
|
|
|
|
#define VL53L0X_LONG_MOTION_DELAY_MS 1000 // how often to get data from sensor
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class UsermodVL53L0XGestures : public Usermod {
|
|
|
|
private:
|
|
|
|
//Private class members. You can declare variables and functions only accessible to your usermod here
|
|
|
|
unsigned long lastTime = 0;
|
|
|
|
VL53L0X sensor;
|
2022-02-01 09:33:57 +01:00
|
|
|
bool enabled = true;
|
2021-04-02 18:04:10 +02:00
|
|
|
|
|
|
|
bool wasMotionBefore = false;
|
|
|
|
bool isLongMotion = false;
|
|
|
|
unsigned long motionStartTime = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
void setup() {
|
2022-02-01 09:33:57 +01:00
|
|
|
PinManagerPinType pins[2] = { { HW_PIN_SCL, true }, { HW_PIN_SDA, true } };
|
|
|
|
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
|
2021-04-02 18:04:10 +02:00
|
|
|
Wire.begin();
|
|
|
|
|
|
|
|
sensor.setTimeout(150);
|
|
|
|
if (!sensor.init())
|
|
|
|
{
|
|
|
|
DEBUG_PRINTLN(F("Failed to detect and initialize VL53L0X sensor!"));
|
|
|
|
} else {
|
|
|
|
sensor.setMeasurementTimingBudget(20000); // set high speed mode
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void loop() {
|
2022-02-01 09:33:57 +01:00
|
|
|
if (!enabled || strip.isUpdating()) return;
|
2021-04-02 18:04:10 +02:00
|
|
|
if (millis() - lastTime > VL53L0X_DELAY_MS)
|
|
|
|
{
|
|
|
|
lastTime = millis();
|
|
|
|
|
|
|
|
int range = sensor.readRangeSingleMillimeters();
|
|
|
|
DEBUG_PRINTF(F("range: %d, brightness: %d"), range, bri);
|
|
|
|
|
|
|
|
if (range < VL53L0X_MAX_RANGE_MM)
|
|
|
|
{
|
|
|
|
if (!wasMotionBefore)
|
|
|
|
{
|
|
|
|
motionStartTime = millis();
|
|
|
|
DEBUG_PRINTF(F("motionStartTime: %d"), motionStartTime);
|
|
|
|
}
|
|
|
|
wasMotionBefore = true;
|
|
|
|
|
|
|
|
if (millis() - motionStartTime > VL53L0X_LONG_MOTION_DELAY_MS) //long motion
|
|
|
|
{
|
|
|
|
DEBUG_PRINTF(F("long motion: %d"), motionStartTime);
|
|
|
|
if (!isLongMotion)
|
|
|
|
{
|
|
|
|
if (macroLongPress)
|
|
|
|
{
|
|
|
|
applyMacro(macroLongPress);
|
|
|
|
}
|
|
|
|
isLongMotion = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set brightness according to range
|
|
|
|
bri = (VL53L0X_MAX_RANGE_MM - max(range, VL53L0X_MIN_RANGE_OFFSET)) * 255 / (VL53L0X_MAX_RANGE_MM - VL53L0X_MIN_RANGE_OFFSET);
|
|
|
|
DEBUG_PRINTF(F("new brightness: %d"), bri);
|
2022-02-16 21:12:33 +01:00
|
|
|
stateUpdated(1);
|
2021-04-02 18:04:10 +02:00
|
|
|
}
|
|
|
|
} else if (wasMotionBefore) { //released
|
|
|
|
long dur = millis() - motionStartTime;
|
|
|
|
|
|
|
|
if (!isLongMotion)
|
|
|
|
{ //short press
|
|
|
|
DEBUG_PRINTF(F("shortPressAction..."));
|
|
|
|
shortPressAction();
|
|
|
|
}
|
|
|
|
wasMotionBefore = false;
|
|
|
|
isLongMotion = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-01 09:33:57 +01:00
|
|
|
/*
|
|
|
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
|
|
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
|
|
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
|
|
|
*/
|
|
|
|
void addToConfig(JsonObject& root)
|
|
|
|
{
|
|
|
|
JsonObject top = root.createNestedObject("VL53L0x");
|
|
|
|
JsonArray pins = top.createNestedArray("pin");
|
|
|
|
pins.add(HW_PIN_SCL);
|
|
|
|
pins.add(HW_PIN_SDA);
|
|
|
|
}
|
|
|
|
|
2021-04-02 18:04:10 +02:00
|
|
|
/*
|
|
|
|
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
|
|
|
* This could be used in the future for the system to determine whether your usermod is installed.
|
|
|
|
*/
|
|
|
|
uint16_t getId()
|
|
|
|
{
|
|
|
|
return USERMOD_ID_VL53L0X;
|
|
|
|
}
|
|
|
|
};
|