Skip to content

Commit

Permalink
Many changes.
Browse files Browse the repository at this point in the history
1. Migrate from microDS18B20 to DallasTemperature
2. Refactoring of sensors: added an external temperature sensor inside the house, added an "offset" parameter for sensors
3. Fixed PID
4. New parameters added:
- settings.heating.minTemp
- settings.heating.maxTemp
- settings.dhw.minTemp
- settings.dhw.maxTemp
- settings.pid.minTemp
- settings.pid.maxTemp
- settings.sensors.outdoor.type
- settings.sensors.outdoor.pin
- settings.sensors.outdoor.offset
- settings.sensors.indoor.type
- settings.sensors.indoor.pin
- settings.sensors.indoor.offset
5. Fixed and updated HomeAssistantHelper
7. Added check for validity of settings. After some updates, the settings may be reset to default, but this will prevent the settings from being distorted.
  • Loading branch information
Laxilef committed Sep 21, 2023
1 parent b0e01af commit 229628f
Show file tree
Hide file tree
Showing 12 changed files with 913 additions and 166 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ To save money, 2 levels are ordered as one board. After manufacturing, the board
- [TelnetStream](https://github.com/jandrassy/TelnetStream)
- [EEManager](https://github.com/GyverLibs/EEManager)
- [GyverPID](https://github.com/GyverLibs/GyverPID)
- [microDS18B20](https://github.com/GyverLibs/microDS18B20)
- [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library)
- [WiFiManager](https://github.com/tzapu/WiFiManager)


Expand Down
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ lib_deps =
jandrassy/TelnetStream@^1.2.4
gyverlibs/EEManager@^2.0
gyverlibs/GyverPID@^3.3
gyverlibs/microDS18B20@^3.10
milesburton/DallasTemperature@^3.11.0
https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
upload_speed = 921600
Expand Down
488 changes: 471 additions & 17 deletions src/HomeAssistantHelper.h

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions src/MainTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class MainTask: public Task {

void setup() {
pinMode(LED_STATUS_PIN, OUTPUT);
//pinMode(LED_OT_RX_PIN, OUTPUT);
}

void loop() {
Expand Down Expand Up @@ -49,12 +48,6 @@ class MainTask: public Task {
}
}

if (!tSensors->isEnabled() && settings.outdoorTempSource == 2) {
tSensors->enable();
} else if (tSensors->isEnabled() && settings.outdoorTempSource != 2) {
tSensors->disable();
}

if (!tOt->isEnabled() && settings.opentherm.inPin > 0 && settings.opentherm.outPin > 0 && settings.opentherm.inPin != settings.opentherm.outPin) {
tOt->enable();
}
Expand Down
254 changes: 193 additions & 61 deletions src/MqttTask.h

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions src/OpenThermTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ class OpenThermTask: public Task {

protected:
void setup() {
vars.parameters.heatingMinTemp = settings.heating.minTemp;
vars.parameters.heatingMaxTemp = settings.heating.maxTemp;
vars.parameters.dhwMinTemp = settings.dhw.minTemp;
vars.parameters.dhwMaxTemp = settings.dhw.maxTemp;

ot = new CustomOpenTherm(settings.opentherm.inPin, settings.opentherm.outPin);

ot->begin(handleInterrupt, responseCallback);
Expand Down Expand Up @@ -63,7 +68,7 @@ class OpenThermTask: public Task {
updateMinMaxDhwTemp();
updateMinMaxHeatingTemp();

if (settings.outdoorTempSource == 0) {
if (settings.sensors.outdoor.type == 0) {
updateOutsideTemp();
}
if (vars.states.fault) {
Expand All @@ -83,6 +88,7 @@ class OpenThermTask: public Task {
if ( settings.dhw.enable || settings.heating.enable || heatingEnable ) {
updateModulationLevel();
}
yield();

if ( settings.dhw.enable ) {
updateDHWTemp();
Expand All @@ -95,7 +101,6 @@ class OpenThermTask: public Task {
} else {
vars.temperatures.heating = 0;
}

yield();

//
Expand Down Expand Up @@ -306,8 +311,8 @@ class OpenThermTask: public Task {
byte maxTemp = (response & 0xFFFF) >> 8;

if (minTemp >= 0 && maxTemp > 0 && maxTemp > minTemp) {
vars.parameters.dhwMinTemp = minTemp;
vars.parameters.dhwMaxTemp = maxTemp;
vars.parameters.dhwMinTemp = minTemp < settings.dhw.minTemp ? settings.dhw.minTemp : minTemp;
vars.parameters.dhwMaxTemp = maxTemp > settings.dhw.maxTemp ? settings.dhw.maxTemp : maxTemp;

return true;
}
Expand All @@ -325,8 +330,8 @@ class OpenThermTask: public Task {
byte maxTemp = (response & 0xFFFF) >> 8;

if (minTemp >= 0 && maxTemp > 0 && maxTemp > minTemp) {
vars.parameters.heatingMinTemp = minTemp;
vars.parameters.heatingMaxTemp = maxTemp;
vars.parameters.heatingMinTemp = minTemp < settings.heating.minTemp ? settings.heating.minTemp : minTemp;
vars.parameters.heatingMaxTemp = maxTemp > settings.heating.maxTemp ? settings.heating.maxTemp : maxTemp;

return true;
}
Expand All @@ -340,7 +345,7 @@ class OpenThermTask: public Task {
return false;
}

vars.temperatures.outdoor = ot->getFloat(response);
vars.temperatures.outdoor = ot->getFloat(response) + settings.sensors.outdoor.offset;
return true;
}

Expand Down
23 changes: 14 additions & 9 deletions src/RegulatorTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <PIDtuner.h>

Equitherm etRegulator;
GyverPID pidRegulator(0, 0, 0, 10000);
GyverPID pidRegulator(0, 0, 0);
PIDtuner pidTuner;

class RegulatorTask: public LeanTask {
Expand Down Expand Up @@ -73,7 +73,7 @@ class RegulatorTask: public LeanTask {
float newTemp = 0;

// if use equitherm
if (settings.emergency.useEquitherm && settings.outdoorTempSource != 1) {
if (settings.emergency.useEquitherm && settings.sensors.outdoor.type != 1) {
float etResult = getEquithermTemp(vars.parameters.heatingMinTemp, vars.parameters.heatingMaxTemp);

if (fabs(prevEtResult - etResult) + 0.0001 >= 0.5) {
Expand Down Expand Up @@ -123,29 +123,34 @@ class RegulatorTask: public LeanTask {
}

// if use pid
if (settings.pid.enable) {
if (settings.pid.enable && vars.states.heating) {
float pidResult = getPidTemp(
settings.equitherm.enable ? -30 : vars.parameters.heatingMinTemp,
settings.equitherm.enable ? 30 : vars.parameters.heatingMaxTemp
settings.equitherm.enable ? (settings.pid.maxTemp * -1) : settings.pid.minTemp,
settings.equitherm.enable ? settings.pid.maxTemp : settings.pid.maxTemp
);

if (fabs(prevPidResult - pidResult) + 0.0001 >= 0.5) {
if (1 || fabs(prevPidResult - pidResult) + 0.0001 >= 0.5) {
prevPidResult = pidResult;
newTemp += pidResult;

INFO_F("[REGULATOR][PID] New result: %u (%f) \n", (int)round(pidResult), pidResult);
INFO_F("[REGULATOR][PID] New result: %d (%f) \n", (int)round(pidResult), pidResult);

} else {
newTemp += prevPidResult;
}

} else if ( settings.pid.enable && !vars.states.heating && prevPidResult != 0 ) {
newTemp += prevPidResult;
}

// default temp, manual mode
if (!settings.equitherm.enable && !settings.pid.enable) {
newTemp = settings.heating.target;
}

return round(newTemp);
newTemp = round(newTemp);
newTemp = constrain(newTemp, 0, 100);
return newTemp;
}

byte getTuningModeTemp() {
Expand Down Expand Up @@ -269,7 +274,7 @@ class RegulatorTask: public LeanTask {
pidRegulator.input = vars.temperatures.indoor;
pidRegulator.setpoint = settings.heating.target;

return pidRegulator.getResultTimer();
return pidRegulator.getResultNow();
}

float tuneEquithermN(float ratio, float currentTemp, float setTemp, unsigned int dirtyInterval = 60, unsigned int accurateInterval = 1800, float accurateStep = 0.01, float accurateStepAfter = 1) {
Expand Down
150 changes: 127 additions & 23 deletions src/SensorsTask.h
Original file line number Diff line number Diff line change
@@ -1,45 +1,149 @@
#include <microDS18B20.h>

MicroDS18B20<DS18B20_PIN> outdoorSensor;
#include <OneWire.h>
#include <DallasTemperature.h>

class SensorsTask: public LeanTask {
public:
SensorsTask(bool _enabled = false, unsigned long _interval = 0): LeanTask(_enabled, _interval) {}

protected:
OneWire* oneWireOutdoorSensor;
OneWire* oneWireIndoorSensor;

DallasTemperature* outdoorSensor;
DallasTemperature* indoorSensor;

bool initOutdoorSensor = false;
unsigned long startConversionTime = 0;
float filteredOutdoorTemp = 0;
bool emptyOutdoorTemp = true;
void setup() {}

bool initIndoorSensor = false;
float filteredIndoorTemp = 0;
bool emptyIndoorTemp = true;


void setup() {}
void loop() {
// DS18B20 sensor
if (outdoorSensor.online()) {
if (outdoorSensor.readTemp()) {
float rawTemp = outdoorSensor.getTemp();
DEBUG_F("[SENSORS][DS18B20] Raw temp: %f \n", rawTemp);
if ( settings.sensors.outdoor.type == 2 ) {
outdoorTemperatureSensor();
}

if ( settings.sensors.indoor.type == 2 ) {
indoorTemperatureSensor();
}
}

if (emptyOutdoorTemp) {
filteredOutdoorTemp = rawTemp;
emptyOutdoorTemp = false;
void outdoorTemperatureSensor() {
if ( !initOutdoorSensor ) {
oneWireOutdoorSensor = new OneWire(settings.sensors.outdoor.pin);
outdoorSensor = new DallasTemperature(oneWireOutdoorSensor);
outdoorSensor->begin();
outdoorSensor->setResolution(12);
outdoorSensor->setWaitForConversion(false);
outdoorSensor->requestTemperatures();
startConversionTime = millis();
initOutdoorSensor = true;
}

unsigned long estimateConversionTime = millis() - startConversionTime;
if ( estimateConversionTime < outdoorSensor->millisToWaitForConversion() ) {
return;
}

} else {
filteredOutdoorTemp += (rawTemp - filteredOutdoorTemp) * OUTDOOR_SENSOR_FILTER_K;
}
bool completed = outdoorSensor->isConversionComplete();
if ( !completed && estimateConversionTime >= 1000 ) {
// fail, retry
outdoorSensor->requestTemperatures();
startConversionTime = millis();

filteredOutdoorTemp = floor(filteredOutdoorTemp * 100) / 100;
ERROR("[SENSORS][OUTDOOR] Could not read temperature data (no response)");
}

if ( !completed ) {
return;
}

if (fabs(vars.temperatures.outdoor - filteredOutdoorTemp) > 0.099) {
vars.temperatures.outdoor = filteredOutdoorTemp;
INFO_F("[SENSORS][DS18B20] New temp: %f \n", filteredOutdoorTemp);
}
float rawTemp = outdoorSensor->getTempCByIndex(0);
if (rawTemp == DEVICE_DISCONNECTED_C) {
ERROR("[SENSORS][OUTDOOR] Could not read temperature data (not connected)");

} else {
DEBUG_F("[SENSORS][OUTDOOR] Raw temp: %f \n", rawTemp);

if (emptyOutdoorTemp) {
filteredOutdoorTemp = rawTemp;
emptyOutdoorTemp = false;

} else {
ERROR("[SENSORS][DS18B20] Invalid data from sensor");
filteredOutdoorTemp += (rawTemp - filteredOutdoorTemp) * EXT_SENSORS_FILTER_K;
}

filteredOutdoorTemp = floor(filteredOutdoorTemp * 100) / 100;

if (fabs(vars.temperatures.outdoor - filteredOutdoorTemp) > 0.099) {
vars.temperatures.outdoor = filteredOutdoorTemp + settings.sensors.outdoor.offset;
INFO_F("[SENSORS][OUTDOOR] New temp: %f \n", filteredOutdoorTemp);
}
}

outdoorSensor->requestTemperatures();
startConversionTime = millis();
}

void indoorTemperatureSensor() {
if ( !initIndoorSensor ) {
oneWireIndoorSensor = new OneWire(settings.sensors.indoor.pin);
indoorSensor = new DallasTemperature(oneWireIndoorSensor);
indoorSensor->begin();
indoorSensor->setResolution(12);
indoorSensor->setWaitForConversion(false);
indoorSensor->requestTemperatures();
startConversionTime = millis();
initIndoorSensor = true;
}

unsigned long estimateConversionTime = millis() - startConversionTime;
if ( estimateConversionTime < indoorSensor->millisToWaitForConversion() ) {
return;
}

bool completed = indoorSensor->isConversionComplete();
if ( !completed && estimateConversionTime >= 1000 ) {
// fail, retry
indoorSensor->requestTemperatures();
startConversionTime = millis();

ERROR("[SENSORS][INDOOR] Could not read temperature data (no response)");
}

if ( !completed ) {
return;
}

float rawTemp = indoorSensor->getTempCByIndex(0);
if (rawTemp == DEVICE_DISCONNECTED_C) {
ERROR("[SENSORS][INDOOR] Could not read temperature data (not connected)");

outdoorSensor.requestTemp();
} else {
ERROR("[SENSORS][DS18B20] Failed to connect to sensor");
DEBUG_F("[SENSORS][INDOOR] Raw temp: %f \n", rawTemp);

if (emptyIndoorTemp) {
filteredIndoorTemp = rawTemp;
emptyIndoorTemp = false;

} else {
filteredIndoorTemp += (rawTemp - filteredIndoorTemp) * EXT_SENSORS_FILTER_K;
}

filteredIndoorTemp = floor(filteredIndoorTemp * 100) / 100;

if (fabs(vars.temperatures.indoor - filteredIndoorTemp) > 0.099) {
vars.temperatures.indoor = filteredIndoorTemp + settings.sensors.indoor.offset;
INFO_F("[SENSORS][INDOOR] New temp: %f \n", filteredIndoorTemp);
}
}

indoorSensor->requestTemperatures();
startConversionTime = millis();
}
};
Loading

0 comments on commit 229628f

Please sign in to comment.