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:
2020-06-10
Revision:
91:8b192efd0288
Parent:
48:6eac12df3ad5
Child:
104:46ce1aaf8be7

File content as of revision 91:8b192efd0288:

#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 runOnResidual16ths; 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      BoilerGetRunOnResidual16ths() { return runOnResidual16ths;  } 
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 BoilerSetRunOnResidual16ths(int   value) { runOnResidual16ths = value;     FramWrite(iRunOnResidual,   4, &runOnResidual16ths ); }
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, &runOnResidual16ths, &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 < runOnResidual16ths) BoilerPump = false;
    }
}
void BoilerMain()
{
    controlBoilerCall();
    if (BoilerCall) BOILER_CALL_SET;
    else            BOILER_CALL_CLR;
    
    controlBoilerPump();
    if (BoilerPump) BOILER_PUMP_SET;
    else            BOILER_PUMP_CLR;
    
}