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:
102:d7bc31f0ac6e
Not working, crashes.

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