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@57:72c1c1357861, 2019-05-06 (annotated)
- Committer:
- andrewboyson
- Date:
- Mon May 06 07:55:09 2019 +0000
- Revision:
- 57:72c1c1357861
- Parent:
- 48:6eac12df3ad5
- Child:
- 90:1c504a7b465e
Added a 'hall' module to manage the hall led and hall pushbutton. Some of the work done in the 'radiator' module was moved to the hall module.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 0:3c04f4b47041 | 1 | #include <stdint.h> |
andrewboyson | 0:3c04f4b47041 | 2 | #include <string.h> |
andrewboyson | 0:3c04f4b47041 | 3 | #include <stdbool.h> |
andrewboyson | 0:3c04f4b47041 | 4 | |
andrewboyson | 0:3c04f4b47041 | 5 | #include "tftp.h" |
andrewboyson | 38:2bfeefa8709a | 6 | #include "dnslabel.h" |
andrewboyson | 0:3c04f4b47041 | 7 | #include "fram.h" |
andrewboyson | 20:904a4f043f2c | 8 | #include "clk.h" |
andrewboyson | 48:6eac12df3ad5 | 9 | #include "clktime.h" |
andrewboyson | 11:fa01ea25b62d | 10 | #include "mstimer.h" |
andrewboyson | 11:fa01ea25b62d | 11 | #include "clktm.h" |
andrewboyson | 0:3c04f4b47041 | 12 | #include "ds18b20.h" |
andrewboyson | 0:3c04f4b47041 | 13 | #include "radiator.h" |
andrewboyson | 0:3c04f4b47041 | 14 | #include "boiler.h" |
andrewboyson | 0:3c04f4b47041 | 15 | #include "program.h" |
andrewboyson | 0:3c04f4b47041 | 16 | #include "log.h" |
andrewboyson | 0:3c04f4b47041 | 17 | #include "net.h" |
andrewboyson | 0:3c04f4b47041 | 18 | |
andrewboyson | 0:3c04f4b47041 | 19 | bool ValuesTrace = false; |
andrewboyson | 0:3c04f4b47041 | 20 | |
andrewboyson | 0:3c04f4b47041 | 21 | static char serverName[DNS_MAX_LABEL_LENGTH+1]; static int iServerName; |
andrewboyson | 20:904a4f043f2c | 22 | static char fileName[DNS_MAX_LABEL_LENGTH+1]; static int iFileName; |
andrewboyson | 0:3c04f4b47041 | 23 | static int32_t writeSize; static int iWriteSize; |
andrewboyson | 0:3c04f4b47041 | 24 | static int32_t readInterval; static int iReadInterval; |
andrewboyson | 0:3c04f4b47041 | 25 | static int64_t startTime; static int iStartTime; |
andrewboyson | 0:3c04f4b47041 | 26 | static int32_t count; static int iCount; |
andrewboyson | 0:3c04f4b47041 | 27 | static int iData; |
andrewboyson | 0:3c04f4b47041 | 28 | |
andrewboyson | 48:6eac12df3ad5 | 29 | char* ValuesGetServerName ( ) { return serverName; } |
andrewboyson | 48:6eac12df3ad5 | 30 | char* ValuesGetFileName ( ) { return fileName; } |
andrewboyson | 48:6eac12df3ad5 | 31 | int ValuesGetWriteSize ( ) { return (int) writeSize; } |
andrewboyson | 48:6eac12df3ad5 | 32 | int ValuesGetReadInterval ( ) { return (int) readInterval; } |
andrewboyson | 48:6eac12df3ad5 | 33 | void ValuesGetStartTm (struct tm* ptm) { ClkTimeToTmUtc(startTime, ptm); } |
andrewboyson | 48:6eac12df3ad5 | 34 | int64_t ValuesGetStartTime ( ) { return startTime >> CLK_TIME_ONE_SECOND_SHIFT;} |
andrewboyson | 48:6eac12df3ad5 | 35 | int ValuesGetCount ( ) { return (int) count; } |
andrewboyson | 0:3c04f4b47041 | 36 | |
andrewboyson | 38:2bfeefa8709a | 37 | void ValuesSetServerName (char* value) { DnsLabelCopy(serverName, value); FramWrite(iServerName , DNS_MAX_LABEL_LENGTH, serverName ); } |
andrewboyson | 38:2bfeefa8709a | 38 | void ValuesSetFileName (char* value) { DnsLabelCopy( fileName, value); FramWrite(iFileName , DNS_MAX_LABEL_LENGTH, fileName ); } |
andrewboyson | 38:2bfeefa8709a | 39 | void ValuesSetWriteSize (int value) { writeSize = value ; FramWrite(iWriteSize , 4, &writeSize ); } |
andrewboyson | 38:2bfeefa8709a | 40 | void ValuesSetReadInterval (int value) { readInterval = value ; FramWrite(iReadInterval, 4, &readInterval ); } |
andrewboyson | 38:2bfeefa8709a | 41 | static void setStartTime (int64_t value) { startTime = value ; FramWrite(iStartTime , 8, &startTime ); } |
andrewboyson | 38:2bfeefa8709a | 42 | static void setCount (int value) { count = value ; FramWrite(iCount , 4, &count ); } |
andrewboyson | 0:3c04f4b47041 | 43 | |
andrewboyson | 0:3c04f4b47041 | 44 | static int readValuesFromFram() |
andrewboyson | 0:3c04f4b47041 | 45 | { |
andrewboyson | 0:3c04f4b47041 | 46 | int address; |
andrewboyson | 0:3c04f4b47041 | 47 | int32_t def4; |
andrewboyson | 0:3c04f4b47041 | 48 | |
andrewboyson | 0:3c04f4b47041 | 49 | address = FramLoad( DNS_MAX_LABEL_LENGTH+1, serverName , NULL ); if (address < 0) return -1; iServerName = address; |
andrewboyson | 0:3c04f4b47041 | 50 | address = FramLoad( DNS_MAX_LABEL_LENGTH+1, fileName , NULL ); if (address < 0) return -1; iFileName = address; |
andrewboyson | 0:3c04f4b47041 | 51 | def4 = 100; address = FramLoad( 4, &writeSize , &def4); if (address < 0) return -1; iWriteSize = address; |
andrewboyson | 0:3c04f4b47041 | 52 | def4 = 15; address = FramLoad( 4, &readInterval, &def4); if (address < 0) return -1; iReadInterval = address; |
andrewboyson | 0:3c04f4b47041 | 53 | address = FramLoad( 8, &startTime , NULL ); if (address < 0) return -1; iStartTime = address; |
andrewboyson | 0:3c04f4b47041 | 54 | address = FramLoad( 4, &count , NULL ); if (address < 0) return -1; iCount = address; |
andrewboyson | 0:3c04f4b47041 | 55 | address = FramAllocate( 1 ); if (address < 0) return -1; iData = address; |
andrewboyson | 0:3c04f4b47041 | 56 | return 0; |
andrewboyson | 0:3c04f4b47041 | 57 | } |
andrewboyson | 0:3c04f4b47041 | 58 | |
andrewboyson | 0:3c04f4b47041 | 59 | |
andrewboyson | 11:fa01ea25b62d | 60 | static uint32_t readStartMs; |
andrewboyson | 0:3c04f4b47041 | 61 | |
andrewboyson | 0:3c04f4b47041 | 62 | static int writeIndex; |
andrewboyson | 0:3c04f4b47041 | 63 | |
andrewboyson | 0:3c04f4b47041 | 64 | static int nextByteOfWriteStream() |
andrewboyson | 0:3c04f4b47041 | 65 | { |
andrewboyson | 0:3c04f4b47041 | 66 | int byteAfterData = count * 8; |
andrewboyson | 0:3c04f4b47041 | 67 | if (writeIndex >= byteAfterData || writeIndex + iData >= FRAM_SIZE) |
andrewboyson | 0:3c04f4b47041 | 68 | { |
andrewboyson | 0:3c04f4b47041 | 69 | setCount(0); |
andrewboyson | 0:3c04f4b47041 | 70 | return -1; |
andrewboyson | 0:3c04f4b47041 | 71 | } |
andrewboyson | 0:3c04f4b47041 | 72 | char c; |
andrewboyson | 0:3c04f4b47041 | 73 | FramRead(writeIndex + iData, 1, &c); |
andrewboyson | 0:3c04f4b47041 | 74 | writeIndex++; |
andrewboyson | 0:3c04f4b47041 | 75 | return c; |
andrewboyson | 0:3c04f4b47041 | 76 | } |
andrewboyson | 0:3c04f4b47041 | 77 | |
andrewboyson | 0:3c04f4b47041 | 78 | static void readValues() |
andrewboyson | 11:fa01ea25b62d | 79 | { |
andrewboyson | 0:3c04f4b47041 | 80 | uint64_t record = 0; |
andrewboyson | 0:3c04f4b47041 | 81 | uint16_t value; |
andrewboyson | 48:6eac12df3ad5 | 82 | value = RadiatorGetHallDS18B20Value(); |
andrewboyson | 0:3c04f4b47041 | 83 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 84 | record |= value; //0000 0000 0000 0AAA |
andrewboyson | 0:3c04f4b47041 | 85 | record <<= 12; //0000 0000 00AA A000 |
andrewboyson | 48:6eac12df3ad5 | 86 | value = BoilerGetTankDS18B20Value(); |
andrewboyson | 0:3c04f4b47041 | 87 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 88 | record |= value; //0000 0000 00AA ABBB |
andrewboyson | 0:3c04f4b47041 | 89 | record <<= 12; //0000 000A AABB B000 |
andrewboyson | 48:6eac12df3ad5 | 90 | value = BoilerGetOutputDS18B20Value(); |
andrewboyson | 0:3c04f4b47041 | 91 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 92 | record |= value; //0000 000A AABB BCCC |
andrewboyson | 0:3c04f4b47041 | 93 | record <<= 12; //0000 AAAB BBCC C000 |
andrewboyson | 48:6eac12df3ad5 | 94 | value = BoilerGetReturnDS18B20Value(); |
andrewboyson | 0:3c04f4b47041 | 95 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 96 | record |= value; //0000 AAAB BBCC CDDD |
andrewboyson | 0:3c04f4b47041 | 97 | record <<= 16; //AAAB BBCC CDDD 0000 |
andrewboyson | 0:3c04f4b47041 | 98 | |
andrewboyson | 0:3c04f4b47041 | 99 | record |= ProgramTimerOutput << 0; |
andrewboyson | 57:72c1c1357861 | 100 | record |= RadiatorGetWinter() << 1; |
andrewboyson | 0:3c04f4b47041 | 101 | record |= RadiatorGetOverride() << 2; |
andrewboyson | 0:3c04f4b47041 | 102 | record |= RadiatorPump << 3; |
andrewboyson | 0:3c04f4b47041 | 103 | record |= BoilerCall << 4; |
andrewboyson | 0:3c04f4b47041 | 104 | record |= BoilerPump << 5; //AAAB BBCC CDDD 003F |
andrewboyson | 0:3c04f4b47041 | 105 | |
andrewboyson | 33:6694d7c515a0 | 106 | if (count == 0) setStartTime(ClkNowTai()); |
andrewboyson | 0:3c04f4b47041 | 107 | |
andrewboyson | 0:3c04f4b47041 | 108 | FramWrite(iData + 8 * count, 8, &record); |
andrewboyson | 0:3c04f4b47041 | 109 | setCount(count + 1); |
andrewboyson | 0:3c04f4b47041 | 110 | } |
andrewboyson | 0:3c04f4b47041 | 111 | |
andrewboyson | 0:3c04f4b47041 | 112 | static void writeValues() |
andrewboyson | 0:3c04f4b47041 | 113 | { |
andrewboyson | 0:3c04f4b47041 | 114 | if (!serverName[0] ) return; //Do nothing if have no server name |
andrewboyson | 0:3c04f4b47041 | 115 | if ( !fileName[0] ) return; //Do nothing if have no file name |
andrewboyson | 0:3c04f4b47041 | 116 | if (TftpWriteStatus) return; //Do nothing if the TFTP client is busy |
andrewboyson | 0:3c04f4b47041 | 117 | |
andrewboyson | 0:3c04f4b47041 | 118 | strcpy(TftpServerName, serverName); |
andrewboyson | 0:3c04f4b47041 | 119 | struct tm tm; |
andrewboyson | 13:2ca12dd42e91 | 120 | ClkTimeToTmUtc(startTime, &tm); |
andrewboyson | 0:3c04f4b47041 | 121 | strftime(TftpFileName, DNS_MAX_LABEL_LENGTH+1, fileName, &tm); |
andrewboyson | 0:3c04f4b47041 | 122 | |
andrewboyson | 0:3c04f4b47041 | 123 | if (ValuesTrace) |
andrewboyson | 0:3c04f4b47041 | 124 | { |
andrewboyson | 0:3c04f4b47041 | 125 | if (NetTraceNewLine) Log("\r\n"); |
andrewboyson | 0:3c04f4b47041 | 126 | LogTimeF("Values - requesting backup of %d values to %s\r\n", count, TftpFileName); |
andrewboyson | 0:3c04f4b47041 | 127 | } |
andrewboyson | 28:bb55def47737 | 128 | |
andrewboyson | 0:3c04f4b47041 | 129 | writeIndex = 0; |
andrewboyson | 0:3c04f4b47041 | 130 | TftpWriteStatus = TFTP_WRITE_STATUS_REQUEST; //This is reset by TFTP when finished |
andrewboyson | 0:3c04f4b47041 | 131 | } |
andrewboyson | 0:3c04f4b47041 | 132 | |
andrewboyson | 0:3c04f4b47041 | 133 | void ValuesMain() |
andrewboyson | 0:3c04f4b47041 | 134 | { |
andrewboyson | 11:fa01ea25b62d | 135 | if (!readInterval) readStartMs = MsTimerCount; |
andrewboyson | 28:bb55def47737 | 136 | if (writeSize && count < writeSize && readInterval) |
andrewboyson | 0:3c04f4b47041 | 137 | { |
andrewboyson | 41:6413522ed343 | 138 | if (MsTimerRelative(readStartMs, readInterval * 1000)) |
andrewboyson | 11:fa01ea25b62d | 139 | { |
andrewboyson | 11:fa01ea25b62d | 140 | readValues(); //Only read values if they are going to be backed up |
andrewboyson | 11:fa01ea25b62d | 141 | readStartMs = MsTimerCount; |
andrewboyson | 11:fa01ea25b62d | 142 | } |
andrewboyson | 0:3c04f4b47041 | 143 | } |
andrewboyson | 11:fa01ea25b62d | 144 | else |
andrewboyson | 11:fa01ea25b62d | 145 | { |
andrewboyson | 11:fa01ea25b62d | 146 | readStartMs = MsTimerCount; |
andrewboyson | 11:fa01ea25b62d | 147 | } |
andrewboyson | 28:bb55def47737 | 148 | if (writeSize && count >= writeSize) writeValues(); //Backup the values once the backup size is reached |
andrewboyson | 0:3c04f4b47041 | 149 | } |
andrewboyson | 0:3c04f4b47041 | 150 | |
andrewboyson | 0:3c04f4b47041 | 151 | int ValuesInit() |
andrewboyson | 0:3c04f4b47041 | 152 | { |
andrewboyson | 0:3c04f4b47041 | 153 | if (readValuesFromFram()) return -1; |
andrewboyson | 11:fa01ea25b62d | 154 | readStartMs = MsTimerCount; |
andrewboyson | 0:3c04f4b47041 | 155 | TftpGetNextByteFunction = nextByteOfWriteStream; |
andrewboyson | 0:3c04f4b47041 | 156 | if (count > 0) writeValues(); //Backup the values if there are any |
andrewboyson | 0:3c04f4b47041 | 157 | return 0; |
andrewboyson | 0:3c04f4b47041 | 158 | } |