From f30a0a0c78caee5d00883be7ac1acfdc4ebcd6af Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 22 Oct 2021 15:52:19 +0200 Subject: [PATCH] smooth battery sensor --- esp32/include/DS2438.h | 16 +++++++---- esp32/src/DS2438.cpp | 64 +++++++++++++++++++++++++----------------- esp32/src/main.cpp | 10 +++---- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/esp32/include/DS2438.h b/esp32/include/DS2438.h index 1969997..76aa479 100644 --- a/esp32/include/DS2438.h +++ b/esp32/include/DS2438.h @@ -9,6 +9,7 @@ #include #include +#include "RunningMedian.h" #define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44 #define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4 @@ -30,6 +31,9 @@ #define DS2438_TEMPERATURE_DELAY 10 #define DS2438_VOLTAGE_CONVERSION_DELAY 8 +#define DS2438_MEDIAN_COUNT 5 +#define DS2438_MEDIAN_DELAY 50 + #define DEFAULT_PAGE0(var) uint8_t var[8] { \ 0b00001011 /* X, ADB=0, NVB=0, TB=0, AD=1, EE=0, CA=1, IAD=1 */, \ 0, /* Temperatur */ \ @@ -70,7 +74,7 @@ class DS2438 { DS2438(OneWire *ow, float currentShunt, int retryOnCRCError); void begin(); - void update(); + void updateMultiple(); double getTemperature(); float getVoltage(int channel=DS2438_CHA); float getCurrent(); @@ -83,15 +87,15 @@ class DS2438 { private: bool validAddress(const uint8_t*); bool validFamily(const uint8_t* deviceAddress); - + void update(bool firstIteration); bool deviceFound = false; OneWire *_ow; DeviceAddress _address; uint8_t _mode; - double _temperature; - float _voltageA; - float _voltageB; - float _current; + RunningMedian _temperature = RunningMedian(DS2438_MEDIAN_COUNT*2); + RunningMedian _voltageA = RunningMedian(DS2438_MEDIAN_COUNT); + RunningMedian _voltageB = RunningMedian(DS2438_MEDIAN_COUNT); + RunningMedian _current = RunningMedian(DS2438_MEDIAN_COUNT); float _currentShunt; int _retryOnCRCError; long _CCA; diff --git a/esp32/src/DS2438.cpp b/esp32/src/DS2438.cpp index 79b4dac..3565956 100644 --- a/esp32/src/DS2438.cpp +++ b/esp32/src/DS2438.cpp @@ -35,9 +35,9 @@ void DS2438::begin(){ _ow->reset_search(); memset(searchDeviceAddress,0, 8); - _temperature = 0; - _voltageA = 0.0; - _voltageB = 0.0; + _temperature.clear(); + _voltageA.clear(); + _voltageB.clear(); _error = true; _mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE); @@ -72,10 +72,20 @@ bool DS2438::validFamily(const uint8_t* deviceAddress) { } } -void DS2438::update() { - uint8_t data[9]; +void DS2438::updateMultiple(){ + for(int i = 0;i< DS2438_MEDIAN_COUNT; i++){ + update(i==0); + if(_error){ + return; + } + delay(DS2438_MEDIAN_DELAY); + } +} +void DS2438::update(bool firstIteration) { + uint8_t data[9]; _error = true; + if(!isFound()){ return; } @@ -93,10 +103,10 @@ void DS2438::update() { } if (doTemperature) { - _temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125; + _temperature.add((double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125); } if (_mode & DS2438_MODE_CHA) { - _voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0; + _voltageA.add((((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0); } } if (_mode & DS2438_MODE_CHB) { @@ -113,33 +123,35 @@ void DS2438::update() { int16_t upperByte = ((int16_t)data[2]) << 8; int16_t lowerByte = data[1] >> 3; int16_t fullByte = (upperByte | lowerByte); - _temperature = ((double)fullByte) * 0.03125; + _temperature.add(((double)fullByte) * 0.03125); } - _voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0; + _voltageB.add((((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0); } int16_t upperByte = ((int16_t)data[6]) << 8; int16_t lowerByte = data[5]; int16_t fullByte = (int16_t)(upperByte | lowerByte); float fullByteb = fullByte; - _current = (fullByteb) / ((4096.0f * _currentShunt)); + _current.add((fullByteb) / ((4096.0f * _currentShunt))); + + + if(firstIteration){ + if (readPage(1, data)){ + PageOne_t *pOne = (PageOne_t *) data; + _ICA = pOne->ICA; + } + + if (readPage(7, data)){ + PageSeven_t *pSeven = (PageSeven_t *) data; + _CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8; + _DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8; + } + } _error = false; - - if (readPage(1, data)){ - PageOne_t *pOne = (PageOne_t *) data; - _ICA = pOne->ICA; - } - - if (readPage(7, data)){ - PageSeven_t *pSeven = (PageSeven_t *) data; - _CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8; - _DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8; - } - } double DS2438::getTemperature() { - return _temperature; + return _temperature.getMedian(); } float DS2438::getAh(){ @@ -161,16 +173,16 @@ long DS2438::getCCA(){ float DS2438::getVoltage(int channel) { if (channel == DS2438_CHA) { - return _voltageA; + return _voltageA.getMedian(); } else if (channel == DS2438_CHB) { - return _voltageB; + return _voltageB.getMedian(); } else { return 0.0; } } float DS2438::getCurrent() { - return _current; + return _current.getMedian(); } boolean DS2438::isError() { diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index 2301594..0733a71 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -233,7 +233,7 @@ void readOneWireSensors() } } - battery.update(); + battery.updateMultiple(); mSolarVoltage = battery.getVoltage(BATTSENSOR_INDEX_SOLAR) * SOLAR_VOLT_FACTOR; Serial.flush(); @@ -888,7 +888,7 @@ void plantcontrol() readOneWireSensors(); - Serial << "W : " << waterRawSensor.getAverage() << " cm (" << String(waterLevelMax.get() - waterRawSensor.getAverage()) << "%)" << endl; + Serial << "W : " << waterRawSensor.getMedian() << " cm (" << String(waterLevelMax.get() - waterRawSensor.getMedian ()) << "%)" << endl; float batteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY); float chipTemp = battery.getTemperature(); @@ -896,14 +896,14 @@ void plantcontrol() if (aliveWasRead()) { - float remaining = waterLevelMax.get() - waterRawSensor.getAverage(); + float remaining = waterLevelMax.get() - waterRawSensor.getMedian(); if (!isnan(remaining)) { sensorWater.setProperty("remaining").send(String(remaining)); } - if (!isnan(waterRawSensor.getAverage())) + if (!isnan(waterRawSensor.getMedian())) { - sensorWater.setProperty("distance").send(String(waterRawSensor.getAverage())); + sensorWater.setProperty("distance").send(String(waterRawSensor.getMedian())); } sensorLipo.setProperty("percent").send(String(100 * batteryVoltage / VOLT_MAX_BATT)); sensorLipo.setProperty("volt").send(String(batteryVoltage));