Central Heating controller using the real time clock, PHY module for internet, 1-wire interface for temperature sensors, a system log and a configuration file
Dependencies: net 1-wire lpc1768 crypto clock web fram log
/media/uploads/andrewboyson/heating.sch
/media/uploads/andrewboyson/heating.brd
/media/uploads/andrewboyson/eagle.epf
Diff: heating/boiler.c
- Revision:
- 106:41ed3ea0bbba
- Parent:
- 105:1899f7ed17ec
--- a/heating/boiler.c Tue Feb 23 20:35:07 2021 +0000 +++ b/heating/boiler.c Fri Apr 23 08:36:42 2021 +0000 @@ -22,7 +22,6 @@ #define PUMP_SPEED_CALLING_AUTO_ONLY -1 #define PUMP_SPEED_CALLING_AUTO_TWEAK -2 -#define MIN_SPEED 40 #define MAX_SPEED 100 static char* tankRom; static int iTankRom; @@ -33,16 +32,16 @@ static int8_t tankSetPoint; static int iTankSetPoint; static int16_t tankHysteresis; static int iTankHysteresis; -static int16_t runOnResidual16ths; static int iRunOnResidual; +static int16_t _runOnDelta16ths; static int iRunOnResidual; static uint8_t runOnTime2s; static int iRunOnTime; static int8_t boilerTarget; static int iBoilerTarget; static int8_t pumpSpeedCalling; static int iPumpSpeedCalling; -static int8_t pumpSpeedRunOn; static int iPumpSpeedRunOn; +static int8_t _rampDownTime; static int _iRampDownTime; -static int16_t rise16thsAt0; static int iRiseAt0; -static int16_t rise16thsAt50; static int iRiseAt50; -static int16_t rise16thsAt100; static int iRiseAt100; +static int8_t _minSpeed; static int _iMinSpeed; +static int8_t _midSpeedPwm; static int _iMidSpeedPwm; +static int16_t _fullSpeedDeltaT16ths; static int _iFullSpeedDeltaT; //Set in main scan static int16_t _boilerOutput16ths = DS18B20_ERROR_VALUE_NOT_SET; @@ -52,36 +51,36 @@ static bool _boilerDeltaTisValid = false; int16_t BoilerGetTankDS18B20Value () { return DS18B20ValueFromRom(tankRom); } -int16_t BoilerGetOutputDS18B20Value() { return _boilerOutput16ths; } -int16_t BoilerGetReturnDS18B20Value() { return _boilerReturn16ths; } -int16_t BoilerGetRtnDelDS18B20Value() { return _boilerRtnDel16ths; } -int16_t BoilerGetDeltaTDS18B20Value() { return _boilerDeltaT16ths; } -int BoilerGetFullSpeedSecs () { return fullSpeedSecs; } -int BoilerGetTankSetPoint () { return tankSetPoint; } -int BoilerGetTankHysteresis () { return tankHysteresis; } -int BoilerGetRunOnDeltaT () { return runOnResidual16ths; } -int BoilerGetRunOnTime () { return runOnTime2s << 1; } -int BoilerGetPumpSpeedCalling () { return pumpSpeedCalling; } -int BoilerGetPumpSpeedRunOn () { return pumpSpeedRunOn; } -int BoilerGetOutputTarget () { return boilerTarget; } -int BoilerGetMinimumFlow () { return rise16thsAt0; } -int BoilerGetMidFlowSpeed () { return rise16thsAt50; } -int BoilerGetFullSpeedDeltaT () { return rise16thsAt100; } +int16_t BoilerGetOutputDS18B20Value() { return _boilerOutput16ths; } +int16_t BoilerGetReturnDS18B20Value() { return _boilerReturn16ths; } +int16_t BoilerGetRtnDelDS18B20Value() { return _boilerRtnDel16ths; } +int16_t BoilerGetDeltaTDS18B20Value() { return _boilerDeltaT16ths; } +int BoilerGetFullSpeedSecs () { return fullSpeedSecs; } +int BoilerGetTankSetPoint () { return tankSetPoint; } +int BoilerGetTankHysteresis () { return tankHysteresis; } +int BoilerGetRunOnDeltaT () { return _runOnDelta16ths; } +int BoilerGetRunOnTime () { return runOnTime2s << 1; } +int BoilerGetPumpSpeedCalling () { return pumpSpeedCalling; } +int BoilerGetRampDownTime () { return _rampDownTime; } +int BoilerGetOutputTarget () { return boilerTarget; } +int BoilerGetMinSpeed () { return _minSpeed; } +int BoilerGetMidSpeedPwm () { return _midSpeedPwm; } +int BoilerGetFullSpeedDeltaT () { return _fullSpeedDeltaT16ths; } -static void setTankRom (char* value) { memcpy(tankRom, value, 8); FramWrite(iTankRom, 8, tankRom ); } -static void setOutputRom (char* value) { memcpy(outputRom, value, 8); FramWrite(iOutputRom, 8, outputRom ); } -static void setReturnRom (char* value) { memcpy(returnRom, value, 8); FramWrite(iReturnRom, 8, returnRom ); } -void BoilerSetFullSpeedSecs (int value) { fullSpeedSecs = value; FramWrite(iFullSpeedSecs, 1, &fullSpeedSecs ); } -void BoilerSetTankSetPoint (int value) { tankSetPoint = value; FramWrite(iTankSetPoint, 1, &tankSetPoint ); } -void BoilerSetTankHysteresis (int value) { tankHysteresis = value; FramWrite(iTankHysteresis, 2, &tankHysteresis ); } -void BoilerSetRunOnDeltaT (int value) { runOnResidual16ths = value; FramWrite(iRunOnResidual, 2, &runOnResidual16ths ); } -void BoilerSetRunOnTime (int value) { runOnTime2s = value >> 1;FramWrite(iRunOnTime, 1, &runOnTime2s ); } -void BoilerSetPumpSpeedCalling (int value) { pumpSpeedCalling = value; FramWrite(iPumpSpeedCalling,1, &pumpSpeedCalling ); } -void BoilerSetPumpSpeedRunOn (int value) { pumpSpeedRunOn = value; FramWrite(iPumpSpeedRunOn, 1, &pumpSpeedRunOn ); } -void BoilerSetOutputTarget (int value) { boilerTarget = value; FramWrite(iBoilerTarget, 1, &boilerTarget ); } -void BoilerSetMinimumFlow (int value) { rise16thsAt0 = value; FramWrite(iRiseAt0, 2, &rise16thsAt0 ); } -void BoilerSetMidFlowSpeed (int value) { rise16thsAt50 = value; FramWrite(iRiseAt50, 2, &rise16thsAt50 ); } -void BoilerSetFullSpeedDeltaT (int value) { rise16thsAt100 = value; FramWrite(iRiseAt100, 2, &rise16thsAt100 ); } +static void setTankRom (char* value) { memcpy(tankRom, value, 8); FramWrite(iTankRom, 8, tankRom ); } +static void setOutputRom (char* value) { memcpy(outputRom, value, 8); FramWrite(iOutputRom, 8, outputRom ); } +static void setReturnRom (char* value) { memcpy(returnRom, value, 8); FramWrite(iReturnRom, 8, returnRom ); } +void BoilerSetFullSpeedSecs (int value) { fullSpeedSecs = value; FramWrite(iFullSpeedSecs, 1, &fullSpeedSecs ); } +void BoilerSetTankSetPoint (int value) { tankSetPoint = value; FramWrite(iTankSetPoint, 1, &tankSetPoint ); } +void BoilerSetTankHysteresis (int value) { tankHysteresis = value; FramWrite(iTankHysteresis, 2, &tankHysteresis ); } +void BoilerSetRunOnDeltaT (int value) { _runOnDelta16ths = value; FramWrite(iRunOnResidual, 2, &_runOnDelta16ths ); } +void BoilerSetRunOnTime (int value) { runOnTime2s = value >> 1;FramWrite(iRunOnTime, 1, &runOnTime2s ); } +void BoilerSetPumpSpeedCalling (int value) { pumpSpeedCalling = value; FramWrite(iPumpSpeedCalling,1, &pumpSpeedCalling ); } +void BoilerSetRampDownTime (int value) { _rampDownTime = value; FramWrite(_iRampDownTime, 1, &_rampDownTime ); } +void BoilerSetOutputTarget (int value) { boilerTarget = value; FramWrite(iBoilerTarget, 1, &boilerTarget ); } +void BoilerSetMinSpeed (int value) { _minSpeed = value; FramWrite(_iMinSpeed, 1, &_minSpeed ); } +void BoilerSetMidSpeedPwm (int value) { _midSpeedPwm = value; FramWrite(_iMidSpeedPwm, 1, &_midSpeedPwm ); } +void BoilerSetFullSpeedDeltaT (int value) { _fullSpeedDeltaT16ths = value; FramWrite(_iFullSpeedDeltaT,2, &_fullSpeedDeltaT16ths); } static int calculateBetweenTwoPoints(int x, int xA, int xB, int yA, int yB) { @@ -90,24 +89,15 @@ } static int calculateSpeedFromDeltaT(int deltaT16ths) { - if (deltaT16ths < rise16thsAt100) return MAX_SPEED; //Needed in case deltaT16ths is negative or zero - int flow = MAX_SPEED * rise16thsAt100 / deltaT16ths; //eg for 20 deg ==> 100 * (10 << 4) / (20 << 4) == 50 - if (flow > MAX_SPEED) flow = MAX_SPEED; - if (flow < MIN_SPEED) flow = MIN_SPEED; - return flow; - - //if (deltaT16ths > rise16thsAt0 ) return MIN_SPEED; - //else if (deltaT16ths > rise16thsAt50 ) return calculateBetweenTwoPoints(deltaT16ths, rise16thsAt50, rise16thsAt0, MID_SPEED, MIN_SPEED); - //else if (deltaT16ths > rise16thsAt100) return calculateBetweenTwoPoints(deltaT16ths, rise16thsAt100, rise16thsAt50, MAX_SPEED, MID_SPEED); - //else return MAX_SPEED; + if (deltaT16ths < _fullSpeedDeltaT16ths) return MAX_SPEED; //Needed in case deltaT16ths is negative or zero + int speed = MAX_SPEED * _fullSpeedDeltaT16ths / deltaT16ths; //eg for 20 deg ==> 100 * (10 << 4) / (20 << 4) == 50 + if (speed > MAX_SPEED) speed = MAX_SPEED; + if (speed < _minSpeed) speed = _minSpeed; + return speed; } static int calculateDeltaTFromSpeed(int speed) { - int deltaT16ths = MAX_SPEED * rise16thsAt100 / speed; //eg for speed = 50 ==> 100 * (10 << 4) / 50 == 20 << 4 - //if (speed >= MAX_SPEED) return rise16thsAt100; - //else if (speed > MID_SPEED) return calculateBetweenTwoPoints(speed, MID_SPEED, MAX_SPEED, rise16thsAt50, rise16thsAt100); - //else if (speed > MIN_SPEED) return calculateBetweenTwoPoints(speed, MIN_SPEED, MID_SPEED, rise16thsAt0, rise16thsAt50 ); - //else return rise16thsAt0; + int deltaT16ths = MAX_SPEED * _fullSpeedDeltaT16ths / speed; //eg for speed = 50 ==> 100 * (10 << 4) / 50 == 20 << 4 return deltaT16ths; } @@ -132,20 +122,22 @@ uint8_t def1; int16_t def2; int32_t def4; - address = FramLoad( 8, tankRom, 0); if (address < 0) return -1; iTankRom = address; - address = FramLoad( 8, outputRom, 0); if (address < 0) return -1; iOutputRom = address; - address = FramLoad( 8, returnRom, 0); if (address < 0) return -1; iReturnRom = address; - def1 = 100; address = FramLoad( 1, &fullSpeedSecs, &def1); if (address < 0) return -1; iFullSpeedSecs = address; - def1 = 65; address = FramLoad( 1, &tankSetPoint, &def1); if (address < 0) return -1; iTankSetPoint = address; - def2 = 5; address = FramLoad( 2, &tankHysteresis, &def2); if (address < 0) return -1; iTankHysteresis = address; - def2 = 2; address = FramLoad( 2, &runOnResidual16ths, &def2); if (address < 0) return -1; iRunOnResidual = address; - def1 = 180; address = FramLoad( 1, &runOnTime2s, &def1); if (address < 0) return -1; iRunOnTime = address; - def1 = 100; address = FramLoad( 1, &pumpSpeedCalling, &def1); if (address < 0) return -1; iPumpSpeedCalling = address; - def1 = 10; address = FramLoad( 1, &pumpSpeedRunOn, &def1); if (address < 0) return -1; iPumpSpeedRunOn = address; - def1 = 65; address = FramLoad( 1, &boilerTarget, &def1); if (address < 0) return -1; iBoilerTarget = address; - def2 = 10<<4; address = FramLoad( 2, &rise16thsAt0, &def2); if (address < 0) return -1; iRiseAt0 = address; - def2 = 15<<4; address = FramLoad( 2, &rise16thsAt50, &def2); if (address < 0) return -1; iRiseAt50 = address; - def2 = 20<<4; address = FramLoad( 2, &rise16thsAt100, &def2); if (address < 0) return -1; iRiseAt100 = address; + address = FramLoad( 8, tankRom, 0); if (address < 0) return -1; iTankRom = address; + address = FramLoad( 8, outputRom, 0); if (address < 0) return -1; iOutputRom = address; + address = FramLoad( 8, returnRom, 0); if (address < 0) return -1; iReturnRom = address; + def1 = 100; address = FramLoad( 1, &fullSpeedSecs, &def1); if (address < 0) return -1; iFullSpeedSecs = address; + def1 = 65; address = FramLoad( 1, &tankSetPoint, &def1); if (address < 0) return -1; iTankSetPoint = address; + def2 = 5; address = FramLoad( 2, &tankHysteresis, &def2); if (address < 0) return -1; iTankHysteresis = address; + def2 = 2; address = FramLoad( 2, &_runOnDelta16ths, &def2); if (address < 0) return -1; iRunOnResidual = address; + def1 = 180; address = FramLoad( 1, &runOnTime2s, &def1); if (address < 0) return -1; iRunOnTime = address; + def1 = 100; address = FramLoad( 1, &pumpSpeedCalling, &def1); if (address < 0) return -1; iPumpSpeedCalling = address; + def1 = 10; address = FramLoad( 1, &_rampDownTime, &def1); if (address < 0) return -1; _iRampDownTime = address; + def1 = 65; address = FramLoad( 1, &boilerTarget, &def1); if (address < 0) return -1; iBoilerTarget = address; + def1 = 50; address = FramLoad( 1, &_minSpeed, &def1); if (address < 0) return -1; _iMinSpeed = address; + FramAllocate(1); + def1 = 50; address = FramLoad( 1, &_midSpeedPwm, &def1); if (address < 0) return -1; _iMidSpeedPwm = address; + FramAllocate(1); + def2 = 10<<4; address = FramLoad( 2, &_fullSpeedDeltaT16ths, &def2); if (address < 0) return -1; _iFullSpeedDeltaT = address; BOILER_PUMP_DIR = 1; //Set the direction to 1 == output BOILER_CALL_DIR = 1; //Set the direction to 1 == output @@ -187,12 +179,12 @@ } else { - if (MsTimerRelative(msTimerBoilerPumpRunOn, runOnTime2s * 2000)) BoilerPump = false; - if (_boilerDeltaTisValid && _boilerDeltaT16ths < runOnResidual16ths ) BoilerPump = false; + if (MsTimerRelative(msTimerBoilerPumpRunOn, runOnTime2s * 2000)) BoilerPump = false; + if (_boilerDeltaTisValid && _boilerDeltaT16ths < _runOnDelta16ths ) BoilerPump = false; } } -int BoilerPumpFlow = MIN_SPEED; -int BoilerPumpSpeed = MIN_SPEED; +int BoilerPumpFlow = MAX_SPEED; +int BoilerPumpSpeed = MAX_SPEED; int BoilerPumpPwm = 0; static int _autoSpeed = 0; static void calculateAutoSpeed() @@ -210,28 +202,29 @@ calculateAutoSpeed(); if (BoilerCall) { - if (pumpSpeedCalling > MAX_SPEED || pumpSpeedCalling < MIN_SPEED) BoilerPumpSpeed = _autoSpeed; //Auto - else BoilerPumpSpeed = pumpSpeedCalling; //Manual + if (pumpSpeedCalling < 0) BoilerPumpSpeed = _autoSpeed; //Auto + else BoilerPumpSpeed = pumpSpeedCalling; //Manual msTimerReduction = MsTimerCount; } else { - if (BoilerPumpSpeed > pumpSpeedRunOn) + if (BoilerPumpSpeed > _minSpeed) { - if (MsTimerRepetitive(&msTimerReduction, 250)) BoilerPumpSpeed--; + int msPerUnit = 1000 * _rampDownTime / (MAX_SPEED - _minSpeed); + if (MsTimerRepetitive(&msTimerReduction, msPerUnit)) BoilerPumpSpeed--; } else { - BoilerPumpSpeed = pumpSpeedRunOn; + BoilerPumpSpeed = _minSpeed; } } + if (BoilerPumpSpeed < _minSpeed) BoilerPumpSpeed = _minSpeed; + if (BoilerPumpSpeed > MAX_SPEED) BoilerPumpSpeed = MAX_SPEED; } -static void flowToSpeed() +static int speedToPwm(int speed) { - //Do nothing yet -} -static void speedToPwm() -{ + #define MAX_SPEED_PWM 10 + #define MIN_SPEED_PWM 84 /* PWM input signal [%] Pump status ≤ 10 Maximum speed @@ -244,10 +237,15 @@ Max speed 100 is at fitted = 74; pwm = 10 Min speed 0 is at fitted = 0; pwm = 84 */ - int pwm = calculateBetweenTwoPoints(BoilerPumpSpeed, MIN_SPEED, MAX_SPEED, 84, 10); - if (pwm < 10) pwm = 10; - if (pwm > 84) pwm = 84; - BoilerPumpPwm = pwm; + if (speed <= _minSpeed) return MIN_SPEED_PWM; + if (speed >= MAX_SPEED) return MAX_SPEED_PWM; + int midSpeed = (_minSpeed + MAX_SPEED) / 2; + if (speed < midSpeed) return calculateBetweenTwoPoints(speed, _minSpeed, midSpeed, MIN_SPEED_PWM, _midSpeedPwm); + else return calculateBetweenTwoPoints(speed, midSpeed, MAX_SPEED, _midSpeedPwm, MAX_SPEED_PWM); + //int pwm = calculateBetweenTwoPoints(BoilerPumpSpeed, _minSpeed, MAX_SPEED, 84, 10); + //if (pwm < 10) pwm = 10; + //if (pwm > 84) pwm = 84; + //BoilerPumpPwm = pwm; } #define TIME_BEFORE_TWEAK_SECS 120 static void tweakDeltaTs() @@ -264,8 +262,8 @@ if (speedLastScan < MAX_SPEED && BoilerPumpSpeed == MAX_SPEED) { - if (rise16thsAt100 > _boilerDeltaT16ths) rise16thsAt100--; - if (rise16thsAt100 < _boilerDeltaT16ths) rise16thsAt100++; + if (_fullSpeedDeltaT16ths > _boilerDeltaT16ths) _fullSpeedDeltaT16ths--; + if (_fullSpeedDeltaT16ths < _boilerDeltaT16ths) _fullSpeedDeltaT16ths++; } speedLastScan = BoilerPumpSpeed; @@ -365,8 +363,7 @@ else BOILER_PUMP_CLR; controlBoilerPumpSpeed(); - flowToSpeed(); - speedToPwm(); + BoilerPumpPwm = speedToPwm(BoilerPumpSpeed); PwmSet(BoilerPumpPwm); tweakDeltaTs();