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:
Thu Nov 05 13:53:43 2020 +0000
Revision:
99:84c3273dc77f
Parent:
98:c75c959bcde3
Child:
102:d7bc31f0ac6e
Corrected toggle on home page to show radiator state (as labelled) rather than the override state (which is what is toggled to change the radiator state).

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