smooth battery sensor

This commit is contained in:
Your Name 2021-10-22 15:52:19 +02:00
parent ecc03e9cb4
commit f30a0a0c78
3 changed files with 53 additions and 37 deletions

View File

@ -9,6 +9,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <OneWire.h> #include <OneWire.h>
#include "RunningMedian.h"
#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44 #define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4 #define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4
@ -30,6 +31,9 @@
#define DS2438_TEMPERATURE_DELAY 10 #define DS2438_TEMPERATURE_DELAY 10
#define DS2438_VOLTAGE_CONVERSION_DELAY 8 #define DS2438_VOLTAGE_CONVERSION_DELAY 8
#define DS2438_MEDIAN_COUNT 5
#define DS2438_MEDIAN_DELAY 50
#define DEFAULT_PAGE0(var) uint8_t var[8] { \ #define DEFAULT_PAGE0(var) uint8_t var[8] { \
0b00001011 /* X, ADB=0, NVB=0, TB=0, AD=1, EE=0, CA=1, IAD=1 */, \ 0b00001011 /* X, ADB=0, NVB=0, TB=0, AD=1, EE=0, CA=1, IAD=1 */, \
0, /* Temperatur */ \ 0, /* Temperatur */ \
@ -70,7 +74,7 @@ class DS2438 {
DS2438(OneWire *ow, float currentShunt, int retryOnCRCError); DS2438(OneWire *ow, float currentShunt, int retryOnCRCError);
void begin(); void begin();
void update(); void updateMultiple();
double getTemperature(); double getTemperature();
float getVoltage(int channel=DS2438_CHA); float getVoltage(int channel=DS2438_CHA);
float getCurrent(); float getCurrent();
@ -83,15 +87,15 @@ class DS2438 {
private: private:
bool validAddress(const uint8_t*); bool validAddress(const uint8_t*);
bool validFamily(const uint8_t* deviceAddress); bool validFamily(const uint8_t* deviceAddress);
void update(bool firstIteration);
bool deviceFound = false; bool deviceFound = false;
OneWire *_ow; OneWire *_ow;
DeviceAddress _address; DeviceAddress _address;
uint8_t _mode; uint8_t _mode;
double _temperature; RunningMedian _temperature = RunningMedian(DS2438_MEDIAN_COUNT*2);
float _voltageA; RunningMedian _voltageA = RunningMedian(DS2438_MEDIAN_COUNT);
float _voltageB; RunningMedian _voltageB = RunningMedian(DS2438_MEDIAN_COUNT);
float _current; RunningMedian _current = RunningMedian(DS2438_MEDIAN_COUNT);
float _currentShunt; float _currentShunt;
int _retryOnCRCError; int _retryOnCRCError;
long _CCA; long _CCA;

View File

@ -35,9 +35,9 @@ void DS2438::begin(){
_ow->reset_search(); _ow->reset_search();
memset(searchDeviceAddress,0, 8); memset(searchDeviceAddress,0, 8);
_temperature = 0; _temperature.clear();
_voltageA = 0.0; _voltageA.clear();
_voltageB = 0.0; _voltageB.clear();
_error = true; _error = true;
_mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE); _mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE);
@ -72,10 +72,20 @@ bool DS2438::validFamily(const uint8_t* deviceAddress) {
} }
} }
void DS2438::update() { void DS2438::updateMultiple(){
uint8_t data[9]; 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; _error = true;
if(!isFound()){ if(!isFound()){
return; return;
} }
@ -93,10 +103,10 @@ void DS2438::update() {
} }
if (doTemperature) { 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) { 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) { if (_mode & DS2438_MODE_CHB) {
@ -113,18 +123,19 @@ void DS2438::update() {
int16_t upperByte = ((int16_t)data[2]) << 8; int16_t upperByte = ((int16_t)data[2]) << 8;
int16_t lowerByte = data[1] >> 3; int16_t lowerByte = data[1] >> 3;
int16_t fullByte = (upperByte | lowerByte); 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 upperByte = ((int16_t)data[6]) << 8;
int16_t lowerByte = data[5]; int16_t lowerByte = data[5];
int16_t fullByte = (int16_t)(upperByte | lowerByte); int16_t fullByte = (int16_t)(upperByte | lowerByte);
float fullByteb = fullByte; float fullByteb = fullByte;
_current = (fullByteb) / ((4096.0f * _currentShunt)); _current.add((fullByteb) / ((4096.0f * _currentShunt)));
_error = false;
if(firstIteration){
if (readPage(1, data)){ if (readPage(1, data)){
PageOne_t *pOne = (PageOne_t *) data; PageOne_t *pOne = (PageOne_t *) data;
_ICA = pOne->ICA; _ICA = pOne->ICA;
@ -135,11 +146,12 @@ void DS2438::update() {
_CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8; _CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8;
_DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8; _DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8;
} }
}
_error = false;
} }
double DS2438::getTemperature() { double DS2438::getTemperature() {
return _temperature; return _temperature.getMedian();
} }
float DS2438::getAh(){ float DS2438::getAh(){
@ -161,16 +173,16 @@ long DS2438::getCCA(){
float DS2438::getVoltage(int channel) { float DS2438::getVoltage(int channel) {
if (channel == DS2438_CHA) { if (channel == DS2438_CHA) {
return _voltageA; return _voltageA.getMedian();
} else if (channel == DS2438_CHB) { } else if (channel == DS2438_CHB) {
return _voltageB; return _voltageB.getMedian();
} else { } else {
return 0.0; return 0.0;
} }
} }
float DS2438::getCurrent() { float DS2438::getCurrent() {
return _current; return _current.getMedian();
} }
boolean DS2438::isError() { boolean DS2438::isError() {

View File

@ -233,7 +233,7 @@ void readOneWireSensors()
} }
} }
battery.update(); battery.updateMultiple();
mSolarVoltage = battery.getVoltage(BATTSENSOR_INDEX_SOLAR) * SOLAR_VOLT_FACTOR; mSolarVoltage = battery.getVoltage(BATTSENSOR_INDEX_SOLAR) * SOLAR_VOLT_FACTOR;
Serial.flush(); Serial.flush();
@ -888,7 +888,7 @@ void plantcontrol()
readOneWireSensors(); 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 batteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY);
float chipTemp = battery.getTemperature(); float chipTemp = battery.getTemperature();
@ -896,14 +896,14 @@ void plantcontrol()
if (aliveWasRead()) if (aliveWasRead())
{ {
float remaining = waterLevelMax.get() - waterRawSensor.getAverage(); float remaining = waterLevelMax.get() - waterRawSensor.getMedian();
if (!isnan(remaining)) if (!isnan(remaining))
{ {
sensorWater.setProperty("remaining").send(String(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("percent").send(String(100 * batteryVoltage / VOLT_MAX_BATT));
sensorLipo.setProperty("volt").send(String(batteryVoltage)); sensorLipo.setProperty("volt").send(String(batteryVoltage));