From 344c9e9238898e323d39ce334c5577e8ff838869 Mon Sep 17 00:00:00 2001 From: Dick Swart Date: Wed, 2 Jun 2021 12:01:06 +1200 Subject: [PATCH] added SN_Photoresistor usermod --- .../SN_Photoresistor/platformio_override.ini | 16 +++ usermods/SN_Photoresistor/readme.md | 30 ++++ .../usermod_sn_photoresistor.h | 128 ++++++++++++++++++ usermods/SN_Photoresistor/usermods_list.cpp | 14 ++ wled00/const.h | 7 +- wled00/usermods_list.cpp | 16 ++- 6 files changed, 204 insertions(+), 7 deletions(-) create mode 100644 usermods/SN_Photoresistor/platformio_override.ini create mode 100644 usermods/SN_Photoresistor/readme.md create mode 100644 usermods/SN_Photoresistor/usermod_sn_photoresistor.h create mode 100644 usermods/SN_Photoresistor/usermods_list.cpp diff --git a/usermods/SN_Photoresistor/platformio_override.ini b/usermods/SN_Photoresistor/platformio_override.ini new file mode 100644 index 00000000..91bc5de2 --- /dev/null +++ b/usermods/SN_Photoresistor/platformio_override.ini @@ -0,0 +1,16 @@ +; Options +; ------- +; USERMOD_SN_PHOTORESISTOR - define this to have this user mod included wled00\usermods_list.cpp +; USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds +; USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 20 seconds +; USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE - the voltage supplied to the sensor, defaults to 5v +; USERMOD_SN_PHOTORESISTOR_ADC_PRECISION - the ADC precision is the number of distinguishable ADC inputs, defaults to 1024.0 (10 bits) +; USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE - the resistor size, defaults to 10000.0 (10K hms) +; USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE - the offset value to report on, defaults to 25 +; +[env:usermod_sn_photoresistor_d1_mini] +extends = env:d1_mini +build_flags = + ${common.build_flags_esp8266} + -D USERMOD_SN_PHOTORESISTOR +lib_deps = ${env.lib_deps} diff --git a/usermods/SN_Photoresistor/readme.md b/usermods/SN_Photoresistor/readme.md new file mode 100644 index 00000000..4f3a36fb --- /dev/null +++ b/usermods/SN_Photoresistor/readme.md @@ -0,0 +1,30 @@ +# SN_Photoresistor usermod + +This usermod will read from an attached photoresistor sensor like the KY-018 sensor. +The luminance is displayed both in the Info section of the web UI as well as published to the `/luminance` MQTT topic if enabled. + +## Installation + +Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`. + +### Define Your Options + +* `USERMOD_SN_PHOTORESISTOR` - define this to have this user mod included wled00\usermods_list.cpp +* `USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL` - the number of milliseconds between measurements, defaults to 60 seconds +* `USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT` - the number of milliseconds after boot to take first measurement, defaults to 20 seconds +* `USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE` - the voltage supplied to the sensor, defaults to 5v +* `USERMOD_SN_PHOTORESISTOR_ADC_PRECISION` - the ADC precision is the number of distinguishable ADC inputs, defaults to 1024.0 (10 bits) +* `USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE` - the resistor size, defaults to 10000.0 (10K hms) +* `USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE` - the offset value to report on, defaults to 25 + +All parameters can be configured at runtime using Usermods settings page. + +## Project link + +* [QuinLED-Dig-Uno](https://quinled.info/2018/09/15/quinled-dig-uno/) - Project link + +### PlatformIO requirements + +If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:usermod_sn_photoresistor_d1_mini`. + +## Change Log diff --git a/usermods/SN_Photoresistor/usermod_sn_photoresistor.h b/usermods/SN_Photoresistor/usermod_sn_photoresistor.h new file mode 100644 index 00000000..465b22f7 --- /dev/null +++ b/usermods/SN_Photoresistor/usermod_sn_photoresistor.h @@ -0,0 +1,128 @@ +#pragma once + +#include "wled.h" + +//Pin defaults for QuinLed Dig-Uno +#define PHOTORESISTOR_PIN A0 + +// the frequency to check photoresistor, 10 seconds +#ifndef USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL +#define USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL 10000 +#endif + +// how many seconds after boot to take first measurement, 10 seconds +#ifndef USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT +#define USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT 10000 +#endif + +// supplied voltage +#ifndef USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE +#define USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE 5 +#endif + +// 10 bits +#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION +#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0 +#endif + +// resistor size 10K hms +#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE +#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0 +#endif + +// only report if differance grater than offset value +#ifndef USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE +#define USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE 5 +#endif + +class Usermod_SN_Photoresistor : public Usermod +{ +private: + // set last reading as "40 sec before boot", so first reading is taken after 20 sec + unsigned long lastMeasurement = UINT32_MAX - (USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT); + // flag to indicate we have finished the first getTemperature call + // allows this library to report to the user how long until the first + // measurement + bool getLuminanceComplete = false; + uint16_t lastLDRValue = -1000; + + bool checkBoundSensor(float newValue, float prevValue, float maxDiff) + { + return isnan(prevValue) || newValue <= prevValue - maxDiff || newValue >= prevValue + maxDiff; + } + + uint16_t getLuminance() + { + // http://forum.arduino.cc/index.php?topic=37555.0 + // https://forum.arduino.cc/index.php?topic=185158.0 + float volts = analogRead(PHOTORESISTOR_PIN) * (USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE / USERMOD_SN_PHOTORESISTOR_ADC_PRECISION); + float amps = volts / USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE; + float lux = amps * 1000000 * 2.0; + + lastMeasurement = millis(); + getLuminanceComplete = true; + return uint16_t(lux); + } + +public: + void setup() + { + pinMode(PHOTORESISTOR_PIN, INPUT); + } + + void loop() + { + unsigned long now = millis(); + + // check to see if we are due for taking a measurement + // lastMeasurement will not be updated until the conversion + // is complete the the reading is finished + if (now - lastMeasurement < USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL) + { + return; + } + + uint16_t currentLDRValue = getLuminance(); + if (checkBoundSensor(currentLDRValue, lastLDRValue, USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE)) + { + lastLDRValue = currentLDRValue; + + if (WLED_MQTT_CONNECTED) + { + char subuf[45]; + strcpy(subuf, mqttDeviceTopic); + strcat_P(subuf, PSTR("/luminance")); + mqtt->publish(subuf, 0, true, String(lastLDRValue).c_str()); + } + else + { + DEBUG_PRINTLN("Missing MQTT connection. Not publishing data"); + } + } + } + + void addToJsonInfo(JsonObject &root) + { + JsonObject user = root[F("u")]; + if (user.isNull()) user = root.createNestedObject(F("u")); + + JsonArray lux = user.createNestedArray(F("Luminance")); + + if (!getLuminanceComplete) + { + // if we haven't read the sensor yet, let the user know + // that we are still waiting for the first measurement + lux.add((USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT - millis()) / 1000); + lux.add(F(" sec until read")); + return; + } + + lux.add(lastLDRValue); + lux.add(F(" lux")); + } + + uint16_t getId() + { + return USERMOD_ID_SN_PHOTORESISTOR; + } +}; diff --git a/usermods/SN_Photoresistor/usermods_list.cpp b/usermods/SN_Photoresistor/usermods_list.cpp new file mode 100644 index 00000000..649e1973 --- /dev/null +++ b/usermods/SN_Photoresistor/usermods_list.cpp @@ -0,0 +1,14 @@ +#include "wled.h" +/* + * Register your v2 usermods here! + */ +#ifdef USERMOD_SN_PHOTORESISTOR +#include "../usermods/SN_Photoresistor/usermod_sn_photoresistor.h" +#endif + +void registerUsermods() +{ +#ifdef USERMOD_SN_PHOTORESISTOR + usermods.add(new Usermod_SN_Photoresistor()); +#endif +} \ No newline at end of file diff --git a/wled00/const.h b/wled00/const.h index 19c2853e..a199c563 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -47,7 +47,7 @@ #define USERMOD_ID_FIXNETSERVICES 4 //Usermod "usermod_Fix_unreachable_netservices.h" #define USERMOD_ID_PIRSWITCH 5 //Usermod "usermod_PIR_sensor_switch.h" #define USERMOD_ID_IMU 6 //Usermod "usermod_mpu6050_imu.h" -#define USERMOD_ID_FOUR_LINE_DISP 7 //Usermod "usermod_v2_four_line_display.h +#define USERMOD_ID_FOUR_LINE_DISP 7 //Usermod "usermod_v2_four_line_display.h #define USERMOD_ID_ROTARY_ENC_UI 8 //Usermod "usermod_v2_rotary_encoder_ui.h" #define USERMOD_ID_AUTO_SAVE 9 //Usermod "usermod_v2_auto_save.h" #define USERMOD_ID_DHT 10 //Usermod "usermod_dht.h" @@ -57,6 +57,7 @@ #define USERMOD_ID_ANIMATED_STAIRCASE 14 //Usermod "Animated_Staircase.h" #define USERMOD_ID_RTC 15 //Usermod "usermod_rtc.h" #define USERMOD_ID_ELEKSTUBE_IPS 16 //Usermod "usermod_elekstube_ips.h" +#define USERMOD_ID_SN_PHOTORESISTOR 17 //Usermod "usermod_sn_photoresistor.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot @@ -64,7 +65,7 @@ #define AP_BEHAVIOR_ALWAYS 2 //Always open #define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec -//Notifier callMode +//Notifier callMode #define NOTIFIER_CALL_MODE_INIT 0 //no updates on init, can be used to disable updates #define NOTIFIER_CALL_MODE_DIRECT_CHANGE 1 #define NOTIFIER_CALL_MODE_BUTTON 2 @@ -81,7 +82,7 @@ #define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider #define RGBW_MODE_AUTO_BRIGHTER 1 //New algorithm. Adds as much white as the darkest RGBW channel #define RGBW_MODE_AUTO_ACCURATE 2 //New algorithm. Adds as much white as the darkest RGBW channel and subtracts this amount from each RGB channel -#define RGBW_MODE_DUAL 3 //Manual slider + auto calculation. Automatically calculates only if manual slider is set to off (0) +#define RGBW_MODE_DUAL 3 //Manual slider + auto calculation. Automatically calculates only if manual slider is set to off (0) #define RGBW_MODE_LEGACY 4 //Old floating algorithm. Too slow for realtime and palette support //realtime modes diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 77af1413..e1586a23 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -14,6 +14,10 @@ #include "../usermods/Temperature/usermod_temperature.h" #endif +#ifdef USERMOD_SN_PHOTORESISTOR +#include "../usermods/SN_Photoresistor/usermod_sn_photoresistor.h" +#endif + //#include "usermod_v2_empty.h" #ifdef USERMOD_BUZZER @@ -77,17 +81,21 @@ void registerUsermods() * \/ \/ \/ */ //usermods.add(new MyExampleUsermod()); - + #ifdef USERMOD_DALLASTEMPERATURE usermods.add(new UsermodTemperature()); #endif - + + #ifdef USERMOD_SN_PHOTORESISTOR + usermods.add(new Usermod_SN_Photoresistor()); + #endif + //usermods.add(new UsermodRenameMe()); - + #ifdef USERMOD_BUZZER usermods.add(new BuzzerUsermod()); #endif - + #ifdef USERMOD_BME280 usermods.add(new UsermodBME280()); #endif