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 Oct 02 15:40:53 2020 +0000
Revision:
95:97621bfbedfa
Parent:
76:3ef2a46c8b1e
Child:
96:18a3813bb4b5
Added 11pm override cancel for the radiators as we kept forgetting to remove the override if used in the summer. Space in the Fram memory for the minute in the day to cancel was found. Still to do the web UI.

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