From 601005f837a527291e642179bec1c965427f7061 Mon Sep 17 00:00:00 2001 From: Egor Chernodarov Date: Fri, 2 Apr 2021 23:04:10 +0700 Subject: [PATCH] Support of simple gestures for VL53L0X laser sensor --- usermods/VL53L0X_gestures/readme.md | 35 +++++ .../usermod_vl53l0x_gestures.h | 121 ++++++++++++++++++ wled00/const.h | 1 + wled00/usermods_list.cpp | 9 ++ wled00/wled.h | 2 +- 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 usermods/VL53L0X_gestures/readme.md create mode 100644 usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h diff --git a/usermods/VL53L0X_gestures/readme.md b/usermods/VL53L0X_gestures/readme.md new file mode 100644 index 00000000..dec84130 --- /dev/null +++ b/usermods/VL53L0X_gestures/readme.md @@ -0,0 +1,35 @@ +# Description + +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. + +## Installation + +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 below to `lib_deps` like this: +```ini +lib_deps = ${env.lib_deps} + pololu/VL53L0X @ ^1.3.0 +``` + +My entire `platformio_override.ini` for example (for nodemcu board): +```ini +[platformio] +default_envs = nodemcu + +[env:nodemcu] +board = nodemcu +platform = ${common.platform_wled_default} +platform_packages = ${common.platform_packages} +board_build.ldscript = ${common.ldscript_4m1m} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp8266} -D RLYPIN=12 -D USERMOD_VL53L0X_GESTURES +lib_deps = ${env.lib_deps} + pololu/VL53L0X @ ^1.3.0 +``` \ No newline at end of file diff --git a/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h b/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h new file mode 100644 index 00000000..83f26e08 --- /dev/null +++ b/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h @@ -0,0 +1,121 @@ +/* + * 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 +#include + +#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; + + bool wasMotionBefore = false; + bool isLongMotion = false; + unsigned long motionStartTime = 0; + + public: + + void setup() { + 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() { + 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); + colorUpdated(1); + } + } else if (wasMotionBefore) { //released + long dur = millis() - motionStartTime; + + if (!isLongMotion) + { //short press + DEBUG_PRINTF(F("shortPressAction...")); + shortPressAction(); + } + wasMotionBefore = false; + isLongMotion = false; + } + } + } + + /* + * 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; + } +}; \ No newline at end of file diff --git a/wled00/const.h b/wled00/const.h index 8ce63372..e6d6d1f3 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -32,6 +32,7 @@ #define USERMOD_ID_AUTO_SAVE 9 //Usermod "usermod_v2_auto_save.h" #define USERMOD_ID_DHT 10 //Usermod "usermod_dht.h" #define USERMOD_ID_MODE_SORT 11 //Usermod "usermod_v2_mode_sort.h" +#define USERMOD_ID_VL53L0X 12 //Usermod "usermod_vl53l0x_gestures.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 518aef3a..fb26c93e 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -45,6 +45,11 @@ #include "../usermods/DHT/usermod_dht.h" #endif +#ifdef USERMOD_VL53L0X_GESTURES +#include //it's needed here to correctly resolve dependencies +#include "../usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h" +#endif + void registerUsermods() { /* @@ -87,4 +92,8 @@ void registerUsermods() #ifdef USERMOD_DHT usermods.add(new UsermodDHT()); #endif + +#ifdef USERMOD_VL53L0X_GESTURES + usermods.add(new UsermodVL53L0XGestures()); +#endif } \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index 2fe5a792..dfee80cc 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -577,7 +577,7 @@ WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager()); #else #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTF(x) + #define DEBUG_PRINTF(x...) #endif #ifdef WLED_DEBUG_FS