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

Committer:
andrewboyson
Date:
2019-04-26
Revision:
48:6eac12df3ad5
Parent:
41:6413522ed343
Child:
91:8b192efd0288

File content as of revision 48:6eac12df3ad5:

#include <string.h>
#include <stdint.h>
#include <stdbool.h>

#include "gpio.h"
#include "mstimer.h"
#include "ds18b20.h"
#include "fram.h"

#define BOILER_PUMP_DIR FIO2DIR(4) // P2.4 == p22
#define BOILER_PUMP_PIN FIO2PIN(4)
#define BOILER_PUMP_SET FIO2SET(4)
#define BOILER_PUMP_CLR FIO2CLR(4)

#define BOILER_CALL_DIR FIO2DIR(5) // P2.5 == p21
#define BOILER_CALL_PIN FIO2PIN(5)
#define BOILER_CALL_SET FIO2SET(5)
#define BOILER_CALL_CLR FIO2CLR(5)

static char*     tankRom; static int iTankRom;
static char*   outputRom; static int iOutputRom;
static char*   returnRom; 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;

uint16_t BoilerGetTankDS18B20Value  () { return DS18B20ValueFromRom(tankRom);   } 
uint16_t BoilerGetOutputDS18B20Value() { return DS18B20ValueFromRom(outputRom); } 
uint16_t BoilerGetReturnDS18B20Value() { return DS18B20ValueFromRom(returnRom); } 
int      BoilerGetTankSetPoint      () { return tankSetPoint;   } 
int      BoilerGetTankHysteresis    () { return tankHysteresis; } 
int      BoilerGetRunOnResidual     () { return runOnResidual;  } 
int      BoilerGetRunOnTime         () { return runOnTime;      } 

static void setTankRom       (char* value) { memcpy(tankRom,   value, 8); FramWrite(iTankRom,         8,  tankRom        ); }
static void setOutputRom     (char* value) { memcpy(outputRom, value, 8); FramWrite(iOutputRom,       8,  outputRom      ); }
static void setReturnRom     (char* value) { memcpy(returnRom, value, 8); FramWrite(iReturnRom,       8,  returnRom      ); }
void BoilerSetTankSetPoint   (int   value) { tankSetPoint    = value;     FramWrite(iTankSetPoint,    4, &tankSetPoint   ); }
void BoilerSetTankHysteresis (int   value) { tankHysteresis  = value;     FramWrite(iTankHysteresis,  4, &tankHysteresis ); }
void BoilerSetRunOnResidual  (int   value) { runOnResidual   = value;     FramWrite(iRunOnResidual,   4, &runOnResidual  ); }
void BoilerSetRunOnTime      (int   value) { runOnTime       = value;     FramWrite(iRunOnTime,       4, &runOnTime      ); }

int BoilerInit()
{
      tankRom = DS18B20Roms + 8 * DS18B20RomCount;
    DS18B20RomSetters[DS18B20RomCount] = setTankRom;
    DS18B20RomNames[DS18B20RomCount] = "Tank";
    DS18B20RomCount++;
    
    outputRom = DS18B20Roms + 8 * DS18B20RomCount;
    DS18B20RomSetters[DS18B20RomCount] = setOutputRom;
    DS18B20RomNames[DS18B20RomCount] = "BlrOut";
    DS18B20RomCount++;
    
    returnRom = DS18B20Roms + 8 * DS18B20RomCount;
    DS18B20RomSetters[DS18B20RomCount] = setReturnRom;
    DS18B20RomNames[DS18B20RomCount] = "BlrRtn";
    DS18B20RomCount++;
    
    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; 
    
    BOILER_PUMP_DIR = 1; //Set the direction to 1 == output
    BOILER_CALL_DIR = 1; //Set the direction to 1 == output

    return 0;
}
bool BoilerCall = false;
static void controlBoilerCall()
{
    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;
    }
}
bool BoilerPump = false;
static void controlBoilerPump()
{
    int boilerOutput16ths   = DS18B20ValueFromRom(outputRom);
    int boilerReturn16ths   = DS18B20ValueFromRom(returnRom);
    int boilerResidual16ths = boilerOutput16ths - boilerReturn16ths;
    int boilerTempsAreValid = DS18B20IsValidValue(boilerOutput16ths) && DS18B20IsValidValue(boilerReturn16ths);

    static uint32_t msTimerBoilerPumpRunOn = 0;
    if (BoilerCall)
    {
        BoilerPump = true;
        msTimerBoilerPumpRunOn = MsTimerCount;
    }
    else
    {
        if (MsTimerRelative(msTimerBoilerPumpRunOn,      runOnTime  * 1000)) BoilerPump = false;
        if (boilerTempsAreValid && boilerResidual16ths < runOnResidual << 4) BoilerPump = false;
    }
}
void BoilerMain()
{
    controlBoilerCall();
    if (BoilerCall) BOILER_CALL_SET;
    else            BOILER_CALL_CLR;
    
    controlBoilerPump();
    if (BoilerPump) BOILER_PUMP_SET;
    else            BOILER_PUMP_CLR;
    
}