From f9ca25755bf3bc2d383d78a31bfb07b6d3597123 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 May 2019 18:43:23 +0200 Subject: [PATCH] Add experimental light sensor code to ADC0 Add experimental light sensor code to ADC0. See xsns_02_analog.ino for information. --- sonoff/i18n.h | 2 ++ sonoff/sonoff.ino | 1 + sonoff/support.ino | 2 +- sonoff/xsns_02_analog.ino | 62 ++++++++++++++++++++++++++++++++------- sonoff/xsns_10_bh1750.ino | 2 +- 5 files changed, 56 insertions(+), 13 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index de19407ee..ead8694ce 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -520,6 +520,8 @@ const char S_JSON_DRIVER_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_DRIVE const char JSON_SNS_TEMP[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"; const char JSON_SNS_TEMPHUM[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s}"; +const char JSON_SNS_ILLUMINANCE[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d}"; + const char JSON_SNS_GNGPM[] PROGMEM = ",\"%s\":{\"" D_JSON_TOTAL_USAGE "\":%s,\"" D_JSON_FLOWRATE "\":%s}"; const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x"; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index a9b664ec6..6e1260c78 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2662,6 +2662,7 @@ void setup(void) for (uint8_t i = 0; i < sizeof(Settings.my_gp); i++) { Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors } + Settings.my_adc0 = ADC0_NONE; // Reset user defined ADC0 disabling sensors } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic diff --git a/sonoff/support.ino b/sonoff/support.ino index b3c4ce2b4..953297dbf 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -639,7 +639,7 @@ double FastPrecisePow(double a, double b) { // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ // calculate approximation with fraction of the exponent - int e = (int)b; + int e = abs((int)b); union { double d; int x[2]; diff --git a/sonoff/xsns_02_analog.ino b/sonoff/xsns_02_analog.ino index 76c19c1df..e93377165 100644 --- a/sonoff/xsns_02_analog.ino +++ b/sonoff/xsns_02_analog.ino @@ -22,18 +22,30 @@ * ADC support \*********************************************************************************************/ -#define XSNS_02 2 +#define XSNS_02 2 #define TO_CELSIUS(x) ((x) - 273.15) #define TO_KELVIN(x) ((x) + 273.15) -// Parameters for Steinhart-Hart equation -#define ANALOG_V33 3.3 // ESP8266 Analog voltage -#define ANALOG_T0 TO_KELVIN(25.0) // 25 degrees Celcius in Kelvin (= 298.15) -// Shelly 2.5 thermistor -#define ANALOG_R21 32000.0 // Voltage bridge resistor -#define ANALOG_R0 10000.0 // Thermistor resistance -#define ANALOG_B 3350.0 // Thermistor Beta Coefficient +// Parameters for equation +#define ANALOG_V33 3.3 // ESP8266 Analog voltage +#define ANALOG_T0 TO_KELVIN(25.0) // 25 degrees Celcius in Kelvin (= 298.15) + +// Shelly 2.5 NTC Thermistor +// 3V3 --- ANALOG_NTC_BRIDGE_RESISTANCE ---v--- NTC --- Gnd +// | +// ADC0 +#define ANALOG_NTC_BRIDGE_RESISTANCE 32000.0 // NTC Voltage bridge resistor +#define ANALOG_NTC_RESISTANCE 10000.0 // NTC Resistance +#define ANALOG_NTC_B_COEFFICIENT 3350.0 // NTC Beta Coefficient + +// LDR parameters +// 3V3 --- LDR ---v--- ANALOG_LDR_BRIDGE_RESISTANCE --- Gnd +// | +// ADC0 +#define ANALOG_LDR_BRIDGE_RESISTANCE 10000.0 // LDR Voltage bridge resistor +#define ANALOG_LDR_LUX_CALC_SCALAR 12518931 // Experimental +#define ANALOG_LDR_LUX_CALC_EXPONENT -1.405 // Experimental uint16_t adc_last_value = 0; float adc_temp = 0; @@ -70,13 +82,25 @@ void AdcEvery250ms(void) } #endif // USE_RULES +uint16_t AdcGetLux() +{ + int adc = AdcRead(2); + // Source: https://www.allaboutcircuits.com/projects/design-a-luxmeter-using-a-light-dependent-resistor/ + double resistorVoltage = ((double)adc / 1023) * ANALOG_V33; + double ldrVoltage = ANALOG_V33 - resistorVoltage; + double ldrResistance = ldrVoltage / resistorVoltage * ANALOG_LDR_BRIDGE_RESISTANCE; + double ldrLux = ANALOG_LDR_LUX_CALC_SCALAR * FastPrecisePow(ldrResistance, ANALOG_LDR_LUX_CALC_EXPONENT); + + return (uint16_t)ldrLux; +} + void AdcEverySecond(void) { if (ADC0_TEMP == my_adc0) { int adc = AdcRead(2); // Steinhart-Hart equation for thermistor as temperature sensor - double Rt = (adc * ANALOG_R21) / (1024.0 * ANALOG_V33 - (double)adc); - double T = ANALOG_B / (ANALOG_B/ANALOG_T0 + log(Rt/ANALOG_R0)); + double Rt = (adc * ANALOG_NTC_BRIDGE_RESISTANCE) / (1024.0 * ANALOG_V33 - (double)adc); + double T = ANALOG_NTC_B_COEFFICIENT / (ANALOG_NTC_B_COEFFICIENT / ANALOG_T0 + log(Rt / ANALOG_NTC_RESISTANCE)); adc_temp = ConvertTemp(TO_CELSIUS(T)); } } @@ -113,6 +137,22 @@ void AdcShow(bool json) #ifdef USE_WEBSERVER } else { WSContentSend_PD(HTTP_SNS_TEMP, "", temperature, TempUnit()); +#endif // USE_WEBSERVER + } + } + else if (ADC0_LIGHT == my_adc0) { + uint16_t adc_light = AdcGetLux(); + + if (json) { + ResponseAppend_P(JSON_SNS_ILLUMINANCE, "ANALOG", adc_light); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzSensor(DZ_ILLUMINANCE, adc_light); + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, "", adc_light); #endif // USE_WEBSERVER } } @@ -126,7 +166,7 @@ bool Xsns02(uint8_t function) { bool result = false; - if ((ADC0_INPUT == my_adc0) || (ADC0_TEMP == my_adc0)) { + if ((ADC0_INPUT == my_adc0) || (ADC0_TEMP == my_adc0) || (ADC0_LIGHT == my_adc0)) { switch (function) { #ifdef USE_RULES case FUNC_EVERY_250_MSECOND: diff --git a/sonoff/xsns_10_bh1750.ino b/sonoff/xsns_10_bh1750.ino index 5398422b7..93cf57e7c 100644 --- a/sonoff/xsns_10_bh1750.ino +++ b/sonoff/xsns_10_bh1750.ino @@ -92,7 +92,7 @@ void Bh1750Show(bool json) { if (bh1750_valid) { if (json) { - ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d}"), bh1750_types, bh1750_illuminance); + ResponseAppend_P(JSON_SNS_ILLUMINANCE, bh1750_types, bh1750_illuminance); #ifdef USE_DOMOTICZ if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, bh1750_illuminance);