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@0:3c04f4b47041, 2018-01-11 (annotated)
- Committer:
- andrewboyson
- Date:
- Thu Jan 11 17:40:08 2018 +0000
- Revision:
- 0:3c04f4b47041
- Child:
- 1:ccc66fdf858d
Removed dependence on Mbed OS
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 | 0:3c04f4b47041 | 6 | #include "dns.h" |
andrewboyson | 0:3c04f4b47041 | 7 | #include "fram.h" |
andrewboyson | 0:3c04f4b47041 | 8 | #include "clock.h" |
andrewboyson | 0:3c04f4b47041 | 9 | #include "ds18b20.h" |
andrewboyson | 0:3c04f4b47041 | 10 | #include "radiator.h" |
andrewboyson | 0:3c04f4b47041 | 11 | #include "boiler.h" |
andrewboyson | 0:3c04f4b47041 | 12 | #include "program.h" |
andrewboyson | 0:3c04f4b47041 | 13 | #include "log.h" |
andrewboyson | 0:3c04f4b47041 | 14 | #include "net.h" |
andrewboyson | 0:3c04f4b47041 | 15 | |
andrewboyson | 0:3c04f4b47041 | 16 | bool ValuesTrace = false; |
andrewboyson | 0:3c04f4b47041 | 17 | |
andrewboyson | 0:3c04f4b47041 | 18 | static char serverName[DNS_MAX_LABEL_LENGTH+1]; static int iServerName; |
andrewboyson | 0:3c04f4b47041 | 19 | static char fileName[DNS_MAX_LABEL_LENGTH+1]; static int iFileName; |
andrewboyson | 0:3c04f4b47041 | 20 | static int32_t writeSize; static int iWriteSize; |
andrewboyson | 0:3c04f4b47041 | 21 | static int32_t readInterval; static int iReadInterval; |
andrewboyson | 0:3c04f4b47041 | 22 | static int64_t startTime; static int iStartTime; |
andrewboyson | 0:3c04f4b47041 | 23 | static int32_t count; static int iCount; |
andrewboyson | 0:3c04f4b47041 | 24 | static int iData; |
andrewboyson | 0:3c04f4b47041 | 25 | |
andrewboyson | 0:3c04f4b47041 | 26 | char* ValuesGetServerName ( ) { return serverName; } |
andrewboyson | 0:3c04f4b47041 | 27 | char* ValuesGetFileName ( ) { return fileName; } |
andrewboyson | 0:3c04f4b47041 | 28 | int ValuesGetWriteSize ( ) { return (int) writeSize; } |
andrewboyson | 0:3c04f4b47041 | 29 | int ValuesGetReadInterval ( ) { return (int) readInterval; } |
andrewboyson | 0:3c04f4b47041 | 30 | void ValuesGetStartTm (struct tm* ptm) { ClockNsToTmUtc(startTime, ptm); } |
andrewboyson | 0:3c04f4b47041 | 31 | int ValuesGetCount ( ) { return (int) count; } |
andrewboyson | 0:3c04f4b47041 | 32 | |
andrewboyson | 0:3c04f4b47041 | 33 | static void lblcpy(char* dst, char* src) { strncpy(dst, src, DNS_MAX_LABEL_LENGTH); dst[DNS_MAX_LABEL_LENGTH] = 0; } |
andrewboyson | 0:3c04f4b47041 | 34 | |
andrewboyson | 0:3c04f4b47041 | 35 | void ValuesSetServerName (char* value) { lblcpy(serverName, value); FramWrite(iServerName , DNS_MAX_LABEL_LENGTH, serverName ); } |
andrewboyson | 0:3c04f4b47041 | 36 | void ValuesSetFileName (char* value) { lblcpy( fileName, value); FramWrite(iFileName , DNS_MAX_LABEL_LENGTH, fileName ); } |
andrewboyson | 0:3c04f4b47041 | 37 | void ValuesSetWriteSize (int value) { writeSize = (int32_t)value ; FramWrite(iWriteSize , 4, &writeSize ); } |
andrewboyson | 0:3c04f4b47041 | 38 | void ValuesSetReadInterval (int value) { readInterval = (int32_t)value ; FramWrite(iReadInterval, 4, &readInterval ); } |
andrewboyson | 0:3c04f4b47041 | 39 | static void setStartTime (int64_t value) { startTime = value ; FramWrite(iStartTime , 8, &startTime ); } |
andrewboyson | 0:3c04f4b47041 | 40 | static void setCount (int value) { count = (int32_t)value ; FramWrite(iCount , 4, &count ); } |
andrewboyson | 0:3c04f4b47041 | 41 | |
andrewboyson | 0:3c04f4b47041 | 42 | static int readValuesFromFram() |
andrewboyson | 0:3c04f4b47041 | 43 | { |
andrewboyson | 0:3c04f4b47041 | 44 | int address; |
andrewboyson | 0:3c04f4b47041 | 45 | int32_t def4; |
andrewboyson | 0:3c04f4b47041 | 46 | |
andrewboyson | 0:3c04f4b47041 | 47 | address = FramLoad( DNS_MAX_LABEL_LENGTH+1, serverName , NULL ); if (address < 0) return -1; iServerName = address; |
andrewboyson | 0:3c04f4b47041 | 48 | address = FramLoad( DNS_MAX_LABEL_LENGTH+1, fileName , NULL ); if (address < 0) return -1; iFileName = address; |
andrewboyson | 0:3c04f4b47041 | 49 | def4 = 100; address = FramLoad( 4, &writeSize , &def4); if (address < 0) return -1; iWriteSize = address; |
andrewboyson | 0:3c04f4b47041 | 50 | def4 = 15; address = FramLoad( 4, &readInterval, &def4); if (address < 0) return -1; iReadInterval = address; |
andrewboyson | 0:3c04f4b47041 | 51 | address = FramLoad( 8, &startTime , NULL ); if (address < 0) return -1; iStartTime = address; |
andrewboyson | 0:3c04f4b47041 | 52 | address = FramLoad( 4, &count , NULL ); if (address < 0) return -1; iCount = address; |
andrewboyson | 0:3c04f4b47041 | 53 | address = FramAllocate( 1 ); if (address < 0) return -1; iData = address; |
andrewboyson | 0:3c04f4b47041 | 54 | return 0; |
andrewboyson | 0:3c04f4b47041 | 55 | } |
andrewboyson | 0:3c04f4b47041 | 56 | |
andrewboyson | 0:3c04f4b47041 | 57 | |
andrewboyson | 0:3c04f4b47041 | 58 | static uint32_t readElapsed; |
andrewboyson | 0:3c04f4b47041 | 59 | |
andrewboyson | 0:3c04f4b47041 | 60 | static int writeIndex; |
andrewboyson | 0:3c04f4b47041 | 61 | |
andrewboyson | 0:3c04f4b47041 | 62 | static int nextByteOfWriteStream() |
andrewboyson | 0:3c04f4b47041 | 63 | { |
andrewboyson | 0:3c04f4b47041 | 64 | int byteAfterData = count * 8; |
andrewboyson | 0:3c04f4b47041 | 65 | if (writeIndex >= byteAfterData || writeIndex + iData >= FRAM_SIZE) |
andrewboyson | 0:3c04f4b47041 | 66 | { |
andrewboyson | 0:3c04f4b47041 | 67 | setCount(0); |
andrewboyson | 0:3c04f4b47041 | 68 | return -1; |
andrewboyson | 0:3c04f4b47041 | 69 | } |
andrewboyson | 0:3c04f4b47041 | 70 | char c; |
andrewboyson | 0:3c04f4b47041 | 71 | FramRead(writeIndex + iData, 1, &c); |
andrewboyson | 0:3c04f4b47041 | 72 | writeIndex++; |
andrewboyson | 0:3c04f4b47041 | 73 | return c; |
andrewboyson | 0:3c04f4b47041 | 74 | } |
andrewboyson | 0:3c04f4b47041 | 75 | |
andrewboyson | 0:3c04f4b47041 | 76 | static void readValues() |
andrewboyson | 0:3c04f4b47041 | 77 | { |
andrewboyson | 0:3c04f4b47041 | 78 | if (readElapsed == 0 ) return; |
andrewboyson | 0:3c04f4b47041 | 79 | if (readElapsed < readInterval) return; //Do nothing if interval not expired |
andrewboyson | 0:3c04f4b47041 | 80 | |
andrewboyson | 0:3c04f4b47041 | 81 | uint64_t record = 0; |
andrewboyson | 0:3c04f4b47041 | 82 | uint16_t value; |
andrewboyson | 0:3c04f4b47041 | 83 | value = DS18B20ValueFromRom(RadiatorGetHallRom()); |
andrewboyson | 0:3c04f4b47041 | 84 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 85 | record |= value; //0000 0000 0000 0AAA |
andrewboyson | 0:3c04f4b47041 | 86 | record <<= 12; //0000 0000 00AA A000 |
andrewboyson | 0:3c04f4b47041 | 87 | value = DS18B20ValueFromRom(BoilerGetTankRom ()); |
andrewboyson | 0:3c04f4b47041 | 88 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 89 | record |= value; //0000 0000 00AA ABBB |
andrewboyson | 0:3c04f4b47041 | 90 | record <<= 12; //0000 000A AABB B000 |
andrewboyson | 0:3c04f4b47041 | 91 | value = DS18B20ValueFromRom(BoilerGetOutputRom()); |
andrewboyson | 0:3c04f4b47041 | 92 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 93 | record |= value; //0000 000A AABB BCCC |
andrewboyson | 0:3c04f4b47041 | 94 | record <<= 12; //0000 AAAB BBCC C000 |
andrewboyson | 0:3c04f4b47041 | 95 | value = DS18B20ValueFromRom(BoilerGetReturnRom()); |
andrewboyson | 0:3c04f4b47041 | 96 | value &= 0x0FFF; |
andrewboyson | 0:3c04f4b47041 | 97 | record |= value; //0000 AAAB BBCC CDDD |
andrewboyson | 0:3c04f4b47041 | 98 | record <<= 16; //AAAB BBCC CDDD 0000 |
andrewboyson | 0:3c04f4b47041 | 99 | |
andrewboyson | 0:3c04f4b47041 | 100 | record |= ProgramTimerOutput << 0; |
andrewboyson | 0:3c04f4b47041 | 101 | record |= RadiatorGetMode() << 1; |
andrewboyson | 0:3c04f4b47041 | 102 | record |= RadiatorGetOverride() << 2; |
andrewboyson | 0:3c04f4b47041 | 103 | record |= RadiatorPump << 3; |
andrewboyson | 0:3c04f4b47041 | 104 | record |= BoilerCall << 4; |
andrewboyson | 0:3c04f4b47041 | 105 | record |= BoilerPump << 5; //AAAB BBCC CDDD 003F |
andrewboyson | 0:3c04f4b47041 | 106 | |
andrewboyson | 0:3c04f4b47041 | 107 | if (count == 0) setStartTime(ClockNowNs()); |
andrewboyson | 0:3c04f4b47041 | 108 | |
andrewboyson | 0:3c04f4b47041 | 109 | FramWrite(iData + 8 * count, 8, &record); |
andrewboyson | 0:3c04f4b47041 | 110 | setCount(count + 1); |
andrewboyson | 0:3c04f4b47041 | 111 | |
andrewboyson | 0:3c04f4b47041 | 112 | readElapsed = 0; |
andrewboyson | 0:3c04f4b47041 | 113 | } |
andrewboyson | 0:3c04f4b47041 | 114 | |
andrewboyson | 0:3c04f4b47041 | 115 | static void writeValues() |
andrewboyson | 0:3c04f4b47041 | 116 | { |
andrewboyson | 0:3c04f4b47041 | 117 | if (count == 0 ) return; //Don't save if nothing to save |
andrewboyson | 0:3c04f4b47041 | 118 | if (!serverName[0] ) return; //Do nothing if have no server name |
andrewboyson | 0:3c04f4b47041 | 119 | if ( !fileName[0] ) return; //Do nothing if have no file name |
andrewboyson | 0:3c04f4b47041 | 120 | if (TftpWriteStatus) return; //Do nothing if the TFTP client is busy |
andrewboyson | 0:3c04f4b47041 | 121 | |
andrewboyson | 0:3c04f4b47041 | 122 | strcpy(TftpServerName, serverName); |
andrewboyson | 0:3c04f4b47041 | 123 | struct tm tm; |
andrewboyson | 0:3c04f4b47041 | 124 | ClockNsToTmUtc(startTime, &tm); |
andrewboyson | 0:3c04f4b47041 | 125 | strftime(TftpFileName, DNS_MAX_LABEL_LENGTH+1, fileName, &tm); |
andrewboyson | 0:3c04f4b47041 | 126 | |
andrewboyson | 0:3c04f4b47041 | 127 | if (ValuesTrace) |
andrewboyson | 0:3c04f4b47041 | 128 | { |
andrewboyson | 0:3c04f4b47041 | 129 | if (NetTraceNewLine) Log("\r\n"); |
andrewboyson | 0:3c04f4b47041 | 130 | LogTimeF("Values - requesting backup of %d values to %s\r\n", count, TftpFileName); |
andrewboyson | 0:3c04f4b47041 | 131 | } |
andrewboyson | 0:3c04f4b47041 | 132 | |
andrewboyson | 0:3c04f4b47041 | 133 | writeIndex = 0; |
andrewboyson | 0:3c04f4b47041 | 134 | TftpWriteStatus = TFTP_WRITE_STATUS_REQUEST; //This is reset by TFTP when finished |
andrewboyson | 0:3c04f4b47041 | 135 | } |
andrewboyson | 0:3c04f4b47041 | 136 | |
andrewboyson | 0:3c04f4b47041 | 137 | void ValuesMain() |
andrewboyson | 0:3c04f4b47041 | 138 | { |
andrewboyson | 0:3c04f4b47041 | 139 | if (ClockTicked) |
andrewboyson | 0:3c04f4b47041 | 140 | { |
andrewboyson | 0:3c04f4b47041 | 141 | if (readInterval) readElapsed++; |
andrewboyson | 0:3c04f4b47041 | 142 | else readElapsed = 0; |
andrewboyson | 0:3c04f4b47041 | 143 | } |
andrewboyson | 0:3c04f4b47041 | 144 | if (writeSize > 0) readValues(); //Only read values if they are going to be backed up |
andrewboyson | 0:3c04f4b47041 | 145 | if (count >= writeSize) writeValues(); //Backup the values once the backup size is reached |
andrewboyson | 0:3c04f4b47041 | 146 | } |
andrewboyson | 0:3c04f4b47041 | 147 | |
andrewboyson | 0:3c04f4b47041 | 148 | int ValuesInit() |
andrewboyson | 0:3c04f4b47041 | 149 | { |
andrewboyson | 0:3c04f4b47041 | 150 | if (readValuesFromFram()) return -1; |
andrewboyson | 0:3c04f4b47041 | 151 | readElapsed = 0; |
andrewboyson | 0:3c04f4b47041 | 152 | TftpGetNextByteFunction = nextByteOfWriteStream; |
andrewboyson | 0:3c04f4b47041 | 153 | if (count > 0) writeValues(); //Backup the values if there are any |
andrewboyson | 0:3c04f4b47041 | 154 | return 0; |
andrewboyson | 0:3c04f4b47041 | 155 | } |