Controls the central heating system and the lights.

Dependencies:   1-wire clock crypto fram log lpc1768 net web wiz mbed

Committer:
andrewboyson
Date:
Wed Jun 09 09:25:03 2021 +0000
Revision:
6:0164a06f25e7
Parent:
3:f1464bf461c1
Child:
7:e55c6a61e15b
Activated the boiler call disable if delta t is outside of the window.

Who changed what in which revision?

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