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/values.c

Committer:
andrewboyson
Date:
2020-06-11
Revision:
94:ded7c74d49fb
Parent:
90:1c504a7b465e
Child:
105:1899f7ed17ec

File content as of revision 94:ded7c74d49fb:

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

#include "tftp.h"
#include "dnslabel.h"
#include "fram.h"
#include "clk.h"
#include "clktime.h"
#include "mstimer.h"
#include "clktm.h"
#include "ds18b20.h"
#include "radiator.h"
#include "boiler.h"
#include "hot-water.h"
#include "log.h"
#include "net.h"

bool ValuesTrace = false;

static char    serverName[DNS_MAX_LABEL_LENGTH+1]; static int iServerName;
static char      fileName[DNS_MAX_LABEL_LENGTH+1]; static int iFileName;
static int32_t writeSize;                          static int iWriteSize;
static int32_t readInterval;                       static int iReadInterval;
static int64_t startTime;                          static int iStartTime;
static int32_t count;                              static int iCount;
                                                   static int iData;

char*   ValuesGetServerName   (              ) { return         serverName;                    }
char*   ValuesGetFileName     (              ) { return           fileName;                    }
int     ValuesGetWriteSize    (              ) { return (int)    writeSize;                    }
int     ValuesGetReadInterval (              ) { return (int)     readInterval;                }
void    ValuesGetStartTm      (struct tm* ptm) { ClkTimeToTmUtc(startTime, ptm);               }
int64_t ValuesGetStartTime    (              ) { return startTime >> CLK_TIME_ONE_SECOND_SHIFT;}
int     ValuesGetCount        (              ) { return (int)        count;                    }

void ValuesSetServerName    (char*   value) { DnsLabelCopy(serverName, value); FramWrite(iServerName  , DNS_MAX_LABEL_LENGTH,  serverName   ); }
void ValuesSetFileName      (char*   value) { DnsLabelCopy(  fileName, value); FramWrite(iFileName    , DNS_MAX_LABEL_LENGTH,    fileName   ); }
void ValuesSetWriteSize     (int     value) { writeSize     =          value ; FramWrite(iWriteSize   ,                    4, &writeSize    ); }
void ValuesSetReadInterval  (int     value) { readInterval  =          value ; FramWrite(iReadInterval,                    4, &readInterval ); }
static void    setStartTime (int64_t value) { startTime     =          value ; FramWrite(iStartTime   ,                    8, &startTime    ); }
static void    setCount     (int     value) { count         =          value ; FramWrite(iCount       ,                    4, &count        ); }

static int readValuesFromFram()
{
    int address;
    int32_t def4;
    
                 address = FramLoad( DNS_MAX_LABEL_LENGTH+1,  serverName  , NULL ); if (address < 0) return -1; iServerName   = address;
                 address = FramLoad( DNS_MAX_LABEL_LENGTH+1,    fileName  , NULL ); if (address < 0) return -1; iFileName     = address;
    def4 =  100; address = FramLoad(                      4, &writeSize   , &def4); if (address < 0) return -1; iWriteSize    = address;
    def4 =   15; address = FramLoad(                      4, &readInterval, &def4); if (address < 0) return -1; iReadInterval = address;
                 address = FramLoad(                      8, &startTime   , NULL ); if (address < 0) return -1; iStartTime    = address;
                 address = FramLoad(                      4, &count       , NULL ); if (address < 0) return -1; iCount        = address;
                 address = FramAllocate(                  1                      ); if (address < 0) return -1; iData         = address;
    return 0;
}


static uint32_t readStartMs;

static int writeIndex;

static int nextByteOfWriteStream()
{
    int byteAfterData = count * 8;
    if (writeIndex >= byteAfterData || writeIndex + iData >= FRAM_SIZE)
    {
        setCount(0);
        return -1;
    }
    char c;
    FramRead(writeIndex + iData, 1, &c);
    writeIndex++;
    return c;
}

static void readValues()
{    
    uint64_t record = 0;
    uint16_t value;
    value = RadiatorGetHallDS18B20Value();
    value &= 0x0FFF;
    record |= value; //0000 0000 0000 0AAA
    record <<= 12;   //0000 0000 00AA A000
    value = BoilerGetTankDS18B20Value();
    value &= 0x0FFF;
    record |= value; //0000 0000 00AA ABBB
    record <<= 12;   //0000 000A AABB B000
    value = BoilerGetOutputDS18B20Value();
    value &= 0x0FFF;
    record |= value; //0000 000A AABB BCCC
    record <<= 12;   //0000 AAAB BBCC C000
    value = BoilerGetReturnDS18B20Value();
    value &= 0x0FFF;
    record |= value; //0000 AAAB BBCC CDDD
    record <<= 12;   //0AAA BBBC CCDD D000
    value = HotWaterGetDS18B20Value();
    value &= 0x0FFF;
    record |= value; //0AAA BBBC CCDD DEEE
    record <<= 4;    //AAAB BBCC CDDD EEE0
    
    record |= RadiatorPump << 0;
    record |= BoilerCall   << 1;
    record |= BoilerPump   << 2;   //AAAB BBCC CDDD EEEF
    
    if (count == 0) setStartTime(ClkNowTai());
    
    FramWrite(iData + 8 * count, 8, &record);
    setCount(count + 1);
}

static void writeValues()
{
    if (!serverName[0] ) return; //Do nothing if have no server name
    if (  !fileName[0] ) return; //Do nothing if have no file name
    if (TftpWriteStatus) return; //Do nothing if the TFTP client is busy

    strcpy(TftpServerName, serverName);
    struct tm tm;
    ClkTimeToTmUtc(startTime, &tm);
    int len = strftime(TftpFileName, DNS_MAX_LABEL_LENGTH+1, fileName, &tm);
    if (len == 0)
    {
        LogTimeF("Values - cannot make filename from template '%s'\r\n", count, fileName);
        return;
    }

    if (ValuesTrace)
    {
        if (NetTraceNewLine) Log("\r\n");
        LogTimeF("Values - requesting backup of %d values to %s\r\n", count, TftpFileName);
    }

    writeIndex = 0;
    TftpWriteStatus = TFTP_WRITE_STATUS_REQUEST; //This is reset by TFTP when finished
}

void ValuesMain()
{
    if (!readInterval) readStartMs = MsTimerCount;
    if (writeSize && count < writeSize && readInterval)
    {
        if (MsTimerRelative(readStartMs, readInterval * 1000))
        {
            readValues(); //Only read values if they are going to be backed up
            readStartMs = MsTimerCount;
        }
    }
    else
    {
        readStartMs = MsTimerCount;
    }
    if (writeSize && count >= writeSize) writeValues(); //Backup the values once the backup size is reached
}

int ValuesInit()
{
    if (readValuesFromFram()) return -1;
    readStartMs = MsTimerCount;
    TftpGetNextByteFunction = nextByteOfWriteStream;
    if (count > 0) writeValues();     //Backup the values if there are any
    return 0;
}