diff --git a/usermods/SN_Photoresistor/usermod_sn_photoresistor.h b/usermods/SN_Photoresistor/usermod_sn_photoresistor.h index 465b22f7..3fd1fafa 100644 --- a/usermods/SN_Photoresistor/usermod_sn_photoresistor.h +++ b/usermods/SN_Photoresistor/usermod_sn_photoresistor.h @@ -2,7 +2,7 @@ #include "wled.h" -//Pin defaults for QuinLed Dig-Uno +//Pin defaults for QuinLed Dig-Uno (A0) #define PHOTORESISTOR_PIN A0 // the frequency to check photoresistor, 10 seconds @@ -38,6 +38,12 @@ class Usermod_SN_Photoresistor : public Usermod { private: + float referenceVoltage = USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE; + float resistorValue = USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE; + float adcPrecision = USERMOD_SN_PHOTORESISTOR_ADC_PRECISION; + int8_t offset = USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE; + + unsigned long readingInterval = USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL; // 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 @@ -46,6 +52,18 @@ private: bool getLuminanceComplete = false; uint16_t lastLDRValue = -1000; + // flag set at startup + bool disabled = false; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _readInterval[]; + static const char _referenceVoltage[]; + static const char _resistorValue[]; + static const char _adcPrecision[]; + static const char _offset[]; + bool checkBoundSensor(float newValue, float prevValue, float maxDiff) { return isnan(prevValue) || newValue <= prevValue - maxDiff || newValue >= prevValue + maxDiff; @@ -55,8 +73,8 @@ private: { // 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 volts = analogRead(PHOTORESISTOR_PIN) * (referenceVoltage / adcPrecision); + float amps = volts / resistorValue; float lux = amps * 1000000 * 2.0; lastMeasurement = millis(); @@ -67,23 +85,27 @@ private: public: void setup() { + // set pinmode pinMode(PHOTORESISTOR_PIN, INPUT); } void loop() { + if (disabled || strip.isUpdating()) + return; + 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) + if (now - lastMeasurement < readingInterval) { return; } uint16_t currentLDRValue = getLuminance(); - if (checkBoundSensor(currentLDRValue, lastLDRValue, USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE)) + if (checkBoundSensor(currentLDRValue, lastLDRValue, offset)) { lastLDRValue = currentLDRValue; @@ -104,7 +126,8 @@ public: void addToJsonInfo(JsonObject &root) { JsonObject user = root[F("u")]; - if (user.isNull()) user = root.createNestedObject(F("u")); + if (user.isNull()) + user = root.createNestedObject(F("u")); JsonArray lux = user.createNestedArray(F("Luminance")); @@ -125,4 +148,63 @@ public: { return USERMOD_ID_SN_PHOTORESISTOR; } + + /** + * addToConfig() (called from set.cpp) stores persistent properties to cfg.json + */ + void addToConfig(JsonObject &root) + { + // we add JSON object. + JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname + top[FPSTR(_enabled)] = !disabled; + top[FPSTR(_readInterval)] = readingInterval / 1000; + top[FPSTR(_referenceVoltage)] = referenceVoltage; + top[FPSTR(_resistorValue)] = resistorValue; + top[FPSTR(_adcPrecision)] = adcPrecision; + top[FPSTR(_offset)] = offset; + + DEBUG_PRINTLN(F("Photoresistor config saved.")); + } + + /** + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + */ + void readFromConfig(JsonObject &root) + { + // we look for JSON object. + JsonObject top = root[FPSTR(_name)]; + + if (!top.isNull()) + { + if (top[FPSTR(_enabled)].is()) + { + disabled = !top[FPSTR(_enabled)].as(); + } + else + { + String str = top[FPSTR(_enabled)]; // checkbox -> off or on + disabled = (bool)(str == "off"); // off is guaranteed to be present + }; + + readingInterval = min(120, max(10, top[FPSTR(_readInterval)].as())) * 1000; // convert to ms + referenceVoltage = top[FPSTR(_referenceVoltage)].as(); + resistorValue = top[FPSTR(_resistorValue)].as(); + adcPrecision = top[FPSTR(_adcPrecision)].as(); + offset = top[FPSTR(_offset)].as(); + DEBUG_PRINTLN(F("Photoresistor config (re)loaded.")); + } + else + { + DEBUG_PRINTLN(F("No config found. (Using defaults.)")); + } + } }; + +// strings to reduce flash memory usage (used more than twice) +const char Usermod_SN_Photoresistor::_name[] PROGMEM = "Photoresistor"; +const char Usermod_SN_Photoresistor::_enabled[] PROGMEM = "enabled"; +const char Usermod_SN_Photoresistor::_readInterval[] PROGMEM = "read-interval-s"; +const char Usermod_SN_Photoresistor::_referenceVoltage[] PROGMEM = "supplied-voltage"; +const char Usermod_SN_Photoresistor::_resistorValue[] PROGMEM = "resistor-value"; +const char Usermod_SN_Photoresistor::_adcPrecision[] PROGMEM = "adc-precision"; +const char Usermod_SN_Photoresistor::_offset[] PROGMEM = "offset"; \ No newline at end of file