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

Committer:
andrewboyson
Date:
Fri Apr 23 08:36:42 2021 +0000
Revision:
106:41ed3ea0bbba
Parent:
105:1899f7ed17ec
Not working, crashes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 0:3c04f4b47041 1 #include <string.h>
andrewboyson 0:3c04f4b47041 2 #include <stdint.h>
andrewboyson 0:3c04f4b47041 3 #include <stdbool.h>
andrewboyson 0:3c04f4b47041 4
andrewboyson 35:bb8a6d1c034c 5 #include "gpio.h"
andrewboyson 35:bb8a6d1c034c 6 #include "mstimer.h"
andrewboyson 1:ccc66fdf858d 7 #include "ds18b20.h"
andrewboyson 35:bb8a6d1c034c 8 #include "fram.h"
andrewboyson 104:46ce1aaf8be7 9 #include "pwm.h"
andrewboyson 104:46ce1aaf8be7 10 #include "log.h"
andrewboyson 0:3c04f4b47041 11
andrewboyson 5:82197a6997fd 12 #define BOILER_PUMP_DIR FIO2DIR(4) // P2.4 == p22
andrewboyson 5:82197a6997fd 13 #define BOILER_PUMP_PIN FIO2PIN(4)
andrewboyson 5:82197a6997fd 14 #define BOILER_PUMP_SET FIO2SET(4)
andrewboyson 5:82197a6997fd 15 #define BOILER_PUMP_CLR FIO2CLR(4)
andrewboyson 5:82197a6997fd 16
andrewboyson 5:82197a6997fd 17 #define BOILER_CALL_DIR FIO2DIR(5) // P2.5 == p21
andrewboyson 5:82197a6997fd 18 #define BOILER_CALL_PIN FIO2PIN(5)
andrewboyson 5:82197a6997fd 19 #define BOILER_CALL_SET FIO2SET(5)
andrewboyson 5:82197a6997fd 20 #define BOILER_CALL_CLR FIO2CLR(5)
andrewboyson 0:3c04f4b47041 21
andrewboyson 105:1899f7ed17ec 22 #define PUMP_SPEED_CALLING_AUTO_ONLY -1
andrewboyson 105:1899f7ed17ec 23 #define PUMP_SPEED_CALLING_AUTO_TWEAK -2
andrewboyson 105:1899f7ed17ec 24
andrewboyson 105:1899f7ed17ec 25 #define MAX_SPEED 100
andrewboyson 105:1899f7ed17ec 26
andrewboyson 48:6eac12df3ad5 27 static char* tankRom; static int iTankRom;
andrewboyson 48:6eac12df3ad5 28 static char* outputRom; static int iOutputRom;
andrewboyson 48:6eac12df3ad5 29 static char* returnRom; static int iReturnRom;
andrewboyson 0:3c04f4b47041 30
andrewboyson 105:1899f7ed17ec 31 static int8_t fullSpeedSecs; static int iFullSpeedSecs;
andrewboyson 105:1899f7ed17ec 32
andrewboyson 105:1899f7ed17ec 33 static int8_t tankSetPoint; static int iTankSetPoint;
andrewboyson 104:46ce1aaf8be7 34 static int16_t tankHysteresis; static int iTankHysteresis;
andrewboyson 106:41ed3ea0bbba 35 static int16_t _runOnDelta16ths; static int iRunOnResidual;
andrewboyson 105:1899f7ed17ec 36 static uint8_t runOnTime2s; static int iRunOnTime;
andrewboyson 104:46ce1aaf8be7 37
andrewboyson 104:46ce1aaf8be7 38 static int8_t boilerTarget; static int iBoilerTarget;
andrewboyson 104:46ce1aaf8be7 39 static int8_t pumpSpeedCalling; static int iPumpSpeedCalling;
andrewboyson 106:41ed3ea0bbba 40 static int8_t _rampDownTime; static int _iRampDownTime;
andrewboyson 104:46ce1aaf8be7 41
andrewboyson 106:41ed3ea0bbba 42 static int8_t _minSpeed; static int _iMinSpeed;
andrewboyson 106:41ed3ea0bbba 43 static int8_t _midSpeedPwm; static int _iMidSpeedPwm;
andrewboyson 106:41ed3ea0bbba 44 static int16_t _fullSpeedDeltaT16ths; static int _iFullSpeedDeltaT;
andrewboyson 0:3c04f4b47041 45
andrewboyson 105:1899f7ed17ec 46 //Set in main scan
andrewboyson 105:1899f7ed17ec 47 static int16_t _boilerOutput16ths = DS18B20_ERROR_VALUE_NOT_SET;
andrewboyson 105:1899f7ed17ec 48 static int16_t _boilerReturn16ths = DS18B20_ERROR_VALUE_NOT_SET;
andrewboyson 105:1899f7ed17ec 49 static int16_t _boilerRtnDel16ths = DS18B20_ERROR_VALUE_NOT_SET;
andrewboyson 105:1899f7ed17ec 50 static int16_t _boilerDeltaT16ths = DS18B20_ERROR_VALUE_NOT_SET;
andrewboyson 105:1899f7ed17ec 51 static bool _boilerDeltaTisValid = false;
andrewboyson 105:1899f7ed17ec 52
andrewboyson 105:1899f7ed17ec 53 int16_t BoilerGetTankDS18B20Value () { return DS18B20ValueFromRom(tankRom); }
andrewboyson 106:41ed3ea0bbba 54 int16_t BoilerGetOutputDS18B20Value() { return _boilerOutput16ths; }
andrewboyson 106:41ed3ea0bbba 55 int16_t BoilerGetReturnDS18B20Value() { return _boilerReturn16ths; }
andrewboyson 106:41ed3ea0bbba 56 int16_t BoilerGetRtnDelDS18B20Value() { return _boilerRtnDel16ths; }
andrewboyson 106:41ed3ea0bbba 57 int16_t BoilerGetDeltaTDS18B20Value() { return _boilerDeltaT16ths; }
andrewboyson 106:41ed3ea0bbba 58 int BoilerGetFullSpeedSecs () { return fullSpeedSecs; }
andrewboyson 106:41ed3ea0bbba 59 int BoilerGetTankSetPoint () { return tankSetPoint; }
andrewboyson 106:41ed3ea0bbba 60 int BoilerGetTankHysteresis () { return tankHysteresis; }
andrewboyson 106:41ed3ea0bbba 61 int BoilerGetRunOnDeltaT () { return _runOnDelta16ths; }
andrewboyson 106:41ed3ea0bbba 62 int BoilerGetRunOnTime () { return runOnTime2s << 1; }
andrewboyson 106:41ed3ea0bbba 63 int BoilerGetPumpSpeedCalling () { return pumpSpeedCalling; }
andrewboyson 106:41ed3ea0bbba 64 int BoilerGetRampDownTime () { return _rampDownTime; }
andrewboyson 106:41ed3ea0bbba 65 int BoilerGetOutputTarget () { return boilerTarget; }
andrewboyson 106:41ed3ea0bbba 66 int BoilerGetMinSpeed () { return _minSpeed; }
andrewboyson 106:41ed3ea0bbba 67 int BoilerGetMidSpeedPwm () { return _midSpeedPwm; }
andrewboyson 106:41ed3ea0bbba 68 int BoilerGetFullSpeedDeltaT () { return _fullSpeedDeltaT16ths; }
andrewboyson 0:3c04f4b47041 69
andrewboyson 106:41ed3ea0bbba 70 static void setTankRom (char* value) { memcpy(tankRom, value, 8); FramWrite(iTankRom, 8, tankRom ); }
andrewboyson 106:41ed3ea0bbba 71 static void setOutputRom (char* value) { memcpy(outputRom, value, 8); FramWrite(iOutputRom, 8, outputRom ); }
andrewboyson 106:41ed3ea0bbba 72 static void setReturnRom (char* value) { memcpy(returnRom, value, 8); FramWrite(iReturnRom, 8, returnRom ); }
andrewboyson 106:41ed3ea0bbba 73 void BoilerSetFullSpeedSecs (int value) { fullSpeedSecs = value; FramWrite(iFullSpeedSecs, 1, &fullSpeedSecs ); }
andrewboyson 106:41ed3ea0bbba 74 void BoilerSetTankSetPoint (int value) { tankSetPoint = value; FramWrite(iTankSetPoint, 1, &tankSetPoint ); }
andrewboyson 106:41ed3ea0bbba 75 void BoilerSetTankHysteresis (int value) { tankHysteresis = value; FramWrite(iTankHysteresis, 2, &tankHysteresis ); }
andrewboyson 106:41ed3ea0bbba 76 void BoilerSetRunOnDeltaT (int value) { _runOnDelta16ths = value; FramWrite(iRunOnResidual, 2, &_runOnDelta16ths ); }
andrewboyson 106:41ed3ea0bbba 77 void BoilerSetRunOnTime (int value) { runOnTime2s = value >> 1;FramWrite(iRunOnTime, 1, &runOnTime2s ); }
andrewboyson 106:41ed3ea0bbba 78 void BoilerSetPumpSpeedCalling (int value) { pumpSpeedCalling = value; FramWrite(iPumpSpeedCalling,1, &pumpSpeedCalling ); }
andrewboyson 106:41ed3ea0bbba 79 void BoilerSetRampDownTime (int value) { _rampDownTime = value; FramWrite(_iRampDownTime, 1, &_rampDownTime ); }
andrewboyson 106:41ed3ea0bbba 80 void BoilerSetOutputTarget (int value) { boilerTarget = value; FramWrite(iBoilerTarget, 1, &boilerTarget ); }
andrewboyson 106:41ed3ea0bbba 81 void BoilerSetMinSpeed (int value) { _minSpeed = value; FramWrite(_iMinSpeed, 1, &_minSpeed ); }
andrewboyson 106:41ed3ea0bbba 82 void BoilerSetMidSpeedPwm (int value) { _midSpeedPwm = value; FramWrite(_iMidSpeedPwm, 1, &_midSpeedPwm ); }
andrewboyson 106:41ed3ea0bbba 83 void BoilerSetFullSpeedDeltaT (int value) { _fullSpeedDeltaT16ths = value; FramWrite(_iFullSpeedDeltaT,2, &_fullSpeedDeltaT16ths); }
andrewboyson 104:46ce1aaf8be7 84
andrewboyson 104:46ce1aaf8be7 85 static int calculateBetweenTwoPoints(int x, int xA, int xB, int yA, int yB)
andrewboyson 104:46ce1aaf8be7 86 {
andrewboyson 104:46ce1aaf8be7 87 float m = (float)(yB - yA) / (xB - xA);
andrewboyson 104:46ce1aaf8be7 88 return yA + m * (x - xA);
andrewboyson 104:46ce1aaf8be7 89 }
andrewboyson 105:1899f7ed17ec 90 static int calculateSpeedFromDeltaT(int deltaT16ths)
andrewboyson 104:46ce1aaf8be7 91 {
andrewboyson 106:41ed3ea0bbba 92 if (deltaT16ths < _fullSpeedDeltaT16ths) return MAX_SPEED; //Needed in case deltaT16ths is negative or zero
andrewboyson 106:41ed3ea0bbba 93 int speed = MAX_SPEED * _fullSpeedDeltaT16ths / deltaT16ths; //eg for 20 deg ==> 100 * (10 << 4) / (20 << 4) == 50
andrewboyson 106:41ed3ea0bbba 94 if (speed > MAX_SPEED) speed = MAX_SPEED;
andrewboyson 106:41ed3ea0bbba 95 if (speed < _minSpeed) speed = _minSpeed;
andrewboyson 106:41ed3ea0bbba 96 return speed;
andrewboyson 105:1899f7ed17ec 97 }
andrewboyson 105:1899f7ed17ec 98 static int calculateDeltaTFromSpeed(int speed)
andrewboyson 105:1899f7ed17ec 99 {
andrewboyson 106:41ed3ea0bbba 100 int deltaT16ths = MAX_SPEED * _fullSpeedDeltaT16ths / speed; //eg for speed = 50 ==> 100 * (10 << 4) / 50 == 20 << 4
andrewboyson 105:1899f7ed17ec 101 return deltaT16ths;
andrewboyson 104:46ce1aaf8be7 102 }
andrewboyson 0:3c04f4b47041 103
andrewboyson 0:3c04f4b47041 104 int BoilerInit()
andrewboyson 0:3c04f4b47041 105 {
andrewboyson 48:6eac12df3ad5 106 tankRom = DS18B20Roms + 8 * DS18B20RomCount;
andrewboyson 48:6eac12df3ad5 107 DS18B20RomSetters[DS18B20RomCount] = setTankRom;
andrewboyson 48:6eac12df3ad5 108 DS18B20RomNames[DS18B20RomCount] = "Tank";
andrewboyson 48:6eac12df3ad5 109 DS18B20RomCount++;
andrewboyson 48:6eac12df3ad5 110
andrewboyson 48:6eac12df3ad5 111 outputRom = DS18B20Roms + 8 * DS18B20RomCount;
andrewboyson 48:6eac12df3ad5 112 DS18B20RomSetters[DS18B20RomCount] = setOutputRom;
andrewboyson 48:6eac12df3ad5 113 DS18B20RomNames[DS18B20RomCount] = "BlrOut";
andrewboyson 48:6eac12df3ad5 114 DS18B20RomCount++;
andrewboyson 48:6eac12df3ad5 115
andrewboyson 48:6eac12df3ad5 116 returnRom = DS18B20Roms + 8 * DS18B20RomCount;
andrewboyson 48:6eac12df3ad5 117 DS18B20RomSetters[DS18B20RomCount] = setReturnRom;
andrewboyson 48:6eac12df3ad5 118 DS18B20RomNames[DS18B20RomCount] = "BlrRtn";
andrewboyson 48:6eac12df3ad5 119 DS18B20RomCount++;
andrewboyson 48:6eac12df3ad5 120
andrewboyson 0:3c04f4b47041 121 int address;
andrewboyson 104:46ce1aaf8be7 122 uint8_t def1;
andrewboyson 104:46ce1aaf8be7 123 int16_t def2;
andrewboyson 0:3c04f4b47041 124 int32_t def4;
andrewboyson 106:41ed3ea0bbba 125 address = FramLoad( 8, tankRom, 0); if (address < 0) return -1; iTankRom = address;
andrewboyson 106:41ed3ea0bbba 126 address = FramLoad( 8, outputRom, 0); if (address < 0) return -1; iOutputRom = address;
andrewboyson 106:41ed3ea0bbba 127 address = FramLoad( 8, returnRom, 0); if (address < 0) return -1; iReturnRom = address;
andrewboyson 106:41ed3ea0bbba 128 def1 = 100; address = FramLoad( 1, &fullSpeedSecs, &def1); if (address < 0) return -1; iFullSpeedSecs = address;
andrewboyson 106:41ed3ea0bbba 129 def1 = 65; address = FramLoad( 1, &tankSetPoint, &def1); if (address < 0) return -1; iTankSetPoint = address;
andrewboyson 106:41ed3ea0bbba 130 def2 = 5; address = FramLoad( 2, &tankHysteresis, &def2); if (address < 0) return -1; iTankHysteresis = address;
andrewboyson 106:41ed3ea0bbba 131 def2 = 2; address = FramLoad( 2, &_runOnDelta16ths, &def2); if (address < 0) return -1; iRunOnResidual = address;
andrewboyson 106:41ed3ea0bbba 132 def1 = 180; address = FramLoad( 1, &runOnTime2s, &def1); if (address < 0) return -1; iRunOnTime = address;
andrewboyson 106:41ed3ea0bbba 133 def1 = 100; address = FramLoad( 1, &pumpSpeedCalling, &def1); if (address < 0) return -1; iPumpSpeedCalling = address;
andrewboyson 106:41ed3ea0bbba 134 def1 = 10; address = FramLoad( 1, &_rampDownTime, &def1); if (address < 0) return -1; _iRampDownTime = address;
andrewboyson 106:41ed3ea0bbba 135 def1 = 65; address = FramLoad( 1, &boilerTarget, &def1); if (address < 0) return -1; iBoilerTarget = address;
andrewboyson 106:41ed3ea0bbba 136 def1 = 50; address = FramLoad( 1, &_minSpeed, &def1); if (address < 0) return -1; _iMinSpeed = address;
andrewboyson 106:41ed3ea0bbba 137 FramAllocate(1);
andrewboyson 106:41ed3ea0bbba 138 def1 = 50; address = FramLoad( 1, &_midSpeedPwm, &def1); if (address < 0) return -1; _iMidSpeedPwm = address;
andrewboyson 106:41ed3ea0bbba 139 FramAllocate(1);
andrewboyson 106:41ed3ea0bbba 140 def2 = 10<<4; address = FramLoad( 2, &_fullSpeedDeltaT16ths, &def2); if (address < 0) return -1; _iFullSpeedDeltaT = address;
andrewboyson 0:3c04f4b47041 141
andrewboyson 5:82197a6997fd 142 BOILER_PUMP_DIR = 1; //Set the direction to 1 == output
andrewboyson 5:82197a6997fd 143 BOILER_CALL_DIR = 1; //Set the direction to 1 == output
andrewboyson 48:6eac12df3ad5 144
andrewboyson 104:46ce1aaf8be7 145 PwmInit(400, 100);
andrewboyson 104:46ce1aaf8be7 146
andrewboyson 0:3c04f4b47041 147 return 0;
andrewboyson 0:3c04f4b47041 148 }
andrewboyson 105:1899f7ed17ec 149 bool BoilerCallEnable = true;
andrewboyson 0:3c04f4b47041 150 bool BoilerCall = false;
andrewboyson 35:bb8a6d1c034c 151 static void controlBoilerCall()
andrewboyson 0:3c04f4b47041 152 {
andrewboyson 105:1899f7ed17ec 153 if (BoilerCallEnable)
andrewboyson 0:3c04f4b47041 154 {
andrewboyson 105:1899f7ed17ec 155 int tankTemp16ths = DS18B20ValueFromRom(tankRom);
andrewboyson 105:1899f7ed17ec 156 if (DS18B20IsValidValue(tankTemp16ths)) //Ignore values which are likely to be wrong
andrewboyson 105:1899f7ed17ec 157 {
andrewboyson 105:1899f7ed17ec 158 int tankUpper16ths = tankSetPoint << 4;
andrewboyson 105:1899f7ed17ec 159 int hysteresis16ths = tankHysteresis << 4;
andrewboyson 105:1899f7ed17ec 160 int tankLower16ths = tankUpper16ths - hysteresis16ths;
andrewboyson 105:1899f7ed17ec 161
andrewboyson 105:1899f7ed17ec 162 if (tankTemp16ths >= tankUpper16ths) BoilerCall = false;
andrewboyson 105:1899f7ed17ec 163 if (tankTemp16ths <= tankLower16ths) BoilerCall = true;
andrewboyson 105:1899f7ed17ec 164 }
andrewboyson 105:1899f7ed17ec 165 }
andrewboyson 105:1899f7ed17ec 166 else
andrewboyson 105:1899f7ed17ec 167 {
andrewboyson 105:1899f7ed17ec 168 BoilerCall = false;
andrewboyson 0:3c04f4b47041 169 }
andrewboyson 35:bb8a6d1c034c 170 }
andrewboyson 35:bb8a6d1c034c 171 bool BoilerPump = false;
andrewboyson 35:bb8a6d1c034c 172 static void controlBoilerPump()
andrewboyson 35:bb8a6d1c034c 173 {
andrewboyson 35:bb8a6d1c034c 174 static uint32_t msTimerBoilerPumpRunOn = 0;
andrewboyson 0:3c04f4b47041 175 if (BoilerCall)
andrewboyson 0:3c04f4b47041 176 {
andrewboyson 0:3c04f4b47041 177 BoilerPump = true;
andrewboyson 35:bb8a6d1c034c 178 msTimerBoilerPumpRunOn = MsTimerCount;
andrewboyson 0:3c04f4b47041 179 }
andrewboyson 0:3c04f4b47041 180 else
andrewboyson 0:3c04f4b47041 181 {
andrewboyson 106:41ed3ea0bbba 182 if (MsTimerRelative(msTimerBoilerPumpRunOn, runOnTime2s * 2000)) BoilerPump = false;
andrewboyson 106:41ed3ea0bbba 183 if (_boilerDeltaTisValid && _boilerDeltaT16ths < _runOnDelta16ths ) BoilerPump = false;
andrewboyson 104:46ce1aaf8be7 184 }
andrewboyson 104:46ce1aaf8be7 185 }
andrewboyson 106:41ed3ea0bbba 186 int BoilerPumpFlow = MAX_SPEED;
andrewboyson 106:41ed3ea0bbba 187 int BoilerPumpSpeed = MAX_SPEED;
andrewboyson 104:46ce1aaf8be7 188 int BoilerPumpPwm = 0;
andrewboyson 104:46ce1aaf8be7 189 static int _autoSpeed = 0;
andrewboyson 104:46ce1aaf8be7 190 static void calculateAutoSpeed()
andrewboyson 104:46ce1aaf8be7 191 {
andrewboyson 105:1899f7ed17ec 192 if (!DS18B20IsValidValue(_boilerReturn16ths)) return;
andrewboyson 104:46ce1aaf8be7 193
andrewboyson 104:46ce1aaf8be7 194 int target16ths = (int)boilerTarget << 4;
andrewboyson 105:1899f7ed17ec 195 int targetRise16ths = target16ths - _boilerReturn16ths; //eg 65 - eg 45 = 20*16 16ths
andrewboyson 104:46ce1aaf8be7 196
andrewboyson 105:1899f7ed17ec 197 _autoSpeed = calculateSpeedFromDeltaT(targetRise16ths);
andrewboyson 104:46ce1aaf8be7 198 }
andrewboyson 104:46ce1aaf8be7 199 static void controlBoilerPumpSpeed()
andrewboyson 104:46ce1aaf8be7 200 {
andrewboyson 104:46ce1aaf8be7 201 static uint32_t msTimerReduction = 0;
andrewboyson 104:46ce1aaf8be7 202 calculateAutoSpeed();
andrewboyson 104:46ce1aaf8be7 203 if (BoilerCall)
andrewboyson 104:46ce1aaf8be7 204 {
andrewboyson 106:41ed3ea0bbba 205 if (pumpSpeedCalling < 0) BoilerPumpSpeed = _autoSpeed; //Auto
andrewboyson 106:41ed3ea0bbba 206 else BoilerPumpSpeed = pumpSpeedCalling; //Manual
andrewboyson 104:46ce1aaf8be7 207 msTimerReduction = MsTimerCount;
andrewboyson 104:46ce1aaf8be7 208 }
andrewboyson 104:46ce1aaf8be7 209 else
andrewboyson 104:46ce1aaf8be7 210 {
andrewboyson 106:41ed3ea0bbba 211 if (BoilerPumpSpeed > _minSpeed)
andrewboyson 104:46ce1aaf8be7 212 {
andrewboyson 106:41ed3ea0bbba 213 int msPerUnit = 1000 * _rampDownTime / (MAX_SPEED - _minSpeed);
andrewboyson 106:41ed3ea0bbba 214 if (MsTimerRepetitive(&msTimerReduction, msPerUnit)) BoilerPumpSpeed--;
andrewboyson 104:46ce1aaf8be7 215 }
andrewboyson 104:46ce1aaf8be7 216 else
andrewboyson 104:46ce1aaf8be7 217 {
andrewboyson 106:41ed3ea0bbba 218 BoilerPumpSpeed = _minSpeed;
andrewboyson 104:46ce1aaf8be7 219 }
andrewboyson 0:3c04f4b47041 220 }
andrewboyson 106:41ed3ea0bbba 221 if (BoilerPumpSpeed < _minSpeed) BoilerPumpSpeed = _minSpeed;
andrewboyson 106:41ed3ea0bbba 222 if (BoilerPumpSpeed > MAX_SPEED) BoilerPumpSpeed = MAX_SPEED;
andrewboyson 35:bb8a6d1c034c 223 }
andrewboyson 106:41ed3ea0bbba 224 static int speedToPwm(int speed)
andrewboyson 105:1899f7ed17ec 225 {
andrewboyson 106:41ed3ea0bbba 226 #define MAX_SPEED_PWM 10
andrewboyson 106:41ed3ea0bbba 227 #define MIN_SPEED_PWM 84
andrewboyson 104:46ce1aaf8be7 228 /*
andrewboyson 104:46ce1aaf8be7 229 PWM input signal [%] Pump status
andrewboyson 104:46ce1aaf8be7 230 ≤ 10 Maximum speed
andrewboyson 104:46ce1aaf8be7 231 > 10 / ≤ 84 Variable speed from minimum to maximum
andrewboyson 104:46ce1aaf8be7 232 speed
andrewboyson 104:46ce1aaf8be7 233 > 84 / ≤ 91 Minimum speed
andrewboyson 104:46ce1aaf8be7 234 > 91/95 Hysteresis area: on/off
andrewboyson 104:46ce1aaf8be7 235 > 95 / ≤ 100 Standby mode: off
andrewboyson 104:46ce1aaf8be7 236
andrewboyson 104:46ce1aaf8be7 237 Max speed 100 is at fitted = 74; pwm = 10
andrewboyson 104:46ce1aaf8be7 238 Min speed 0 is at fitted = 0; pwm = 84
andrewboyson 104:46ce1aaf8be7 239 */
andrewboyson 106:41ed3ea0bbba 240 if (speed <= _minSpeed) return MIN_SPEED_PWM;
andrewboyson 106:41ed3ea0bbba 241 if (speed >= MAX_SPEED) return MAX_SPEED_PWM;
andrewboyson 106:41ed3ea0bbba 242 int midSpeed = (_minSpeed + MAX_SPEED) / 2;
andrewboyson 106:41ed3ea0bbba 243 if (speed < midSpeed) return calculateBetweenTwoPoints(speed, _minSpeed, midSpeed, MIN_SPEED_PWM, _midSpeedPwm);
andrewboyson 106:41ed3ea0bbba 244 else return calculateBetweenTwoPoints(speed, midSpeed, MAX_SPEED, _midSpeedPwm, MAX_SPEED_PWM);
andrewboyson 106:41ed3ea0bbba 245 //int pwm = calculateBetweenTwoPoints(BoilerPumpSpeed, _minSpeed, MAX_SPEED, 84, 10);
andrewboyson 106:41ed3ea0bbba 246 //if (pwm < 10) pwm = 10;
andrewboyson 106:41ed3ea0bbba 247 //if (pwm > 84) pwm = 84;
andrewboyson 106:41ed3ea0bbba 248 //BoilerPumpPwm = pwm;
andrewboyson 104:46ce1aaf8be7 249 }
andrewboyson 104:46ce1aaf8be7 250 #define TIME_BEFORE_TWEAK_SECS 120
andrewboyson 104:46ce1aaf8be7 251 static void tweakDeltaTs()
andrewboyson 104:46ce1aaf8be7 252 {
andrewboyson 105:1899f7ed17ec 253 if (pumpSpeedCalling != PUMP_SPEED_CALLING_AUTO_TWEAK) return;
andrewboyson 105:1899f7ed17ec 254
andrewboyson 104:46ce1aaf8be7 255 static uint32_t msTimerBoilerHeating = 0;
andrewboyson 104:46ce1aaf8be7 256 if (!BoilerCall) msTimerBoilerHeating = MsTimerCount;
andrewboyson 104:46ce1aaf8be7 257 if (!MsTimerRelative(msTimerBoilerHeating, TIME_BEFORE_TWEAK_SECS * 1000)) return;
andrewboyson 104:46ce1aaf8be7 258
andrewboyson 105:1899f7ed17ec 259 if (!_boilerDeltaTisValid) return;
andrewboyson 104:46ce1aaf8be7 260
andrewboyson 104:46ce1aaf8be7 261 static int speedLastScan = -1;
andrewboyson 104:46ce1aaf8be7 262
andrewboyson 105:1899f7ed17ec 263 if (speedLastScan < MAX_SPEED && BoilerPumpSpeed == MAX_SPEED)
andrewboyson 104:46ce1aaf8be7 264 {
andrewboyson 106:41ed3ea0bbba 265 if (_fullSpeedDeltaT16ths > _boilerDeltaT16ths) _fullSpeedDeltaT16ths--;
andrewboyson 106:41ed3ea0bbba 266 if (_fullSpeedDeltaT16ths < _boilerDeltaT16ths) _fullSpeedDeltaT16ths++;
andrewboyson 104:46ce1aaf8be7 267 }
andrewboyson 104:46ce1aaf8be7 268
andrewboyson 104:46ce1aaf8be7 269 speedLastScan = BoilerPumpSpeed;
andrewboyson 104:46ce1aaf8be7 270 }
andrewboyson 105:1899f7ed17ec 271
andrewboyson 105:1899f7ed17ec 272 #define TIME_BEFORE_DELTA_T_ALARM_SECS 300
andrewboyson 105:1899f7ed17ec 273 #define DELTA_T_LIMIT (3 << 4)
andrewboyson 105:1899f7ed17ec 274 static void checkDeltaTs()
andrewboyson 105:1899f7ed17ec 275 {
andrewboyson 105:1899f7ed17ec 276 static uint32_t msTimerDeltaTNonConform = 0;
andrewboyson 105:1899f7ed17ec 277 if (!BoilerCall)
andrewboyson 105:1899f7ed17ec 278 {
andrewboyson 105:1899f7ed17ec 279 msTimerDeltaTNonConform = MsTimerCount;
andrewboyson 105:1899f7ed17ec 280 return;
andrewboyson 105:1899f7ed17ec 281 }
andrewboyson 105:1899f7ed17ec 282
andrewboyson 105:1899f7ed17ec 283 int expectedDeltaT16ths = calculateDeltaTFromSpeed(BoilerPumpSpeed);
andrewboyson 105:1899f7ed17ec 284
andrewboyson 105:1899f7ed17ec 285 bool deltaTisOk = _boilerDeltaTisValid &&
andrewboyson 105:1899f7ed17ec 286 _boilerDeltaT16ths > (expectedDeltaT16ths - DELTA_T_LIMIT) &&
andrewboyson 105:1899f7ed17ec 287 _boilerDeltaT16ths < (expectedDeltaT16ths + DELTA_T_LIMIT);
andrewboyson 105:1899f7ed17ec 288
andrewboyson 105:1899f7ed17ec 289
andrewboyson 105:1899f7ed17ec 290 static bool deltaTwasOk = true;
andrewboyson 105:1899f7ed17ec 291
andrewboyson 105:1899f7ed17ec 292 /*
andrewboyson 105:1899f7ed17ec 293 if (deltaTwasOk != deltaTisOk)
andrewboyson 105:1899f7ed17ec 294 {
andrewboyson 105:1899f7ed17ec 295 LogTimeF("Boiler delta T ");
andrewboyson 105:1899f7ed17ec 296 DS18B20Log(_boilerDeltaT16ths);
andrewboyson 105:1899f7ed17ec 297 if (deltaTisOk)
andrewboyson 105:1899f7ed17ec 298 {
andrewboyson 105:1899f7ed17ec 299 Log(" is inside expected value ");
andrewboyson 105:1899f7ed17ec 300 }
andrewboyson 105:1899f7ed17ec 301 else
andrewboyson 105:1899f7ed17ec 302 {
andrewboyson 105:1899f7ed17ec 303 Log(" is outside expected value ");
andrewboyson 105:1899f7ed17ec 304 }
andrewboyson 105:1899f7ed17ec 305 DS18B20Log(expectedDeltaT16ths);
andrewboyson 105:1899f7ed17ec 306 Log("\r\n");
andrewboyson 105:1899f7ed17ec 307 }
andrewboyson 105:1899f7ed17ec 308
andrewboyson 105:1899f7ed17ec 309 deltaTwasOk = deltaTisOk;
andrewboyson 105:1899f7ed17ec 310 */
andrewboyson 105:1899f7ed17ec 311
andrewboyson 105:1899f7ed17ec 312 static bool hadAlarm = false;
andrewboyson 105:1899f7ed17ec 313 if (deltaTisOk) msTimerDeltaTNonConform = MsTimerCount;
andrewboyson 105:1899f7ed17ec 314 bool haveAlarm = MsTimerRelative(msTimerDeltaTNonConform, TIME_BEFORE_DELTA_T_ALARM_SECS * 1000);
andrewboyson 105:1899f7ed17ec 315 if (haveAlarm && !hadAlarm)
andrewboyson 105:1899f7ed17ec 316 {
andrewboyson 105:1899f7ed17ec 317 LogTimeF("Boiler delta T would have tripped after not being ok for %d seconds\r\n", TIME_BEFORE_DELTA_T_ALARM_SECS);
andrewboyson 105:1899f7ed17ec 318 }
andrewboyson 105:1899f7ed17ec 319 hadAlarm = haveAlarm;
andrewboyson 105:1899f7ed17ec 320 }
andrewboyson 105:1899f7ed17ec 321 #define NUMBER_OF_STEPS 10
andrewboyson 105:1899f7ed17ec 322 static int16_t _returns16ths[NUMBER_OF_STEPS]; //0 is last, 9th is first
andrewboyson 105:1899f7ed17ec 323 static void delayLine()
andrewboyson 105:1899f7ed17ec 324 {
andrewboyson 105:1899f7ed17ec 325 static uint32_t msTimerDelay = 0;
andrewboyson 105:1899f7ed17ec 326 if (BoilerPump)
andrewboyson 105:1899f7ed17ec 327 {
andrewboyson 105:1899f7ed17ec 328 int msTotal = 1000 * fullSpeedSecs * MAX_SPEED / BoilerPumpSpeed; //speed 10 ==> 10000; speed 100 ==> 1000
andrewboyson 105:1899f7ed17ec 329 int msPerStep = msTotal / NUMBER_OF_STEPS;
andrewboyson 105:1899f7ed17ec 330 if (MsTimerRelative(msTimerDelay, msPerStep))
andrewboyson 105:1899f7ed17ec 331 {
andrewboyson 105:1899f7ed17ec 332 for (int i = 0; i < NUMBER_OF_STEPS - 1; i++) _returns16ths[i] = _returns16ths[i + 1];
andrewboyson 105:1899f7ed17ec 333 _returns16ths[NUMBER_OF_STEPS - 1] = _boilerReturn16ths;
andrewboyson 105:1899f7ed17ec 334 msTimerDelay = MsTimerCount;
andrewboyson 105:1899f7ed17ec 335 //LogTimeF("Ms per step = %d, delayed boiler return = ", msPerStep);
andrewboyson 105:1899f7ed17ec 336 //DS18B20Log(_returns16ths[0]);
andrewboyson 105:1899f7ed17ec 337 //Log("\r\n");
andrewboyson 105:1899f7ed17ec 338 }
andrewboyson 105:1899f7ed17ec 339 }
andrewboyson 105:1899f7ed17ec 340 else
andrewboyson 105:1899f7ed17ec 341 {
andrewboyson 105:1899f7ed17ec 342 msTimerDelay = MsTimerCount;
andrewboyson 105:1899f7ed17ec 343 for (int i = 0; i < NUMBER_OF_STEPS; i++) _returns16ths[i] = DS18B20_ERROR_VALUE_NOT_SET;
andrewboyson 105:1899f7ed17ec 344 }
andrewboyson 105:1899f7ed17ec 345 }
andrewboyson 105:1899f7ed17ec 346
andrewboyson 35:bb8a6d1c034c 347 void BoilerMain()
andrewboyson 35:bb8a6d1c034c 348 {
andrewboyson 105:1899f7ed17ec 349 delayLine();
andrewboyson 105:1899f7ed17ec 350 _boilerOutput16ths = DS18B20ValueFromRom(outputRom);
andrewboyson 105:1899f7ed17ec 351 _boilerReturn16ths = DS18B20ValueFromRom(returnRom);
andrewboyson 105:1899f7ed17ec 352 _boilerRtnDel16ths = _returns16ths[0];
andrewboyson 105:1899f7ed17ec 353 _boilerDeltaTisValid = DS18B20IsValidValue(_boilerOutput16ths) && DS18B20IsValidValue(_boilerRtnDel16ths);
andrewboyson 105:1899f7ed17ec 354 if (_boilerDeltaTisValid) _boilerDeltaT16ths = _boilerOutput16ths - _boilerRtnDel16ths;
andrewboyson 105:1899f7ed17ec 355 else _boilerDeltaT16ths = DS18B20_ERROR_VALUE_NOT_SET;
andrewboyson 105:1899f7ed17ec 356
andrewboyson 35:bb8a6d1c034c 357 controlBoilerCall();
andrewboyson 35:bb8a6d1c034c 358 if (BoilerCall) BOILER_CALL_SET;
andrewboyson 35:bb8a6d1c034c 359 else BOILER_CALL_CLR;
andrewboyson 0:3c04f4b47041 360
andrewboyson 35:bb8a6d1c034c 361 controlBoilerPump();
andrewboyson 5:82197a6997fd 362 if (BoilerPump) BOILER_PUMP_SET;
andrewboyson 5:82197a6997fd 363 else BOILER_PUMP_CLR;
andrewboyson 0:3c04f4b47041 364
andrewboyson 104:46ce1aaf8be7 365 controlBoilerPumpSpeed();
andrewboyson 106:41ed3ea0bbba 366 BoilerPumpPwm = speedToPwm(BoilerPumpSpeed);
andrewboyson 104:46ce1aaf8be7 367 PwmSet(BoilerPumpPwm);
andrewboyson 104:46ce1aaf8be7 368
andrewboyson 104:46ce1aaf8be7 369 tweakDeltaTs();
andrewboyson 105:1899f7ed17ec 370 checkDeltaTs();
andrewboyson 0:3c04f4b47041 371 }