Merge branch 'master' into dev
Conflicts: CHANGELOG.md package.json platformio.ini usermods/Temperature/usermod_temperature.h wled00/FX.cpp wled00/FX.h wled00/FX_fcn.cpp wled00/cfg.cpp wled00/data/index.js wled00/data/settings_leds.htm wled00/data/settings_time.htm wled00/data/style.css wled00/html_other.h wled00/html_settings.h wled00/html_ui.h wled00/ntp.cpp wled00/usermods_list.cpp wled00/wled.cpp wled00/wled.h
This commit is contained in:
commit
29e048af7b
19
CHANGELOG.md
19
CHANGELOG.md
@ -2,11 +2,30 @@
|
||||
|
||||
### Builds after release 0.12.0
|
||||
|
||||
#### Build 2104141
|
||||
|
||||
- Reduced memory usage by 540b by switching to a different trigonometric approximation
|
||||
|
||||
#### Build 2104140
|
||||
|
||||
- Added dynamic location-based Sunrise/Sunset macros (PR #1889)
|
||||
- Improved seasonal background handling (PR #1890)
|
||||
- Fixed instance discovery not working if MQTT not compiled in
|
||||
- Fixed Button, IR, Relay pin not assigned by default (resolves #1891)
|
||||
|
||||
#### Build 2104120
|
||||
|
||||
- Added switch support (button macro is switch closing action, long press macro switch opening)
|
||||
- Replaced Circus effect with new Running Dual effect (Circus is Tricolor Chase with Red/White/Black)
|
||||
- Fixed ledmap with multiple segments (PR #1864)
|
||||
|
||||
#### Build 2104030
|
||||
|
||||
- Fixed ESP32 crash on Drip effect with reversed segment (#1854)
|
||||
- Added flag `WLED_DISABLE_BROWNOUT_DET` to disable ESP32 brownout detector (off by default)
|
||||
|
||||
### WLED release 0.12.0
|
||||
|
||||
#### Build 2104020
|
||||
|
||||
- Allow clearing button/IR/relay pin on platforms that don't support negative numbers
|
||||
|
@ -178,7 +178,7 @@ upload_speed = 115200
|
||||
lib_compat_mode = strict
|
||||
lib_deps =
|
||||
fastled/FastLED @ 3.3.2
|
||||
NeoPixelBus @ 2.6.0
|
||||
NeoPixelBus @ ^2.6.0
|
||||
ESPAsyncTCP @ 1.2.0
|
||||
ESPAsyncUDP
|
||||
AsyncTCP @ 1.0.3
|
||||
@ -188,10 +188,10 @@ lib_deps =
|
||||
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
||||
#TFT_eSPI
|
||||
#For use SSD1306 OLED display uncomment following
|
||||
#U8g2@~2.27.2
|
||||
U8g2@~2.27.2
|
||||
#For Dallas sensor uncomment following 2 lines
|
||||
#OneWire@~2.3.5
|
||||
#milesburton/DallasTemperature@^3.9.0
|
||||
OneWire@~2.3.5
|
||||
milesburton/DallasTemperature@^3.9.0
|
||||
#For BME280 sensor uncomment following
|
||||
#BME280@~3.0.0
|
||||
; adafruit/Adafruit BMP280 Library @ 2.1.0
|
||||
@ -400,31 +400,7 @@ build_flags = ${common.build_flags_esp32} ${common.debug_flags} ${common.build_f
|
||||
# codm pixel controller board configurations
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
[env:codm-controller-0.4]
|
||||
board = esp_wroom_02
|
||||
platform = ${common.platform_wled_default}
|
||||
platform_packages = ${common.platform_packages}
|
||||
board_build.ldscript = ${common.ldscript_2m512k}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266} -D LEDPIN=3
|
||||
|
||||
[env:codm-controller-0.4-WS2801]
|
||||
board = esp_wroom_02
|
||||
platform = ${common.platform_wled_default}
|
||||
platform_packages = ${common.platform_packages}
|
||||
board_build.ldscript = ${common.ldscript_2m512k}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266} -D USE_WS2801 -D CLKPIN=13 -D DATAPIN=3
|
||||
|
||||
[env:codm-controller-0.4-APA102]
|
||||
board = esp_wroom_02
|
||||
platform = ${common.platform_wled_default}
|
||||
platform_packages = ${common.platform_packages}
|
||||
board_build.ldscript = ${common.ldscript_2m512k}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266} -D USE_APA102 -D CLKPIN=13 -D DATAPIN=3
|
||||
|
||||
[env:codm-controller-0.5]
|
||||
[env:codm-controller-0.6]
|
||||
board = esp_wroom_02
|
||||
platform = ${common.platform_wled_default}
|
||||
platform_packages = ${common.platform_packages}
|
||||
@ -432,18 +408,10 @@ board_build.ldscript = ${common.ldscript_2m512k}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266}
|
||||
|
||||
[env:codm-controller-0.5-WS2801]
|
||||
[env:codm-controller-0.6-rev2]
|
||||
board = esp_wroom_02
|
||||
platform = ${common.platform_wled_default}
|
||||
platform_packages = ${common.platform_packages}
|
||||
board_build.ldscript = ${common.ldscript_2m512k}
|
||||
board_build.ldscript = ${common.ldscript_4m1m}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266} -D USE_WS2801 #-D CLKPIN=0 -D DATAPIN=2
|
||||
|
||||
[env:codm-controller-0.5-APA102]
|
||||
board = esp_wroom_02
|
||||
platform = ${common.platform_wled_default}
|
||||
platform_packages = ${common.platform_packages}
|
||||
board_build.ldscript = ${common.ldscript_2m512k}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266} -D USE_APA102 #-D CLKPIN=0 -D DATAPIN=2
|
||||
build_flags = ${common.build_flags_esp8266}
|
||||
|
6
tools/WLED_ESP32_8MB.csv
Normal file
6
tools/WLED_ESP32_8MB.csv
Normal file
@ -0,0 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x200000,
|
||||
app1, app, ota_1, 0x210000,0x200000,
|
||||
spiffs, data, spiffs, 0x410000,0x3F0000,
|
|
@ -93,8 +93,8 @@ or remove them and put everything on one line.
|
||||
| segment-delay-ms | Delay (milliseconds) between switching on/off each step | 150 |
|
||||
| on-time-s | Time (seconds) the stairs stay lit after last detection | 5 |
|
||||
| bottom-echo-us | Detection range of ultrasonic sensor | 1749 |
|
||||
| bottomsensor | Manually trigger a down to up animation via API | false |
|
||||
| topsensor | Manually trigger an up to down animation via API | false |
|
||||
| bottom-sensor | Manually trigger a down to up animation via API | false |
|
||||
| top-sensor | Manually trigger an up to down animation via API | false |
|
||||
|
||||
|
||||
To read the current settings, open a browser to `http://xxx.xxx.xxx.xxx/json/state` (use your WLED
|
||||
@ -108,8 +108,8 @@ The staircase settings and sensor states are inside the WLED status element:
|
||||
"enabled": true,
|
||||
"segment-delay-ms": 150,
|
||||
"on-time-s": 5,
|
||||
"bottomsensor": false,
|
||||
"topsensor": false
|
||||
"bottom-sensor": false,
|
||||
"tops-ensor": false
|
||||
},
|
||||
}
|
||||
```
|
||||
@ -187,7 +187,7 @@ the API. To simulate triggering the bottom sensor, use:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" \
|
||||
-d '{"staircase":{"bottomsensor":true}}' \
|
||||
-d '{"staircase":{"bottom-sensor":true}}' \
|
||||
xxx.xxx.xxx.xxx/json/state
|
||||
```
|
||||
|
||||
@ -195,7 +195,7 @@ Likewise, to trigger the top sensor, use:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" \
|
||||
-d '{"staircase":{"topsensor":true}}' \
|
||||
-d '{"staircase":{"top-sensor":true}}' \
|
||||
xxx.xxx.xxx.xxx/json/state
|
||||
```
|
||||
|
||||
|
@ -12,10 +12,11 @@ private:
|
||||
// User-defined configuration
|
||||
#define Celsius // Show temperature mesaurement in Celcius. Comment out for Fahrenheit
|
||||
#define TemperatureDecimals 1 // Number of decimal places in published temperaure values
|
||||
#define HumidityDecimals 0 // Number of decimal places in published humidity values
|
||||
#define HumidityDecimals 2 // Number of decimal places in published humidity values
|
||||
#define PressureDecimals 2 // Number of decimal places in published pressure values
|
||||
#define TemperatureInterval 5 // Interval to measure temperature (and humidity, dew point if available) in seconds
|
||||
#define PressureInterval 300 // Interval to measure pressure in seconds
|
||||
#define PublishAlways 0 // Publish values even when they have not changed
|
||||
|
||||
// Sanity checks
|
||||
#if !defined(TemperatureDecimals) || TemperatureDecimals < 0
|
||||
@ -33,6 +34,9 @@ private:
|
||||
#if !defined(PressureInterval) || PressureInterval < 0
|
||||
#define PressureInterval TemperatureInterval
|
||||
#endif
|
||||
#if !defined(PublishAlways)
|
||||
#define PublishAlways 0
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32 // ESP32 boards
|
||||
uint8_t SCL_PIN = 22;
|
||||
@ -58,7 +62,7 @@ private:
|
||||
|
||||
BME280I2C bme{settings};
|
||||
|
||||
uint8_t SensorType;
|
||||
uint8_t sensorType;
|
||||
|
||||
// Measurement timers
|
||||
long timer;
|
||||
@ -66,11 +70,11 @@ private:
|
||||
long lastPressureMeasure = 0;
|
||||
|
||||
// Current sensor values
|
||||
float SensorTemperature;
|
||||
float SensorHumidity;
|
||||
float SensorHeatIndex;
|
||||
float SensorDewPoint;
|
||||
float SensorPressure;
|
||||
float sensorTemperature;
|
||||
float sensorHumidity;
|
||||
float sensorHeatIndex;
|
||||
float sensorDewPoint;
|
||||
float sensorPressure;
|
||||
// Track previous sensor values
|
||||
float lastTemperature;
|
||||
float lastHumidity;
|
||||
@ -96,13 +100,13 @@ private:
|
||||
|
||||
bme.read(_pressure, _temperature, _humidity, tempUnit, presUnit);
|
||||
|
||||
SensorTemperature = _temperature;
|
||||
SensorHumidity = _humidity;
|
||||
SensorPressure = _pressure;
|
||||
if (SensorType == 1)
|
||||
sensorTemperature = _temperature;
|
||||
sensorHumidity = _humidity;
|
||||
sensorPressure = _pressure;
|
||||
if (sensorType == 1)
|
||||
{
|
||||
SensorHeatIndex = EnvironmentCalculations::HeatIndex(_temperature, _humidity, envTempUnit);
|
||||
SensorDewPoint = EnvironmentCalculations::DewPoint(_temperature, _humidity, envTempUnit);
|
||||
sensorHeatIndex = EnvironmentCalculations::HeatIndex(_temperature, _humidity, envTempUnit);
|
||||
sensorDewPoint = EnvironmentCalculations::DewPoint(_temperature, _humidity, envTempUnit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +117,7 @@ public:
|
||||
|
||||
if (!bme.begin())
|
||||
{
|
||||
SensorType = 0;
|
||||
sensorType = 0;
|
||||
Serial.println("Could not find BME280I2C sensor!");
|
||||
}
|
||||
else
|
||||
@ -121,15 +125,15 @@ public:
|
||||
switch (bme.chipModel())
|
||||
{
|
||||
case BME280::ChipModel_BME280:
|
||||
SensorType = 1;
|
||||
sensorType = 1;
|
||||
Serial.println("Found BME280 sensor! Success.");
|
||||
break;
|
||||
case BME280::ChipModel_BMP280:
|
||||
SensorType = 2;
|
||||
sensorType = 2;
|
||||
Serial.println("Found BMP280 sensor! No Humidity available.");
|
||||
break;
|
||||
default:
|
||||
SensorType = 0;
|
||||
sensorType = 0;
|
||||
Serial.println("Found UNKNOWN sensor! Error!");
|
||||
}
|
||||
}
|
||||
@ -139,7 +143,7 @@ public:
|
||||
{
|
||||
// BME280 sensor MQTT publishing
|
||||
// Check if sensor present and MQTT Connected, otherwise it will crash the MCU
|
||||
if (SensorType != 0 && mqtt != nullptr)
|
||||
if (sensorType != 0 && mqtt != nullptr)
|
||||
{
|
||||
// Timer to fetch new temperature, humidity and pressure data at intervals
|
||||
timer = millis();
|
||||
@ -148,48 +152,48 @@ public:
|
||||
{
|
||||
lastTemperatureMeasure = timer;
|
||||
|
||||
UpdateBME280Data(SensorType);
|
||||
UpdateBME280Data(sensorType);
|
||||
|
||||
float Temperature = roundf(SensorTemperature * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||
float Humidity, HeatIndex, DewPoint;
|
||||
float temperature = roundf(sensorTemperature * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||
float humidity, heatIndex, dewPoint;
|
||||
|
||||
// If temperature has changed since last measure, create string populated with device topic
|
||||
// from the UI and values read from sensor, then publish to broker
|
||||
if (Temperature != lastTemperature)
|
||||
if (temperature != lastTemperature || PublishAlways)
|
||||
{
|
||||
String topic = String(mqttDeviceTopic) + "/temperature";
|
||||
mqttTemperaturePub = mqtt->publish(topic.c_str(), 0, false, String(Temperature, TemperatureDecimals).c_str());
|
||||
mqttTemperaturePub = mqtt->publish(topic.c_str(), 0, false, String(temperature, TemperatureDecimals).c_str());
|
||||
}
|
||||
|
||||
lastTemperature = Temperature; // Update last sensor temperature for next loop
|
||||
lastTemperature = temperature; // Update last sensor temperature for next loop
|
||||
|
||||
if (SensorType == 1) // Only if sensor is a BME280
|
||||
if (sensorType == 1) // Only if sensor is a BME280
|
||||
{
|
||||
Humidity = roundf(SensorHumidity * pow(10, HumidityDecimals)) / pow(10, HumidityDecimals);
|
||||
HeatIndex = roundf(SensorHeatIndex * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||
DewPoint = roundf(SensorDewPoint * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||
humidity = roundf(sensorHumidity * pow(10, HumidityDecimals)) / pow(10, HumidityDecimals);
|
||||
heatIndex = roundf(sensorHeatIndex * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||
dewPoint = roundf(sensorDewPoint * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||
|
||||
if (Humidity != lastHumidity)
|
||||
if (humidity != lastHumidity || PublishAlways)
|
||||
{
|
||||
String topic = String(mqttDeviceTopic) + "/humidity";
|
||||
mqtt->publish(topic.c_str(), 0, false, String(Humidity, HumidityDecimals).c_str());
|
||||
mqtt->publish(topic.c_str(), 0, false, String(humidity, HumidityDecimals).c_str());
|
||||
}
|
||||
|
||||
if (HeatIndex != lastHeatIndex)
|
||||
if (heatIndex != lastHeatIndex || PublishAlways)
|
||||
{
|
||||
String topic = String(mqttDeviceTopic) + "/heat_index";
|
||||
mqtt->publish(topic.c_str(), 0, false, String(HeatIndex, TemperatureDecimals).c_str());
|
||||
mqtt->publish(topic.c_str(), 0, false, String(heatIndex, TemperatureDecimals).c_str());
|
||||
}
|
||||
|
||||
if (DewPoint != lastDewPoint)
|
||||
if (dewPoint != lastDewPoint || PublishAlways)
|
||||
{
|
||||
String topic = String(mqttDeviceTopic) + "/dew_point";
|
||||
mqtt->publish(topic.c_str(), 0, false, String(DewPoint, TemperatureDecimals).c_str());
|
||||
mqtt->publish(topic.c_str(), 0, false, String(dewPoint, TemperatureDecimals).c_str());
|
||||
}
|
||||
|
||||
lastHumidity = Humidity;
|
||||
lastHeatIndex = HeatIndex;
|
||||
lastDewPoint = DewPoint;
|
||||
lastHumidity = humidity;
|
||||
lastHeatIndex = heatIndex;
|
||||
lastDewPoint = dewPoint;
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,15 +201,15 @@ public:
|
||||
{
|
||||
lastPressureMeasure = timer;
|
||||
|
||||
float Pressure = roundf(SensorPressure * pow(10, PressureDecimals)) / pow(10, PressureDecimals);
|
||||
float pressure = roundf(sensorPressure * pow(10, PressureDecimals)) / pow(10, PressureDecimals);
|
||||
|
||||
if (Pressure != lastPressure)
|
||||
if (pressure != lastPressure || PublishAlways)
|
||||
{
|
||||
String topic = String(mqttDeviceTopic) + "/pressure";
|
||||
mqttPressurePub = mqtt->publish(topic.c_str(), 0, true, String(Pressure, PressureDecimals).c_str());
|
||||
mqttPressurePub = mqtt->publish(topic.c_str(), 0, true, String(pressure, PressureDecimals).c_str());
|
||||
}
|
||||
|
||||
lastPressure = Pressure;
|
||||
lastPressure = pressure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ default_envs = d1_mini
|
||||
...
|
||||
[common]
|
||||
...
|
||||
lib_deps_external =
|
||||
lib_deps =
|
||||
...
|
||||
#For use SSD1306 OLED display uncomment following
|
||||
U8g2@~2.27.3
|
||||
@ -55,4 +55,4 @@ lib_deps_external =
|
||||
* Changed to use async, non-blocking implementation
|
||||
* Do not report low temperatures that indicate an error to mqtt
|
||||
* Disable plugin if temperature sensor not detected
|
||||
* Report the number of seconds until the first read in the info screen instead of sensor error
|
||||
* Report the number of seconds until the first read in the info screen instead of sensor error
|
||||
|
35
usermods/VL53L0X_gestures/readme.md
Normal file
35
usermods/VL53L0X_gestures/readme.md
Normal file
@ -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
|
||||
```
|
121
usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h
Normal file
121
usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h
Normal file
@ -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 <Wire.h>
|
||||
#include <VL53L0X.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
};
|
@ -4,7 +4,7 @@ default_envs = d1_mini
|
||||
|
||||
[env:esp32dev]
|
||||
board = esp32dev
|
||||
platform = espressif32@3.1.1
|
||||
platform = espressif32@3.2
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags =
|
||||
${common.build_flags_esp32}
|
||||
|
@ -418,28 +418,45 @@ uint16_t WS2812FX::mode_theater_chase_rainbow(void) {
|
||||
/*
|
||||
* Running lights effect with smooth sine transition base.
|
||||
*/
|
||||
uint16_t WS2812FX::running_base(bool saw) {
|
||||
uint16_t WS2812FX::running_base(bool saw, bool dual=false) {
|
||||
uint8_t x_scale = SEGMENT.intensity >> 2;
|
||||
uint32_t counter = (now * SEGMENT.speed) >> 9;
|
||||
|
||||
for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||
uint8_t s = 0;
|
||||
uint8_t a = i*x_scale - counter;
|
||||
uint16_t a = i*x_scale - counter;
|
||||
if (saw) {
|
||||
a &= 0xFF;
|
||||
if (a < 16)
|
||||
{
|
||||
a = 192 + a*8;
|
||||
} else {
|
||||
a = map(a,16,255,64,192);
|
||||
}
|
||||
a = 255 - a;
|
||||
}
|
||||
s = sin8(a);
|
||||
setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), s));
|
||||
uint8_t s = dual ? sin_gap(a) : sin8(a);
|
||||
uint32_t ca = color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s);
|
||||
if (dual) {
|
||||
uint16_t b = (SEGLEN-1-i)*x_scale - counter;
|
||||
uint8_t t = sin_gap(b);
|
||||
uint32_t cb = color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), t);
|
||||
ca = color_blend(ca, cb, 127);
|
||||
}
|
||||
setPixelColor(i, ca);
|
||||
}
|
||||
return FRAMETIME;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Running lights in opposite directions.
|
||||
* Idea: Make the gap width controllable with a third slider in the future
|
||||
*/
|
||||
uint16_t WS2812FX::mode_running_dual(void) {
|
||||
return running_base(false, true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Running lights effect with smooth sine transition.
|
||||
*/
|
||||
@ -1306,14 +1323,6 @@ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternating white/red/black pixels running. PLACEHOLDER
|
||||
*/
|
||||
uint16_t WS2812FX::mode_circus_combustus(void) {
|
||||
return tricolor_chase(RED, WHITE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tricolor chase mode
|
||||
*/
|
||||
@ -3060,7 +3069,7 @@ uint16_t WS2812FX::mode_drip(void)
|
||||
if (drops[j].colIndex==1) {
|
||||
if (drops[j].col>255) drops[j].col=255;
|
||||
setPixelColor(uint16_t(drops[j].pos),color_blend(BLACK,SEGCOLOR(0),drops[j].col));
|
||||
|
||||
|
||||
drops[j].col += map(SEGMENT.speed, 0, 255, 1, 6); // swelling
|
||||
|
||||
if (random8() < drops[j].col/10) { // random drop
|
||||
@ -3074,8 +3083,9 @@ uint16_t WS2812FX::mode_drip(void)
|
||||
if (drops[j].pos < 0) drops[j].pos = 0;
|
||||
drops[j].vel += gravity; // gravity is negative
|
||||
|
||||
for (uint8_t i=1;i<7-drops[j].colIndex;i++) { // some minor math so we don't expand bouncing droplets
|
||||
setPixelColor(constrain(uint16_t(drops[j].pos)+i,0,SEGLEN-1),color_blend(BLACK,SEGCOLOR(0),drops[j].col/i)); //spread pixel with fade while falling
|
||||
for (uint16_t i=1;i<7-drops[j].colIndex;i++) { // some minor math so we don't expand bouncing droplets
|
||||
uint16_t pos = constrain(uint16_t(drops[j].pos) +i, 0, SEGLEN-1); //this is BAD, returns a pos >= SEGLEN occasionally
|
||||
setPixelColor(pos,color_blend(BLACK,SEGCOLOR(0),drops[j].col/i)); //spread pixel with fade while falling
|
||||
}
|
||||
|
||||
if (drops[j].colIndex > 2) { // during bounce, some water is on the floor
|
||||
|
11
wled00/FX.h
11
wled00/FX.h
@ -166,7 +166,7 @@
|
||||
#define FX_MODE_POLICE_ALL 49
|
||||
#define FX_MODE_TWO_DOTS 50
|
||||
#define FX_MODE_TWO_AREAS 51
|
||||
#define FX_MODE_CIRCUS_COMBUSTUS 52
|
||||
#define FX_MODE_RUNNING_DUAL 52
|
||||
#define FX_MODE_HALLOWEEN 53
|
||||
#define FX_MODE_TRICOLOR_CHASE 54
|
||||
#define FX_MODE_TRICOLOR_WIPE 55
|
||||
@ -504,7 +504,7 @@ class WS2812FX {
|
||||
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_police_all;
|
||||
_mode[FX_MODE_TWO_DOTS] = &WS2812FX::mode_two_dots;
|
||||
_mode[FX_MODE_TWO_AREAS] = &WS2812FX::mode_two_areas;
|
||||
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
||||
_mode[FX_MODE_RUNNING_DUAL] = &WS2812FX::mode_running_dual;
|
||||
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
||||
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
||||
_mode[FX_MODE_TRICOLOR_WIPE] = &WS2812FX::mode_tricolor_wipe;
|
||||
@ -633,6 +633,7 @@ class WS2812FX {
|
||||
getMainSegmentId(void),
|
||||
gamma8(uint8_t),
|
||||
gamma8_cal(uint8_t, float),
|
||||
sin_gap(uint16_t),
|
||||
get_random_wheel_index(uint8_t);
|
||||
|
||||
int8_t
|
||||
@ -720,7 +721,7 @@ class WS2812FX {
|
||||
mode_police_all(void),
|
||||
mode_two_dots(void),
|
||||
mode_two_areas(void),
|
||||
mode_circus_combustus(void),
|
||||
mode_running_dual(void),
|
||||
mode_bicolor_chase(void),
|
||||
mode_tricolor_chase(void),
|
||||
mode_tricolor_wipe(void),
|
||||
@ -818,7 +819,7 @@ class WS2812FX {
|
||||
color_wipe(bool, bool),
|
||||
dynamic(bool),
|
||||
scan(bool),
|
||||
running_base(bool),
|
||||
running_base(bool,bool),
|
||||
larson_scanner(bool),
|
||||
sinelon_base(bool,bool),
|
||||
dissolve(uint32_t),
|
||||
@ -872,7 +873,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
||||
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
|
||||
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Aurora","Stream",
|
||||
"Scanner","Lighthouse","Fireworks","Rain","Tetrix","Fire Flicker","Gradient","Loading","Police","Police All",
|
||||
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||
"Two Dots","Two Areas","Running Dual","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
||||
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
|
||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
||||
|
@ -207,7 +207,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
|
||||
for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
|
||||
uint16_t indexSet = realIndex + (IS_REVERSE ? -j : j);
|
||||
if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) { // watch for group out of bounds condition
|
||||
if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) {
|
||||
if (IS_MIRROR) { //set the corresponding mirrored pixel
|
||||
uint16_t indexMir = SEGMENT.stop + SEGMENT.start - indexSet - 1;
|
||||
if (indexMir < customMappingSize) indexMir = customMappingTable[indexMir];
|
||||
@ -765,6 +765,12 @@ uint16_t WS2812FX::triwave16(uint16_t in)
|
||||
return 0xFFFF - (in - 0x8000)*2;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::sin_gap(uint16_t in) {
|
||||
if (in & 0x100) return 0;
|
||||
//if (in > 255) return 0;
|
||||
return sin8(in + 192); //correct phase shift of sine so that it starts and stops at 0
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates a tristate square wave w/ attac & decay
|
||||
* @param x input value 0-255
|
||||
|
@ -4,6 +4,8 @@
|
||||
* Physical IO
|
||||
*/
|
||||
|
||||
#define WLED_DEBOUNCE_THRESHOLD 50 //only consider button input of at least 50ms as valid (debouncing)
|
||||
|
||||
void shortPressAction()
|
||||
{
|
||||
if (!macroButton)
|
||||
@ -25,10 +27,42 @@ bool isButtonPressed()
|
||||
}
|
||||
|
||||
|
||||
void handleSwitch()
|
||||
{
|
||||
if (buttonPressedBefore != isButtonPressed()) {
|
||||
buttonPressedTime = millis();
|
||||
buttonPressedBefore = !buttonPressedBefore;
|
||||
}
|
||||
|
||||
if (buttonLongPressed == buttonPressedBefore) return;
|
||||
|
||||
if (millis() - buttonPressedTime > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce)
|
||||
if (buttonPressedBefore) { //LOW, falling edge, switch closed
|
||||
if (macroButton) applyPreset(macroButton);
|
||||
else { //turn on
|
||||
if (!bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);}
|
||||
}
|
||||
} else { //HIGH, rising edge, switch opened
|
||||
if (macroLongPress) applyPreset(macroLongPress);
|
||||
else { //turn off
|
||||
if (bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);}
|
||||
}
|
||||
}
|
||||
buttonLongPressed = buttonPressedBefore; //save the last "long term" switch state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleButton()
|
||||
{
|
||||
if (btnPin<0 || !buttonEnabled) return;
|
||||
if (btnPin<0 || buttonType < BTN_TYPE_PUSH) return;
|
||||
|
||||
|
||||
if (buttonType == BTN_TYPE_SWITCH) { //button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NO gpio0)
|
||||
handleSwitch(); return;
|
||||
}
|
||||
|
||||
//momentary button logic
|
||||
if (isButtonPressed()) //pressed
|
||||
{
|
||||
if (!buttonPressedBefore) buttonPressedTime = millis();
|
||||
@ -48,7 +82,7 @@ void handleButton()
|
||||
else if (!isButtonPressed() && buttonPressedBefore) //released
|
||||
{
|
||||
long dur = millis() - buttonPressedTime;
|
||||
if (dur < 50) {buttonPressedBefore = false; return;} //too short "press", debounce
|
||||
if (dur < WLED_DEBOUNCE_THRESHOLD) {buttonPressedBefore = false; return;} //too short "press", debounce
|
||||
bool doublePress = buttonWaitTime;
|
||||
buttonWaitTime = 0;
|
||||
|
||||
|
@ -141,9 +141,9 @@ void deserializeConfig() {
|
||||
if (hw_led["rev"]) busses.getBus(0)->reversed = true; //set 0.11 global reversed setting for first bus
|
||||
|
||||
JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0];
|
||||
CJSON(buttonEnabled, hw_btn_ins_0["type"]);
|
||||
CJSON(buttonType, hw_btn_ins_0["type"]);
|
||||
int hw_btn_pin = hw_btn_ins_0["pin"][0];
|
||||
if (hw_btn_pin>=0 && pinManager.allocatePin(hw_btn_pin,false)) {
|
||||
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
||||
btnPin = hw_btn_pin;
|
||||
pinMode(btnPin, INPUT_PULLUP);
|
||||
} else {
|
||||
@ -159,7 +159,7 @@ void deserializeConfig() {
|
||||
|
||||
#ifndef WLED_DISABLE_INFRARED
|
||||
int hw_ir_pin = hw["ir"]["pin"] | -1; // 4
|
||||
if (hw_ir_pin >=0 && pinManager.allocatePin(hw_ir_pin,false)) {
|
||||
if (pinManager.allocatePin(hw_ir_pin,false)) {
|
||||
irPin = hw_ir_pin;
|
||||
} else {
|
||||
irPin = -1;
|
||||
@ -484,7 +484,7 @@ void serializeConfig() {
|
||||
|
||||
// button BTNPIN
|
||||
JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject();
|
||||
hw_btn_ins_0["type"] = (buttonEnabled) ? BTN_TYPE_PUSH : BTN_TYPE_NONE;
|
||||
hw_btn_ins_0["type"] = buttonType;
|
||||
|
||||
JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin");
|
||||
hw_btn_ins_0_pin.add(btnPin);
|
||||
|
@ -34,6 +34,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
|
||||
@ -136,7 +137,7 @@
|
||||
#define BTN_TYPE_RESERVED 1
|
||||
#define BTN_TYPE_PUSH 2
|
||||
#define BTN_TYPE_PUSH_ACT_HIGH 3 //not implemented
|
||||
#define BTN_TYPE_SWITCH 4 //not implemented
|
||||
#define BTN_TYPE_SWITCH 4
|
||||
#define BTN_TYPE_SWITCH_ACT_HIGH 5 //not implemented
|
||||
|
||||
//Ethernet board types
|
||||
|
@ -150,12 +150,12 @@ function loadBg(iUrl)
|
||||
if (iUrl == "") {
|
||||
var today = new Date();
|
||||
var hol = [
|
||||
[0,11,24,5,"https://aircoookie.github.io/xmas.png"], // christmas
|
||||
[0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas
|
||||
[0,2,17,1,"https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day
|
||||
[2022,3,16,3,"https://aircoookie.github.io/easter.png"],
|
||||
[2023,3,8,3,"https://aircoookie.github.io/easter.png"],
|
||||
[2024,2,30,3,"https://aircoookie.github.io/easter.png"]
|
||||
]
|
||||
[2022,3,17,2,"https://aircoookie.github.io/easter.png"],
|
||||
[2023,3,9,2,"https://aircoookie.github.io/easter.png"],
|
||||
[2024,2,31,2,"https://aircoookie.github.io/easter.png"]
|
||||
];
|
||||
for (var i=0; i<hol.length; i++) {
|
||||
var yr = hol[i][0]==0 ? today.getFullYear() : hol[i][0];
|
||||
var hs = new Date(yr,hol[i][1],hol[i][2]);
|
||||
|
@ -18,7 +18,12 @@ function GetV(){var d=document;}
|
||||
</div>
|
||||
<h2>Sync setup</h2>
|
||||
<h3>Button setup</h3>
|
||||
On/Off button enabled: <input type="checkbox" name="BT"><br>
|
||||
Button type:
|
||||
<select name=BT>
|
||||
<option value=0>Disabled</option>
|
||||
<option value=2>Pushbutton</option>
|
||||
<option value=4>Switch</option>
|
||||
</select><br>
|
||||
Infrared remote:
|
||||
<select name=IR>
|
||||
<option value=0>Disabled</option>
|
||||
|
@ -27,7 +27,7 @@
|
||||
ldS();
|
||||
}
|
||||
function check(o,k) {
|
||||
var n = o.name.substr(-6);
|
||||
var n = o.name.replace("[]","").substr(-4);
|
||||
if (o.type=="number" && n.substr(0,4)=="_pin") {
|
||||
for (var i=0; i<pins.length; i++) {
|
||||
if (k==pinO[i]) continue;
|
||||
|
@ -1,77 +1,77 @@
|
||||
body {
|
||||
font-family: Verdana, sans-serif;
|
||||
text-align: center;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
line-height: 200%;
|
||||
margin: 0;
|
||||
}
|
||||
hr {
|
||||
border-color: #666;
|
||||
}
|
||||
button {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
border: 0.3ch solid #333;
|
||||
border-radius: 24px;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 12px 8px 8px;
|
||||
padding: 8px 12px;
|
||||
min-width: 48px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.toprow {
|
||||
top: 0;
|
||||
position: sticky;
|
||||
background-color:#222;
|
||||
z-index:1;
|
||||
}
|
||||
.helpB {
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
}
|
||||
input {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
border: 0.5ch solid #333;
|
||||
}
|
||||
input[type="number"] {
|
||||
width: 4em;
|
||||
font-size: medium;
|
||||
margin: 2px;
|
||||
}
|
||||
input[type="number"].big {
|
||||
width: 80px;
|
||||
}
|
||||
input[type="number"].small {
|
||||
width: 40px;
|
||||
}
|
||||
select {
|
||||
margin: 2px;
|
||||
font-size: medium;
|
||||
}
|
||||
input[type="checkbox"] {
|
||||
/* Double-sized Checkboxes */
|
||||
-ms-transform: scale(2); /* IE */
|
||||
-moz-transform: scale(2); /* FF */
|
||||
-webkit-transform: scale(2); /* Safari and Chrome */
|
||||
-o-transform: scale(2); /* Opera */
|
||||
transform: scale(2);
|
||||
margin-right: 10px;
|
||||
}
|
||||
select {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
border: 0.5ch solid #333;
|
||||
}
|
||||
td {
|
||||
padding: 2px;
|
||||
}
|
||||
.d5 {
|
||||
width: 4.5em !important;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana, sans-serif;
|
||||
text-align: center;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
line-height: 200%;
|
||||
margin: 0;
|
||||
}
|
||||
hr {
|
||||
border-color: #666;
|
||||
}
|
||||
button {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
border: 0.3ch solid #333;
|
||||
border-radius: 24px;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 12px 8px 8px;
|
||||
padding: 8px 12px;
|
||||
min-width: 48px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.toprow {
|
||||
top: 0;
|
||||
position: sticky;
|
||||
background-color:#222;
|
||||
z-index:1;
|
||||
}
|
||||
.helpB {
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
}
|
||||
input {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
border: 0.5ch solid #333;
|
||||
}
|
||||
input[type="number"] {
|
||||
width: 4em;
|
||||
font-size: medium;
|
||||
margin: 2px;
|
||||
}
|
||||
input[type="number"].big {
|
||||
width: 80px;
|
||||
}
|
||||
input[type="number"].small {
|
||||
width: 40px;
|
||||
}
|
||||
select {
|
||||
margin: 2px;
|
||||
font-size: medium;
|
||||
}
|
||||
input[type="checkbox"] {
|
||||
/* Double-sized Checkboxes */
|
||||
-ms-transform: scale(2); /* IE */
|
||||
-moz-transform: scale(2); /* FF */
|
||||
-webkit-transform: scale(2); /* Safari and Chrome */
|
||||
-o-transform: scale(2); /* Opera */
|
||||
transform: scale(2);
|
||||
margin-right: 10px;
|
||||
}
|
||||
select {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
border: 0.5ch solid #333;
|
||||
}
|
||||
td {
|
||||
padding: 2px;
|
||||
}
|
||||
.d5 {
|
||||
width: 4.5em !important;
|
||||
}
|
||||
|
@ -221,9 +221,10 @@ var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki
|
||||
id="form_s" name="Sf" method="post"><div class="toprow"><div class="helpB">
|
||||
<button type="button" onclick="H()">?</button></div><button type="button"
|
||||
onclick="B()">Back</button><button type="submit">Save</button><hr></div><h2>
|
||||
Sync setup</h2><h3>Button setup</h3>On/Off button enabled: <input
|
||||
type="checkbox" name="BT"><br>Infrared remote: <select name="IR"><option
|
||||
value="0">Disabled</option><option value="1">24-key RGB</option><option
|
||||
Sync setup</h2><h3>Button setup</h3>Button type: <select name="BT"><option
|
||||
value="0">Disabled</option><option value="2">Pushbutton</option><option
|
||||
value="4">Switch</option></select><br>Infrared remote: <select name="IR"><option
|
||||
value="0">Disabled</option><option value="1">24-key RGB</option><option
|
||||
value="2">24-key with CT</option><option value="3">40-key blue</option><option
|
||||
value="4">44-key RGB</option><option value="5">21-key RGB</option><option
|
||||
value="6">6-key black</option><option value="7">9-key red</option></select><br>
|
||||
|
1324
wled00/html_ui.h
1324
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
#include "src/dependencies/timezone/Timezone.h"
|
||||
#include "wled.h"
|
||||
#include "wled_math.h"
|
||||
|
||||
/*
|
||||
* Acquires time from NTP server
|
||||
@ -316,8 +317,8 @@ void checkTimers()
|
||||
// get sunrise (or sunset) time (in minutes) for a given day at a given geo location
|
||||
int getSunriseUTC(int year, int month, int day, float lat, float lon, bool sunset=false) {
|
||||
//1. first calculate the day of the year
|
||||
float N1 = floor(275 * month / 9);
|
||||
float N2 = floor((month + 9) / 12);
|
||||
float N1 = 275 * month / 9;
|
||||
float N2 = (month + 9) / 12;
|
||||
float N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3));
|
||||
float N = N1 - (N2 * N3) + day - 30;
|
||||
|
||||
@ -329,10 +330,10 @@ int getSunriseUTC(int year, int month, int day, float lat, float lon, bool sunse
|
||||
float M = (0.9856 * t) - 3.289;
|
||||
|
||||
//4. calculate the Sun's true longitude
|
||||
float L = fmod(M + (1.916 * sin(DEG_TO_RAD*M)) + (0.020 * sin(2*DEG_TO_RAD*M)) + 282.634, 360.0);
|
||||
float L = fmod(M + (1.916 * sin_t(DEG_TO_RAD*M)) + (0.020 * sin_t(2*DEG_TO_RAD*M)) + 282.634, 360.0);
|
||||
|
||||
//5a. calculate the Sun's right ascension
|
||||
float RA = fmod(RAD_TO_DEG*atan(0.91764 * tan(DEG_TO_RAD*L)), 360.0);
|
||||
float RA = fmod(RAD_TO_DEG*atan_t(0.91764 * tan_t(DEG_TO_RAD*L)), 360.0);
|
||||
|
||||
//5b. right ascension value needs to be in the same quadrant as L
|
||||
float Lquadrant = floor( L/90) * 90;
|
||||
@ -343,16 +344,16 @@ int getSunriseUTC(int year, int month, int day, float lat, float lon, bool sunse
|
||||
RA /= 15.;
|
||||
|
||||
//6. calculate the Sun's declination
|
||||
float sinDec = 0.39782 * sin(DEG_TO_RAD*L);
|
||||
float cosDec = cos(asin(sinDec));
|
||||
float sinDec = 0.39782 * sin_t(DEG_TO_RAD*L);
|
||||
float cosDec = cos_t(asin_t(sinDec));
|
||||
|
||||
//7a. calculate the Sun's local hour angle
|
||||
float cosH = (sin(DEG_TO_RAD*ZENITH) - (sinDec * sin(DEG_TO_RAD*lat))) / (cosDec * cos(DEG_TO_RAD*lat));
|
||||
float cosH = (sin_t(DEG_TO_RAD*ZENITH) - (sinDec * sin_t(DEG_TO_RAD*lat))) / (cosDec * cos_t(DEG_TO_RAD*lat));
|
||||
if (cosH > 1 && !sunset) return 0; // the sun never rises on this location (on the specified date)
|
||||
if (cosH < -1 && sunset) return 0; // the sun never sets on this location (on the specified date)
|
||||
|
||||
//7b. finish calculating H and convert into hours
|
||||
float H = sunset ? RAD_TO_DEG*acos(cosH) : 360 - RAD_TO_DEG*acos(cosH);
|
||||
float H = sunset ? RAD_TO_DEG*acos_t(cosH) : 360 - RAD_TO_DEG*acos_t(cosH);
|
||||
H /= 15.;
|
||||
|
||||
//8. calculate local mean time of rising/setting
|
||||
|
@ -197,7 +197,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
//SYNC
|
||||
if (subPage == 4)
|
||||
{
|
||||
buttonEnabled = request->hasArg(F("BT"));
|
||||
buttonType = request->arg(F("BT")).toInt();
|
||||
irEnabled = request->arg(F("IR")).toInt();
|
||||
int t = request->arg(F("UP")).toInt();
|
||||
if (t > 0) udpPort = t;
|
||||
|
@ -45,6 +45,11 @@
|
||||
#include "../usermods/DHT/usermod_dht.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_VL53L0X_GESTURES
|
||||
#include <Wire.h> //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
|
||||
}
|
@ -239,7 +239,7 @@ void WLED::loop()
|
||||
lastMqttReconnectAttempt = 0;
|
||||
}
|
||||
if (millis() - lastMqttReconnectAttempt > 30000) {
|
||||
lastMqttReconnectAttempt = millis(); // don't do it in initMqtt() since MQTT may be disabled
|
||||
lastMqttReconnectAttempt = millis();
|
||||
initMqtt();
|
||||
yield();
|
||||
// refresh WLED nodes list
|
||||
@ -441,7 +441,8 @@ void WLED::beginStrip()
|
||||
if (rlyPin>=0) digitalWrite(rlyPin, (bri ? rlyMde : !rlyMde));
|
||||
|
||||
// disable button if it is "pressed" unintentionally
|
||||
if (btnPin>=0 && isButtonPressed()) buttonEnabled = false;
|
||||
if (btnPin>=0 && buttonType == BTN_TYPE_PUSH && isButtonPressed())
|
||||
buttonType = BTN_TYPE_NONE;
|
||||
}
|
||||
|
||||
void WLED::initAP(bool resetAP)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2104121
|
||||
#define VERSION 2104141
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -182,12 +182,12 @@ WLED_GLOBAL char otaPass[33] _INIT(DEFAULT_OTA_PASS);
|
||||
// Hardware CONFIG (only changeble HERE, not at runtime)
|
||||
// LED strip pin, button pin and IR pin changeable in NpbWrapper.h!
|
||||
#ifndef BTNPIN
|
||||
WLED_GLOBAL int8_t btnPin _INIT(-1);
|
||||
WLED_GLOBAL int8_t btnPin _INIT(0);
|
||||
#else
|
||||
WLED_GLOBAL int8_t btnPin _INIT(BTNPIN);
|
||||
#endif
|
||||
#ifndef RLYPIN
|
||||
WLED_GLOBAL int8_t rlyPin _INIT(-1);
|
||||
WLED_GLOBAL int8_t rlyPin _INIT(12);
|
||||
#else
|
||||
WLED_GLOBAL int8_t rlyPin _INIT(RLYPIN);
|
||||
#endif
|
||||
@ -198,7 +198,7 @@ WLED_GLOBAL bool rlyMde _INIT(true);
|
||||
WLED_GLOBAL bool rlyMde _INIT(RLYMDE);
|
||||
#endif
|
||||
#ifndef IRPIN
|
||||
WLED_GLOBAL int8_t irPin _INIT(-1);
|
||||
WLED_GLOBAL int8_t irPin _INIT(4);
|
||||
#else
|
||||
WLED_GLOBAL int8_t irPin _INIT(IRPIN);
|
||||
#endif
|
||||
@ -253,7 +253,7 @@ WLED_GLOBAL NodesMap Nodes;
|
||||
WLED_GLOBAL bool nodeListEnabled _INIT(true);
|
||||
WLED_GLOBAL bool nodeBroadcastEnabled _INIT(true);
|
||||
|
||||
WLED_GLOBAL bool buttonEnabled _INIT(true);
|
||||
WLED_GLOBAL byte buttonType _INIT(BTN_TYPE_PUSH);
|
||||
WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver
|
||||
|
||||
WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port
|
||||
|
@ -93,7 +93,7 @@ void loadSettingsFromEEPROM()
|
||||
|
||||
notifyButton = EEPROM.read(230);
|
||||
notifyTwice = EEPROM.read(231);
|
||||
buttonEnabled = EEPROM.read(232);
|
||||
buttonType = EEPROM.read(232) ? BTN_TYPE_PUSH : BTN_TYPE_NONE;
|
||||
|
||||
staticIP[0] = EEPROM.read(234);
|
||||
staticIP[1] = EEPROM.read(235);
|
||||
|
71
wled00/wled_math.h
Normal file
71
wled00/wled_math.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef WLED_MATH_H
|
||||
#define WLED_MATH_H
|
||||
|
||||
/*
|
||||
* Contains some trigonometric functions.
|
||||
* The ANSI C equivalents are likely faster, but using any sin/cos/tan function incurs a memory penalty of 460 bytes on ESP8266, likely for lookup tables.
|
||||
* This implementation has no extra static memory usage.
|
||||
*
|
||||
* Source of the cos_t() function: https://web.eecs.utk.edu/~azh/blog/cosine.html (cos_taylor_literal_6terms)
|
||||
*/
|
||||
|
||||
#include <Arduino.h> //PI constant
|
||||
|
||||
#define modd(x, y) ((x) - (int)((x) / (y)) * (y))
|
||||
|
||||
double cos_t(double x)
|
||||
{
|
||||
x = modd(x, TWO_PI);
|
||||
char sign = 1;
|
||||
if (x > PI)
|
||||
{
|
||||
x -= PI;
|
||||
sign = -1;
|
||||
}
|
||||
double xx = x * x;
|
||||
|
||||
return sign * (1 - ((xx) / (2)) + ((xx * xx) / (24)) - ((xx * xx * xx) / (720)) + ((xx * xx * xx * xx) / (40320)) - ((xx * xx * xx * xx * xx) / (3628800)) + ((xx * xx * xx * xx * xx * xx) / (479001600)));
|
||||
}
|
||||
|
||||
double sin_t(double x) {
|
||||
return cos_t(HALF_PI - x);
|
||||
}
|
||||
|
||||
double tan_t(double x) {
|
||||
double c = cos_t(x);
|
||||
if (c==0.0) return 0;
|
||||
return sin_t(x) / c;
|
||||
}
|
||||
|
||||
//https://stackoverflow.com/questions/3380628
|
||||
// Absolute error <= 6.7e-5
|
||||
float acos_t(float x) {
|
||||
float negate = float(x < 0);
|
||||
x = std::abs(x);
|
||||
float ret = -0.0187293;
|
||||
ret = ret * x;
|
||||
ret = ret + 0.0742610;
|
||||
ret = ret * x;
|
||||
ret = ret - 0.2121144;
|
||||
ret = ret * x;
|
||||
ret = ret + HALF_PI;
|
||||
ret = ret * sqrt(1.0-x);
|
||||
ret = ret - 2 * negate * ret;
|
||||
return negate * PI + ret;
|
||||
}
|
||||
|
||||
float asin_t(float x) {
|
||||
return HALF_PI - acos_t(x);
|
||||
}
|
||||
|
||||
//https://stackoverflow.com/a/42542593
|
||||
#define A 0.0776509570923569
|
||||
#define B -0.287434475393028
|
||||
#define C ((HALF_PI/2) - A - B)
|
||||
|
||||
double atan_t(double x) {
|
||||
double xx = x * x;
|
||||
return ((A*xx + B)*xx + C)*x;
|
||||
}
|
||||
|
||||
#endif
|
@ -394,7 +394,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
|
||||
if (subPage == 4)
|
||||
{
|
||||
sappend('c',SET_F("BT"),buttonEnabled);
|
||||
sappend('v',SET_F("BT"),buttonType);
|
||||
sappend('v',SET_F("IR"),irEnabled);
|
||||
sappend('v',SET_F("UP"),udpPort);
|
||||
sappend('v',SET_F("U2"),udpPort2);
|
||||
|
Loading…
Reference in New Issue
Block a user