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:
Sun Oct 04 07:54:54 2020 +0000
Revision:
97:84d58bf7a835
Parent:
96:18a3813bb4b5
Child:
98:c75c959bcde3
Added bound checks to radiator settings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 0:3c04f4b47041 1 #include <stdint.h>
andrewboyson 0:3c04f4b47041 2 #include <string.h>
andrewboyson 0:3c04f4b47041 3 #include <stdbool.h>
andrewboyson 0:3c04f4b47041 4
andrewboyson 35:bb8a6d1c034c 5 #include "gpio.h"
andrewboyson 35:bb8a6d1c034c 6 #include "program.h"
andrewboyson 35:bb8a6d1c034c 7 #include "ds18b20.h"
andrewboyson 35:bb8a6d1c034c 8 #include "fram.h"
andrewboyson 0:3c04f4b47041 9 #include "radiator.h"
andrewboyson 95:97621bfbedfa 10 #include "clktime.h"
andrewboyson 95:97621bfbedfa 11 #include "clk.h"
andrewboyson 35:bb8a6d1c034c 12 #include "led.h"
andrewboyson 5:82197a6997fd 13
andrewboyson 5:82197a6997fd 14
andrewboyson 5:82197a6997fd 15 #define RADIATOR_PUMP_DIR FIO2DIR(03) // P2.03 == p23;
andrewboyson 5:82197a6997fd 16 #define RADIATOR_PUMP_PIN FIO2PIN(03)
andrewboyson 5:82197a6997fd 17 #define RADIATOR_PUMP_SET FIO2SET(03)
andrewboyson 5:82197a6997fd 18 #define RADIATOR_PUMP_CLR FIO2CLR(03)
andrewboyson 0:3c04f4b47041 19
andrewboyson 95:97621bfbedfa 20 static char htgWinter; static int iWinter;
andrewboyson 95:97621bfbedfa 21 static char htgOverride; static int iOverride;
andrewboyson 95:97621bfbedfa 22 static char* hallRom; static int iHallRom;
andrewboyson 96:18a3813bb4b5 23 static uint8_t overrideCancelHour; static int iOverrideCancelHour;
andrewboyson 96:18a3813bb4b5 24 static uint8_t overrideCancelMinute; static int iOverrideCancelMinute;
andrewboyson 95:97621bfbedfa 25 static int16_t nightTemperature; static int iNightTemperature;
andrewboyson 95:97621bfbedfa 26 static int16_t frostTemperature; static int iFrostTemperature;
andrewboyson 0:3c04f4b47041 27
andrewboyson 95:97621bfbedfa 28 bool RadiatorGetWinter () { return (bool)htgWinter; }
andrewboyson 95:97621bfbedfa 29 bool RadiatorGetOverride () { return (bool)htgOverride; }
andrewboyson 95:97621bfbedfa 30 uint16_t RadiatorGetHallDS18B20Value () { return DS18B20ValueFromRom(hallRom); }
andrewboyson 96:18a3813bb4b5 31 int RadiatorGetOverrideCancelHour () { return (int)overrideCancelHour; }
andrewboyson 96:18a3813bb4b5 32 int RadiatorGetOverrideCancelMinute() { return (int)overrideCancelMinute; }
andrewboyson 95:97621bfbedfa 33 int RadiatorGetNightTemperature () { return (int)nightTemperature; }
andrewboyson 95:97621bfbedfa 34 int RadiatorGetFrostTemperature () { return (int)frostTemperature; }
andrewboyson 0:3c04f4b47041 35
andrewboyson 97:84d58bf7a835 36 static void setWinter ( bool v) { htgWinter = (char)v; FramWrite(iWinter, 1, &htgWinter ); }
andrewboyson 97:84d58bf7a835 37 static void setOverride ( bool v) { htgOverride = (char)v; FramWrite(iOverride, 1, &htgOverride ); }
andrewboyson 97:84d58bf7a835 38 static void setHallRom ( char* v) { memcpy(hallRom, v, 8); FramWrite(iHallRom, 8, hallRom ); }
andrewboyson 97:84d58bf7a835 39 void RadiatorSetOverrideCancelHour ( int v) { if (v > 23 || v < 0) v = 0; overrideCancelHour = (uint8_t)v, FramWrite(iOverrideCancelHour, 1, &overrideCancelHour ); }
andrewboyson 97:84d58bf7a835 40 void RadiatorSetOverrideCancelMinute( int v) { if (v > 59 || v < 0) v = 0; overrideCancelMinute = (uint8_t)v, FramWrite(iOverrideCancelMinute, 1, &overrideCancelMinute); }
andrewboyson 97:84d58bf7a835 41 void RadiatorSetNightTemperature ( int v) { if (v > 99 || v < 0) v = 0; nightTemperature = (int16_t)v; FramWrite(iNightTemperature, 2, &nightTemperature ); }
andrewboyson 97:84d58bf7a835 42 void RadiatorSetFrostTemperature ( int v) { if (v > 99 || v < 0) v = 0; frostTemperature = (int16_t)v; FramWrite(iFrostTemperature, 2, &frostTemperature ); }
andrewboyson 0:3c04f4b47041 43
andrewboyson 0:3c04f4b47041 44 static bool outputBeforeOverride = false;
andrewboyson 0:3c04f4b47041 45 static void makeOutputBeforeOverride()
andrewboyson 0:3c04f4b47041 46 {
andrewboyson 0:3c04f4b47041 47 //See if the temperature is too low
andrewboyson 0:3c04f4b47041 48 int hallTemp16ths = DS18B20ValueFromRom(hallRom);
andrewboyson 0:3c04f4b47041 49 int nightTemp16ths = nightTemperature << 4;
andrewboyson 0:3c04f4b47041 50 int frostTemp16ths = frostTemperature << 4;
andrewboyson 0:3c04f4b47041 51
andrewboyson 0:3c04f4b47041 52 static bool tooCold = false; //This is static to ride through invalid temperature reads
andrewboyson 0:3c04f4b47041 53 if (DS18B20IsValidValue(hallTemp16ths))
andrewboyson 0:3c04f4b47041 54 {
andrewboyson 0:3c04f4b47041 55 tooCold = hallTemp16ths < frostTemp16ths;
andrewboyson 57:72c1c1357861 56 if (htgWinter) tooCold |= hallTemp16ths < nightTemp16ths;
andrewboyson 0:3c04f4b47041 57 }
andrewboyson 0:3c04f4b47041 58
andrewboyson 76:3ef2a46c8b1e 59 outputBeforeOverride = (htgWinter && ProgramTimerOutput) || tooCold;
andrewboyson 0:3c04f4b47041 60 }
andrewboyson 96:18a3813bb4b5 61 static void autoCancelOverride()
andrewboyson 0:3c04f4b47041 62 {
andrewboyson 95:97621bfbedfa 63
andrewboyson 95:97621bfbedfa 64 //Remove override at 11pm
andrewboyson 96:18a3813bb4b5 65 if (ClkTimeIsSet())
andrewboyson 95:97621bfbedfa 66 {
andrewboyson 95:97621bfbedfa 67 struct tm tm;
andrewboyson 95:97621bfbedfa 68 ClkNowTmLocal(&tm);
andrewboyson 96:18a3813bb4b5 69 static bool cancelWasDue = false;
andrewboyson 96:18a3813bb4b5 70 bool cancelIsDue = tm.tm_hour == overrideCancelHour && tm.tm_min == overrideCancelMinute;
andrewboyson 96:18a3813bb4b5 71 if (cancelIsDue && !cancelWasDue && htgOverride) setOverride(false);
andrewboyson 96:18a3813bb4b5 72 cancelWasDue = cancelIsDue;
andrewboyson 95:97621bfbedfa 73 }
andrewboyson 95:97621bfbedfa 74
andrewboyson 95:97621bfbedfa 75 //Remove override if no longer required
andrewboyson 0:3c04f4b47041 76 static bool previousOutput = false;
andrewboyson 96:18a3813bb4b5 77 if (previousOutput != outputBeforeOverride && htgOverride) setOverride(false);
andrewboyson 0:3c04f4b47041 78 previousOutput = outputBeforeOverride;
andrewboyson 0:3c04f4b47041 79 }
andrewboyson 0:3c04f4b47041 80 bool RadiatorPump = false;
andrewboyson 0:3c04f4b47041 81 static void makeOutputWithOverride()
andrewboyson 0:3c04f4b47041 82 {
andrewboyson 0:3c04f4b47041 83 RadiatorPump = htgOverride ? !outputBeforeOverride : outputBeforeOverride ;
andrewboyson 0:3c04f4b47041 84 }
andrewboyson 0:3c04f4b47041 85
andrewboyson 57:72c1c1357861 86 void RadiatorSetWinter(bool value) //Summer is false, Winter is true
andrewboyson 0:3c04f4b47041 87 {
andrewboyson 57:72c1c1357861 88 if (htgWinter == (char)value) return; //Ignore no change
andrewboyson 57:72c1c1357861 89 setWinter(value); //Change to the new value
andrewboyson 0:3c04f4b47041 90
andrewboyson 0:3c04f4b47041 91 bool prevOutputBeforeOverride = outputBeforeOverride;
andrewboyson 0:3c04f4b47041 92 makeOutputBeforeOverride();
andrewboyson 0:3c04f4b47041 93
andrewboyson 0:3c04f4b47041 94 if (htgOverride) //Only deal with an override that is already set; if it wasn't set don't change it
andrewboyson 0:3c04f4b47041 95 {
andrewboyson 57:72c1c1357861 96 if (htgWinter) //Summer -> Winter
andrewboyson 0:3c04f4b47041 97 {
andrewboyson 0:3c04f4b47041 98 if (outputBeforeOverride != prevOutputBeforeOverride) setOverride(0); //Adjust the override to leave the heat as it was - off or on.
andrewboyson 0:3c04f4b47041 99 }
andrewboyson 0:3c04f4b47041 100 else //Winter -> Summer
andrewboyson 0:3c04f4b47041 101 {
andrewboyson 0:3c04f4b47041 102 setOverride(0); //turn off the heat.
andrewboyson 0:3c04f4b47041 103 }
andrewboyson 0:3c04f4b47041 104 }
andrewboyson 0:3c04f4b47041 105
andrewboyson 0:3c04f4b47041 106 makeOutputWithOverride();
andrewboyson 0:3c04f4b47041 107 }
andrewboyson 0:3c04f4b47041 108 void RadiatorSetOverride(bool value)
andrewboyson 0:3c04f4b47041 109 {
andrewboyson 0:3c04f4b47041 110 setOverride(value);
andrewboyson 0:3c04f4b47041 111 makeOutputBeforeOverride();
andrewboyson 0:3c04f4b47041 112 makeOutputWithOverride(); }
andrewboyson 0:3c04f4b47041 113
andrewboyson 57:72c1c1357861 114 void RadiatorChgWinter (){ RadiatorSetWinter (!RadiatorGetWinter ()); }
andrewboyson 0:3c04f4b47041 115 void RadiatorChgOverride(){ RadiatorSetOverride(!RadiatorGetOverride()); }
andrewboyson 0:3c04f4b47041 116
andrewboyson 0:3c04f4b47041 117 int RadiatorInit()
andrewboyson 0:3c04f4b47041 118 {
andrewboyson 48:6eac12df3ad5 119 hallRom = DS18B20Roms + 8 * DS18B20RomCount;
andrewboyson 48:6eac12df3ad5 120 DS18B20RomSetters[DS18B20RomCount] = setHallRom;
andrewboyson 48:6eac12df3ad5 121 DS18B20RomNames[DS18B20RomCount] = "Hall";
andrewboyson 48:6eac12df3ad5 122 DS18B20RomCount++;
andrewboyson 48:6eac12df3ad5 123
andrewboyson 0:3c04f4b47041 124 int address;
andrewboyson 96:18a3813bb4b5 125 int8_t def1;
andrewboyson 95:97621bfbedfa 126 int16_t def2;
andrewboyson 96:18a3813bb4b5 127 def1 = 0; address = FramLoad( 1, &htgWinter, &def1); if (address < 0) return -1; iWinter = address;
andrewboyson 96:18a3813bb4b5 128 def1 = 0; address = FramLoad( 1, &htgOverride, &def1); if (address < 0) return -1; iOverride = address;
andrewboyson 96:18a3813bb4b5 129 address = FramLoad( 8, hallRom, 0); if (address < 0) return -1; iHallRom = address;
andrewboyson 96:18a3813bb4b5 130 def1 = 23; address = FramLoad( 1, &overrideCancelHour, &def1); if (address < 0) return -1; iOverrideCancelHour = address;
andrewboyson 96:18a3813bb4b5 131 def1 = 0; address = FramLoad( 1, &overrideCancelMinute, &def1); if (address < 0) return -1; iOverrideCancelMinute = address;
andrewboyson 95:97621bfbedfa 132 FramAllocate(2); //Spare two bytes
andrewboyson 96:18a3813bb4b5 133 def2 = 15; address = FramLoad( 2, &nightTemperature, &def2); if (address < 0) return -1; iNightTemperature = address;
andrewboyson 96:18a3813bb4b5 134 def2 = 8; address = FramLoad( 2, &frostTemperature, &def2); if (address < 0) return -1; iFrostTemperature = address;
andrewboyson 0:3c04f4b47041 135
andrewboyson 5:82197a6997fd 136 RADIATOR_PUMP_DIR = 1; //Set the direction to 1 == output
andrewboyson 0:3c04f4b47041 137
andrewboyson 0:3c04f4b47041 138 return 0;
andrewboyson 0:3c04f4b47041 139 }
andrewboyson 0:3c04f4b47041 140 void RadiatorMain()
andrewboyson 0:3c04f4b47041 141 {
andrewboyson 0:3c04f4b47041 142 //Make the radiator output
andrewboyson 0:3c04f4b47041 143 makeOutputBeforeOverride();
andrewboyson 96:18a3813bb4b5 144 autoCancelOverride(); //Do this after making the outputt as it uses that information
andrewboyson 0:3c04f4b47041 145 makeOutputWithOverride();
andrewboyson 0:3c04f4b47041 146
andrewboyson 0:3c04f4b47041 147 //Pump output
andrewboyson 5:82197a6997fd 148 if (RadiatorPump) RADIATOR_PUMP_SET;
andrewboyson 5:82197a6997fd 149 else RADIATOR_PUMP_CLR;
andrewboyson 0:3c04f4b47041 150
andrewboyson 0:3c04f4b47041 151 }