From d392964b90a7ae9b833f52dbe096abda1b8a1946 Mon Sep 17 00:00:00 2001 From: Radim Date: Thu, 10 Nov 2022 13:21:05 +0100 Subject: [PATCH] ADC improvement & fix (#1314) * fix when ADC_DIVIDER is defined NEW multiple readings option * publish at least every 1min * define minimum pub adc interval --- main/ZsensorADC.ino | 24 ++++++++++++++++++++---- main/config_ADC.h | 8 ++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/main/ZsensorADC.ino b/main/ZsensorADC.ino index 89cf24d..9ad1d92 100644 --- a/main/ZsensorADC.ino +++ b/main/ZsensorADC.ino @@ -36,7 +36,7 @@ ADC_MODE(ADC_TOUT); //Time used to wait for an interval before resending adc value unsigned long timeadc = 0; - +unsigned long timeadcpub = 0; void setupADC() { Log.notice(F("ADC_GPIO: %d" CR), ADC_GPIO); } @@ -45,18 +45,29 @@ void MeasureADC() { if (millis() > (timeadc + TimeBetweenReadingADC)) { //retrieving value of temperature and humidity of the box from DHT every xUL # if defined(ESP8266) yield(); + analogRead(ADC_GPIO); //the reliability of the readings can be significantly improved by discarding an initial reading and then averaging the results # endif timeadc = millis(); static int persistedadc; int val = analogRead(ADC_GPIO); + int sum_val = val; + if (NumberOfReadingsADC > 1) { // add extra measurement for accuracy + for (int i = 1; i < NumberOfReadingsADC; i++) { + sum_val += analogRead(ADC_GPIO); + } + val = sum_val / NumberOfReadingsADC; + } if (isnan(val)) { Log.error(F("Failed to read from ADC !" CR)); } else { - if (val >= persistedadc + ThresholdReadingADC || val <= persistedadc - ThresholdReadingADC) { + if (val >= persistedadc + ThresholdReadingADC || val <= persistedadc - ThresholdReadingADC || (MinTimeInSecBetweenPublishingADC > 0 && millis() > (timeadcpub + (MinTimeInSecBetweenPublishingADC * 1000UL)))) { Log.trace(F("Creating ADC buffer" CR)); StaticJsonDocument jsonBuffer; JsonObject ADCdata = jsonBuffer.to(); ADCdata["adc"] = (int)val; + if (NumberOfReadingsADC > 1) { + ADCdata["adc_reads"] = NumberOfReadingsADC; + } # if defined(ADC_DIVIDER) float volt = 0; # if defined(ESP32) @@ -71,9 +82,14 @@ void MeasureADC() { # endif volt *= ADC_DIVIDER; // let's give 2 decimal point - val = (volt * 100); - volt = (float)val / 100.0; + int v = (volt * 100); + volt = (float)v / 100.0; ADCdata["volt"] = (float)volt; +# endif +# if defined(ADC_CALIBRATED_SCALE_FACTOR) // calibration: scale factor = ref-Vcal-mV / sum-of-cal-readings @see https://skillbank.co.uk/arduino/calibrate.htm + float voltage = sum_val * ADC_CALIBRATED_SCALE_FACTOR; // convert to voltage in millivolts + ADCdata["adc_sum"] = (int)sum_val; + ADCdata["mvolt_scaled"] = (int)voltage; // real scaled/calibrated value in mV # endif pub(ADCTOPIC, ADCdata); persistedadc = val; diff --git a/main/config_ADC.h b/main/config_ADC.h index ebb4c8a..b7fe80f 100644 --- a/main/config_ADC.h +++ b/main/config_ADC.h @@ -40,6 +40,14 @@ extern void ADCtoMQTT(); # define ThresholdReadingADC 50 // following the comparison between the previous value and the current one +- the threshold the value will be published or not #endif +#if !defined(NumberOfReadingsADC) || (NumberOfReadingsADC < 1) +# define NumberOfReadingsADC 1 // number of readings for better accuracy: avg adc = sum of adc / num readings +#endif + +#ifndef MinTimeInSecBetweenPublishingADC +# define MinTimeInSecBetweenPublishingADC 0 // pub at least at defined interval - usefull to publish values in case they do not change so much ; 0 = disabled +#endif + /*-------------------PIN DEFINITIONS----------------------*/ #if defined(ESP8266) || !defined(ADC_GPIO) # define ADC_GPIO A0 //on nodeMCU this is D3 pin