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
Diff: heating/values.c
- Revision:
- 0:3c04f4b47041
- Child:
- 1:ccc66fdf858d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heating/values.c Thu Jan 11 17:40:08 2018 +0000 @@ -0,0 +1,155 @@ +#include <stdint.h> +#include <string.h> +#include <stdbool.h> + +#include "tftp.h" +#include "dns.h" +#include "fram.h" +#include "clock.h" +#include "ds18b20.h" +#include "radiator.h" +#include "boiler.h" +#include "program.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) { ClockNsToTmUtc(startTime, ptm); } +int ValuesGetCount ( ) { return (int) count; } + +static void lblcpy(char* dst, char* src) { strncpy(dst, src, DNS_MAX_LABEL_LENGTH); dst[DNS_MAX_LABEL_LENGTH] = 0; } + +void ValuesSetServerName (char* value) { lblcpy(serverName, value); FramWrite(iServerName , DNS_MAX_LABEL_LENGTH, serverName ); } +void ValuesSetFileName (char* value) { lblcpy( fileName, value); FramWrite(iFileName , DNS_MAX_LABEL_LENGTH, fileName ); } +void ValuesSetWriteSize (int value) { writeSize = (int32_t)value ; FramWrite(iWriteSize , 4, &writeSize ); } +void ValuesSetReadInterval (int value) { readInterval = (int32_t)value ; FramWrite(iReadInterval, 4, &readInterval ); } +static void setStartTime (int64_t value) { startTime = value ; FramWrite(iStartTime , 8, &startTime ); } +static void setCount (int value) { count = (int32_t)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 readElapsed; + +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() +{ + if (readElapsed == 0 ) return; + if (readElapsed < readInterval) return; //Do nothing if interval not expired + + uint64_t record = 0; + uint16_t value; + value = DS18B20ValueFromRom(RadiatorGetHallRom()); + value &= 0x0FFF; + record |= value; //0000 0000 0000 0AAA + record <<= 12; //0000 0000 00AA A000 + value = DS18B20ValueFromRom(BoilerGetTankRom ()); + value &= 0x0FFF; + record |= value; //0000 0000 00AA ABBB + record <<= 12; //0000 000A AABB B000 + value = DS18B20ValueFromRom(BoilerGetOutputRom()); + value &= 0x0FFF; + record |= value; //0000 000A AABB BCCC + record <<= 12; //0000 AAAB BBCC C000 + value = DS18B20ValueFromRom(BoilerGetReturnRom()); + value &= 0x0FFF; + record |= value; //0000 AAAB BBCC CDDD + record <<= 16; //AAAB BBCC CDDD 0000 + + record |= ProgramTimerOutput << 0; + record |= RadiatorGetMode() << 1; + record |= RadiatorGetOverride() << 2; + record |= RadiatorPump << 3; + record |= BoilerCall << 4; + record |= BoilerPump << 5; //AAAB BBCC CDDD 003F + + if (count == 0) setStartTime(ClockNowNs()); + + FramWrite(iData + 8 * count, 8, &record); + setCount(count + 1); + + readElapsed = 0; +} + +static void writeValues() +{ + if (count == 0 ) return; //Don't save if nothing to save + 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; + ClockNsToTmUtc(startTime, &tm); + strftime(TftpFileName, DNS_MAX_LABEL_LENGTH+1, fileName, &tm); + + 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 (ClockTicked) + { + if (readInterval) readElapsed++; + else readElapsed = 0; + } + if (writeSize > 0) readValues(); //Only read values if they are going to be backed up + if (count >= writeSize) writeValues(); //Backup the values once the backup size is reached +} + +int ValuesInit() +{ + if (readValuesFromFram()) return -1; + readElapsed = 0; + TftpGetNextByteFunction = nextByteOfWriteStream; + if (count > 0) writeValues(); //Backup the values if there are any + return 0; +}