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
heating/boiler.c@91:8b192efd0288, 2020-06-10 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Jun 10 10:08:06 2020 +0000
- Revision:
- 91:8b192efd0288
- Parent:
- 48:6eac12df3ad5
- Child:
- 104:46ce1aaf8be7
Changed the run on residual to a fixed 4 bit fraction temperature to allow better than one degree precision.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 0:3c04f4b47041 | 1 | #include <string.h> |
andrewboyson | 0:3c04f4b47041 | 2 | #include <stdint.h> |
andrewboyson | 0:3c04f4b47041 | 3 | #include <stdbool.h> |
andrewboyson | 0:3c04f4b47041 | 4 | |
andrewboyson | 35:bb8a6d1c034c | 5 | #include "gpio.h" |
andrewboyson | 35:bb8a6d1c034c | 6 | #include "mstimer.h" |
andrewboyson | 1:ccc66fdf858d | 7 | #include "ds18b20.h" |
andrewboyson | 35:bb8a6d1c034c | 8 | #include "fram.h" |
andrewboyson | 0:3c04f4b47041 | 9 | |
andrewboyson | 5:82197a6997fd | 10 | #define BOILER_PUMP_DIR FIO2DIR(4) // P2.4 == p22 |
andrewboyson | 5:82197a6997fd | 11 | #define BOILER_PUMP_PIN FIO2PIN(4) |
andrewboyson | 5:82197a6997fd | 12 | #define BOILER_PUMP_SET FIO2SET(4) |
andrewboyson | 5:82197a6997fd | 13 | #define BOILER_PUMP_CLR FIO2CLR(4) |
andrewboyson | 5:82197a6997fd | 14 | |
andrewboyson | 5:82197a6997fd | 15 | #define BOILER_CALL_DIR FIO2DIR(5) // P2.5 == p21 |
andrewboyson | 5:82197a6997fd | 16 | #define BOILER_CALL_PIN FIO2PIN(5) |
andrewboyson | 5:82197a6997fd | 17 | #define BOILER_CALL_SET FIO2SET(5) |
andrewboyson | 5:82197a6997fd | 18 | #define BOILER_CALL_CLR FIO2CLR(5) |
andrewboyson | 0:3c04f4b47041 | 19 | |
andrewboyson | 48:6eac12df3ad5 | 20 | static char* tankRom; static int iTankRom; |
andrewboyson | 48:6eac12df3ad5 | 21 | static char* outputRom; static int iOutputRom; |
andrewboyson | 48:6eac12df3ad5 | 22 | static char* returnRom; static int iReturnRom; |
andrewboyson | 0:3c04f4b47041 | 23 | |
andrewboyson | 91:8b192efd0288 | 24 | static int32_t tankSetPoint; static int iTankSetPoint; |
andrewboyson | 91:8b192efd0288 | 25 | static int32_t tankHysteresis; static int iTankHysteresis; |
andrewboyson | 91:8b192efd0288 | 26 | static int32_t runOnResidual16ths; static int iRunOnResidual; |
andrewboyson | 91:8b192efd0288 | 27 | static int32_t runOnTime; static int iRunOnTime; |
andrewboyson | 0:3c04f4b47041 | 28 | |
andrewboyson | 48:6eac12df3ad5 | 29 | uint16_t BoilerGetTankDS18B20Value () { return DS18B20ValueFromRom(tankRom); } |
andrewboyson | 48:6eac12df3ad5 | 30 | uint16_t BoilerGetOutputDS18B20Value() { return DS18B20ValueFromRom(outputRom); } |
andrewboyson | 48:6eac12df3ad5 | 31 | uint16_t BoilerGetReturnDS18B20Value() { return DS18B20ValueFromRom(returnRom); } |
andrewboyson | 48:6eac12df3ad5 | 32 | int BoilerGetTankSetPoint () { return tankSetPoint; } |
andrewboyson | 48:6eac12df3ad5 | 33 | int BoilerGetTankHysteresis () { return tankHysteresis; } |
andrewboyson | 91:8b192efd0288 | 34 | int BoilerGetRunOnResidual16ths() { return runOnResidual16ths; } |
andrewboyson | 48:6eac12df3ad5 | 35 | int BoilerGetRunOnTime () { return runOnTime; } |
andrewboyson | 0:3c04f4b47041 | 36 | |
andrewboyson | 91:8b192efd0288 | 37 | static void setTankRom (char* value) { memcpy(tankRom, value, 8); FramWrite(iTankRom, 8, tankRom ); } |
andrewboyson | 91:8b192efd0288 | 38 | static void setOutputRom (char* value) { memcpy(outputRom, value, 8); FramWrite(iOutputRom, 8, outputRom ); } |
andrewboyson | 91:8b192efd0288 | 39 | static void setReturnRom (char* value) { memcpy(returnRom, value, 8); FramWrite(iReturnRom, 8, returnRom ); } |
andrewboyson | 91:8b192efd0288 | 40 | void BoilerSetTankSetPoint (int value) { tankSetPoint = value; FramWrite(iTankSetPoint, 4, &tankSetPoint ); } |
andrewboyson | 91:8b192efd0288 | 41 | void BoilerSetTankHysteresis (int value) { tankHysteresis = value; FramWrite(iTankHysteresis, 4, &tankHysteresis ); } |
andrewboyson | 91:8b192efd0288 | 42 | void BoilerSetRunOnResidual16ths(int value) { runOnResidual16ths = value; FramWrite(iRunOnResidual, 4, &runOnResidual16ths ); } |
andrewboyson | 91:8b192efd0288 | 43 | void BoilerSetRunOnTime (int value) { runOnTime = value; FramWrite(iRunOnTime, 4, &runOnTime ); } |
andrewboyson | 0:3c04f4b47041 | 44 | |
andrewboyson | 0:3c04f4b47041 | 45 | int BoilerInit() |
andrewboyson | 0:3c04f4b47041 | 46 | { |
andrewboyson | 48:6eac12df3ad5 | 47 | tankRom = DS18B20Roms + 8 * DS18B20RomCount; |
andrewboyson | 48:6eac12df3ad5 | 48 | DS18B20RomSetters[DS18B20RomCount] = setTankRom; |
andrewboyson | 48:6eac12df3ad5 | 49 | DS18B20RomNames[DS18B20RomCount] = "Tank"; |
andrewboyson | 48:6eac12df3ad5 | 50 | DS18B20RomCount++; |
andrewboyson | 48:6eac12df3ad5 | 51 | |
andrewboyson | 48:6eac12df3ad5 | 52 | outputRom = DS18B20Roms + 8 * DS18B20RomCount; |
andrewboyson | 48:6eac12df3ad5 | 53 | DS18B20RomSetters[DS18B20RomCount] = setOutputRom; |
andrewboyson | 48:6eac12df3ad5 | 54 | DS18B20RomNames[DS18B20RomCount] = "BlrOut"; |
andrewboyson | 48:6eac12df3ad5 | 55 | DS18B20RomCount++; |
andrewboyson | 48:6eac12df3ad5 | 56 | |
andrewboyson | 48:6eac12df3ad5 | 57 | returnRom = DS18B20Roms + 8 * DS18B20RomCount; |
andrewboyson | 48:6eac12df3ad5 | 58 | DS18B20RomSetters[DS18B20RomCount] = setReturnRom; |
andrewboyson | 48:6eac12df3ad5 | 59 | DS18B20RomNames[DS18B20RomCount] = "BlrRtn"; |
andrewboyson | 48:6eac12df3ad5 | 60 | DS18B20RomCount++; |
andrewboyson | 48:6eac12df3ad5 | 61 | |
andrewboyson | 0:3c04f4b47041 | 62 | int address; |
andrewboyson | 0:3c04f4b47041 | 63 | int32_t def4; |
andrewboyson | 91:8b192efd0288 | 64 | address = FramLoad( 8, tankRom, 0); if (address < 0) return -1; iTankRom = address; |
andrewboyson | 91:8b192efd0288 | 65 | address = FramLoad( 8, outputRom, 0); if (address < 0) return -1; iOutputRom = address; |
andrewboyson | 91:8b192efd0288 | 66 | address = FramLoad( 8, returnRom, 0); if (address < 0) return -1; iReturnRom = address; |
andrewboyson | 91:8b192efd0288 | 67 | def4 = 80; address = FramLoad( 4, &tankSetPoint, &def4); if (address < 0) return -1; iTankSetPoint = address; |
andrewboyson | 91:8b192efd0288 | 68 | def4 = 5; address = FramLoad( 4, &tankHysteresis, &def4); if (address < 0) return -1; iTankHysteresis = address; |
andrewboyson | 91:8b192efd0288 | 69 | def4 = 2; address = FramLoad( 4, &runOnResidual16ths, &def4); if (address < 0) return -1; iRunOnResidual = address; |
andrewboyson | 91:8b192efd0288 | 70 | def4 = 360; address = FramLoad( 4, &runOnTime, &def4); if (address < 0) return -1; iRunOnTime = address; |
andrewboyson | 0:3c04f4b47041 | 71 | |
andrewboyson | 5:82197a6997fd | 72 | BOILER_PUMP_DIR = 1; //Set the direction to 1 == output |
andrewboyson | 5:82197a6997fd | 73 | BOILER_CALL_DIR = 1; //Set the direction to 1 == output |
andrewboyson | 48:6eac12df3ad5 | 74 | |
andrewboyson | 0:3c04f4b47041 | 75 | return 0; |
andrewboyson | 0:3c04f4b47041 | 76 | } |
andrewboyson | 0:3c04f4b47041 | 77 | bool BoilerCall = false; |
andrewboyson | 35:bb8a6d1c034c | 78 | static void controlBoilerCall() |
andrewboyson | 0:3c04f4b47041 | 79 | { |
andrewboyson | 0:3c04f4b47041 | 80 | int tankTemp16ths = DS18B20ValueFromRom(tankRom); |
andrewboyson | 0:3c04f4b47041 | 81 | if (DS18B20IsValidValue(tankTemp16ths)) //Ignore values which are likely to be wrong |
andrewboyson | 0:3c04f4b47041 | 82 | { |
andrewboyson | 0:3c04f4b47041 | 83 | int tankUpper16ths = tankSetPoint << 4; |
andrewboyson | 0:3c04f4b47041 | 84 | int hysteresis16ths = tankHysteresis << 4; |
andrewboyson | 0:3c04f4b47041 | 85 | int tankLower16ths = tankUpper16ths - hysteresis16ths; |
andrewboyson | 0:3c04f4b47041 | 86 | |
andrewboyson | 0:3c04f4b47041 | 87 | if (tankTemp16ths >= tankUpper16ths) BoilerCall = false; |
andrewboyson | 0:3c04f4b47041 | 88 | if (tankTemp16ths <= tankLower16ths) BoilerCall = true; |
andrewboyson | 0:3c04f4b47041 | 89 | } |
andrewboyson | 35:bb8a6d1c034c | 90 | } |
andrewboyson | 35:bb8a6d1c034c | 91 | bool BoilerPump = false; |
andrewboyson | 35:bb8a6d1c034c | 92 | static void controlBoilerPump() |
andrewboyson | 35:bb8a6d1c034c | 93 | { |
andrewboyson | 0:3c04f4b47041 | 94 | int boilerOutput16ths = DS18B20ValueFromRom(outputRom); |
andrewboyson | 0:3c04f4b47041 | 95 | int boilerReturn16ths = DS18B20ValueFromRom(returnRom); |
andrewboyson | 0:3c04f4b47041 | 96 | int boilerResidual16ths = boilerOutput16ths - boilerReturn16ths; |
andrewboyson | 0:3c04f4b47041 | 97 | int boilerTempsAreValid = DS18B20IsValidValue(boilerOutput16ths) && DS18B20IsValidValue(boilerReturn16ths); |
andrewboyson | 0:3c04f4b47041 | 98 | |
andrewboyson | 35:bb8a6d1c034c | 99 | static uint32_t msTimerBoilerPumpRunOn = 0; |
andrewboyson | 0:3c04f4b47041 | 100 | if (BoilerCall) |
andrewboyson | 0:3c04f4b47041 | 101 | { |
andrewboyson | 0:3c04f4b47041 | 102 | BoilerPump = true; |
andrewboyson | 35:bb8a6d1c034c | 103 | msTimerBoilerPumpRunOn = MsTimerCount; |
andrewboyson | 0:3c04f4b47041 | 104 | } |
andrewboyson | 0:3c04f4b47041 | 105 | else |
andrewboyson | 0:3c04f4b47041 | 106 | { |
andrewboyson | 41:6413522ed343 | 107 | if (MsTimerRelative(msTimerBoilerPumpRunOn, runOnTime * 1000)) BoilerPump = false; |
andrewboyson | 91:8b192efd0288 | 108 | if (boilerTempsAreValid && boilerResidual16ths < runOnResidual16ths) BoilerPump = false; |
andrewboyson | 0:3c04f4b47041 | 109 | } |
andrewboyson | 35:bb8a6d1c034c | 110 | } |
andrewboyson | 35:bb8a6d1c034c | 111 | void BoilerMain() |
andrewboyson | 35:bb8a6d1c034c | 112 | { |
andrewboyson | 35:bb8a6d1c034c | 113 | controlBoilerCall(); |
andrewboyson | 35:bb8a6d1c034c | 114 | if (BoilerCall) BOILER_CALL_SET; |
andrewboyson | 35:bb8a6d1c034c | 115 | else BOILER_CALL_CLR; |
andrewboyson | 0:3c04f4b47041 | 116 | |
andrewboyson | 35:bb8a6d1c034c | 117 | controlBoilerPump(); |
andrewboyson | 5:82197a6997fd | 118 | if (BoilerPump) BOILER_PUMP_SET; |
andrewboyson | 5:82197a6997fd | 119 | else BOILER_PUMP_CLR; |
andrewboyson | 0:3c04f4b47041 | 120 | |
andrewboyson | 0:3c04f4b47041 | 121 | } |