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

Revision:
0:3c04f4b47041
Child:
1:ccc66fdf858d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/heating/boiler.c	Thu Jan 11 17:40:08 2018 +0000
@@ -0,0 +1,103 @@
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "peripherals.h"
+#include "clock.h"
+#include  "ds18b20.h"
+#include     "fram.h"
+
+#define BOILER_PUMP_MASK 1UL << 4 // P2.4 == p22
+#define BOILER_CALL_MASK 1UL << 5 // P2.5 == p21
+
+static char    tankRom[8];   static int iTankRom;
+static char    outputRom[8]; static int iOutputRom;
+static char    returnRom[8]; static int iReturnRom;
+
+
+static int32_t tankSetPoint;   static int iTankSetPoint;
+static int32_t tankHysteresis; static int iTankHysteresis;
+static int32_t runOnResidual;  static int iRunOnResidual;
+static int32_t runOnTime;      static int iRunOnTime;
+
+char* BoilerGetTankRom       () { return       tankRom;        } 
+char* BoilerGetOutputRom     () { return       outputRom;      } 
+char* BoilerGetReturnRom     () { return       returnRom;      } 
+int   BoilerGetTankSetPoint  () { return (int) tankSetPoint;   } 
+int   BoilerGetTankHysteresis() { return (int) tankHysteresis; } 
+int   BoilerGetRunOnResidual () { return (int) runOnResidual;  } 
+int   BoilerGetRunOnTime     () { return (int) runOnTime;      } 
+
+void BoilerSetTankRom        (char* value) { memcpy(tankRom,   value, 8);      FramWrite(iTankRom,         8,  tankRom        ); }
+void BoilerSetOutputRom      (char* value) { memcpy(outputRom, value, 8);      FramWrite(iOutputRom,       8,  outputRom      ); }
+void BoilerSetReturnRom      (char* value) { memcpy(returnRom, value, 8);      FramWrite(iReturnRom,       8,  returnRom      ); }
+void BoilerSetTankSetPoint   (int   value) { tankSetPoint    = (int32_t)value; FramWrite(iTankSetPoint,    4, &tankSetPoint   ); }
+void BoilerSetTankHysteresis (int   value) { tankHysteresis  = (int32_t)value; FramWrite(iTankHysteresis,  4, &tankHysteresis ); }
+void BoilerSetRunOnResidual  (int   value) { runOnResidual   = (int32_t)value; FramWrite(iRunOnResidual,   4, &runOnResidual  ); }
+void BoilerSetRunOnTime      (int   value) { runOnTime       = (int32_t)value; FramWrite(iRunOnTime,       4, &runOnTime      ); }
+
+
+int BoilerInit()
+{
+    int address;
+    int32_t def4;
+                address = FramLoad( 8,  tankRom,            0); if (address < 0) return -1; iTankRom        = address;
+                address = FramLoad( 8,  outputRom,          0); if (address < 0) return -1; iOutputRom      = address;
+                address = FramLoad( 8,  returnRom,          0); if (address < 0) return -1; iReturnRom      = address;
+    def4 =  80; address = FramLoad( 4, &tankSetPoint,   &def4); if (address < 0) return -1; iTankSetPoint   = address; 
+    def4 =   5; address = FramLoad( 4, &tankHysteresis, &def4); if (address < 0) return -1; iTankHysteresis = address; 
+    def4 =   2; address = FramLoad( 4, &runOnResidual,  &def4); if (address < 0) return -1; iRunOnResidual  = address; 
+    def4 = 360; address = FramLoad( 4, &runOnTime,      &def4); if (address < 0) return -1; iRunOnTime      = address; 
+    
+    LPC_GPIO2->FIODIR |= BOILER_PUMP_MASK; //Set the direction to 1 == output
+    LPC_GPIO2->FIODIR |= BOILER_CALL_MASK; //Set the direction to 1 == output
+    
+    return 0;
+}
+bool BoilerPump = false;
+bool BoilerCall = false;
+
+void BoilerMain()
+{
+    //Control boiler call
+    int tankTemp16ths = DS18B20ValueFromRom(tankRom);
+    if (DS18B20IsValidValue(tankTemp16ths)) //Ignore values which are likely to be wrong
+    {
+        int  tankUpper16ths = tankSetPoint   << 4;
+        int hysteresis16ths = tankHysteresis << 4;
+        int  tankLower16ths = tankUpper16ths - hysteresis16ths;
+    
+        if (tankTemp16ths >= tankUpper16ths) BoilerCall = false;
+        if (tankTemp16ths <= tankLower16ths) BoilerCall = true;
+    }
+    if (BoilerCall) LPC_GPIO2->FIOSET = BOILER_CALL_MASK;
+    else            LPC_GPIO2->FIOCLR = BOILER_CALL_MASK;
+    
+    //Control boiler circulation pump
+    int boilerOutput16ths   = DS18B20ValueFromRom(outputRom);
+    int boilerReturn16ths   = DS18B20ValueFromRom(returnRom);
+    int boilerResidual16ths = boilerOutput16ths - boilerReturn16ths;
+    int boilerTempsAreValid = DS18B20IsValidValue(boilerOutput16ths) && DS18B20IsValidValue(boilerReturn16ths);
+
+    static int64_t offTimeNs;
+    if (BoilerCall)
+    {
+        BoilerPump = true;
+        offTimeNs = ClockNowNs();
+    }
+    else
+    {
+        int64_t nowNs = ClockNowNs();
+        int secondsSinceBoilerOff = (nowNs - offTimeNs) >> 20;
+        if (secondsSinceBoilerOff > runOnTime) BoilerPump = false;
+        if (boilerTempsAreValid)
+        {
+            int boilerStillSupplyingHeat = boilerResidual16ths > runOnResidual;
+            if (!boilerStillSupplyingHeat) BoilerPump = false;
+        }
+    }
+    
+    if (BoilerPump) LPC_GPIO2->FIOSET = BOILER_PUMP_MASK;
+    else            LPC_GPIO2->FIOCLR = BOILER_PUMP_MASK;
+    
+}
\ No newline at end of file